### Eclipse Workspace Patch 1.0
#P iText-2.1.7
Index: src/core/com/lowagie/text/rtf/document/RtfProtection.java
===================================================================
--- src/core/com/lowagie/text/rtf/document/RtfProtection.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/document/RtfProtection.java	(revision 0)
@@ -0,0 +1,259 @@
+/*
+ * $Id: RtfProtection.java 3373 2008-05-12 16:21:24Z xlv $
+ *
+ * Copyright 2008 by Howard Shank (hgshank@yahoo.com)
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+ 
+package com.lowagie.text.rtf.document;
+
+/**
+ * <code>RtfProtection</code> 
+ * <pre>
+ * See ECMA Specification for WordprocessingML documentProtection element.
+ * 
+ * <strong>Reference:</strong>
+ * Standard ECMA-376 1st Edition / December 2006
+ * Office Open XML File Formats
+ * </pre>
+ * @since 2.1.1
+ * @author Howard Shank (hgshank@yahoo.com)
+ */
+public final class RtfProtection {
+    /**
+     * Default for protection level. 
+     * @since 2.1.1
+     */
+	static final public int LEVEL_NONE = 0x0000;
+	/**
+	 * REVPROT
+	 * Mutually exclusive
+	 * This document is protected for revisions. The user can edit the document, 
+	 * but revision marking cannot be disabled.
+     * @since 2.1.1
+	 */
+	static final public int LEVEL_REVPROT = 0x0001; // protlevel0
+	/**
+	 * ANNNOTPROT
+	 * Mutually exclusive
+	 * This document is protected for comments (annotations).
+	 * The user cannot edit the document but can insert comments (annotations).
+     * @since 2.1.1
+	 */
+	static final public int LEVEL_ANNOTPROT = 0x0002; // protlevel1
+	/**
+	 * FORMPROT
+	 * Mutually exclusive
+	 * Document is protected for forms.
+	 * see also \allprot (forms controlword)
+     * @since 2.1.1
+	 */
+	static final public int LEVEL_FORMPROT = 0x0004; // protlevel2
+	/**
+	 * READPROT
+	 * Mutually exclusive but can be combined with ANNOTPROT for backward compatibility 
+	 * Document is protected for editing, except areas marked as exceptions by \protstart and\protend
+     * @since 2.1.1
+	 */
+	static final public int LEVEL_READPROT = 0x0008; // protlevel3
+
+
+	/**
+	 * STYLELOCK
+	 * 
+	 * The document contains styles and formatting restrictions.
+     * @since 2.1.1
+	 */
+	static final public int STYLELOCK = 0x0001;
+	/**
+	 * STYLELOCKENFORCED
+	 * 
+	 * The styles and formatting restrictions are being enforced.
+     * @since 2.1.1
+	 */
+	static final public int STYLELOCKENFORCED = 0x0002;
+	/**
+	 * STYLELOCKBACKCOMP
+	 * 
+	 * Style lockdown backward compatibility flag, indicating we emitted protection 
+	 * keywords to get documents with styles and formatting restrictions to behave 
+	 * in a reasonable way when opened by older versions.
+     * @since 2.1.1
+	 */
+	static final public int STYLELOCKBACKCOMP = 0x0004;
+	/**
+	 * STYLELOCKBACKCOMP
+	 * 
+	 * Allow AutoFormat to override styles and formatting restrictions.  When style 
+	 * protection is on, the user cannot add direct formatting.  This setting allows 
+	 * AutoFormat actions to apply direct formatting when needed.
+     * @since 2.1.1
+	 */
+	static final public int AUTOFMTOVERRIDE = 0x0008;
+	
+	
+	/**
+	 * <code>initialCodeArray</code> Table from ECMA-376 Specification
+     * @since 2.1.1
+	 */
+	static final private int initialCodeArray[] = { 
+			0xE1F0, 
+			0x1D0F, 
+			0xCC9C, 
+			0x84C0,
+			0x110C,
+			0x0E10,
+			0xF1CE,
+			0x313E,
+			0x1872,
+			0xE139,
+			0xD40F,
+			0x84F9,
+			0x280C,
+			0xA96A,
+			0x4EC3
+
+	};
+	
+	/**
+	 * <code>encryptionMatrix</code> Table from ECMA-376 Specification
+     * @since 2.1.1
+	 */
+	static final private int encryptionMatrix [][] = {
+		/*              bit1    bit2    bit3    bit4    bit5    bit6    bit7   **bit8 is ignored** */
+		/* char 1  */ {0x1021, 0x2042, 0x4084, 0x8108, 0x1231, 0x2462, 0x48C4},
+		/* char 2  */ {0x3331, 0x6662, 0xCCC4, 0x89A9, 0x0373, 0x06E6, 0x0DCC},
+		/* char 3  */ {0x3730, 0x6E60, 0xDCC0, 0xA9A1, 0x4363, 0x86C6, 0x1DAD},
+		/* char 4  */ {0x76B4, 0xED68, 0xCAF1, 0x85C3, 0x1BA7, 0x374E, 0x6E9C},
+		/* char 5  */ {0xAA51, 0x4483, 0x8906, 0x022D, 0x045A, 0x08B4, 0x1168},
+		/* char 6  */ {0x45A0, 0x8B40, 0x06A1, 0x0D42, 0x1A84, 0x3508, 0x6A10},
+		/* char 7  */ {0xB861, 0x60E3, 0xC1C6, 0x93AD, 0x377B, 0x6EF6, 0xDDEC},
+		/* char 8  */ {0x47D3, 0x8FA6, 0x0F6D, 0x1EDA, 0x3DB4, 0x7B68, 0xF6D0},
+		/* char 9  */ {0xEB23, 0xC667, 0x9CEF, 0x29FF, 0x53FE, 0xA7FC, 0x5FD9},
+		/* char 10 */ {0x6F45, 0xDE8A, 0xAD35, 0x4A4B, 0x9496, 0x390D, 0x721A},
+		/* char 11 */ {0xD849, 0xA0B3, 0x5147, 0xA28E, 0x553D, 0xAA7A, 0x44D5},
+		/* char 12 */ {0x0375, 0x06EA, 0x0DD4, 0x1BA8, 0x3750, 0x6EA0, 0xDD40},
+		/* char 13 */ {0x4563, 0x8AC6, 0x05AD, 0x0B5A, 0x16B4, 0x2D68, 0x5AD0},
+		/* char 14 */ {0x7B61, 0xF6C2, 0xFDA5, 0xEB6B, 0xC6F7, 0x9DCF, 0x2BBF},
+		/* char 15 */ {0xAEFC, 0x4DD9, 0x9BB2, 0x2745, 0x4E8A, 0x9D14, 0x2A09}
+	};
+	
+	/**
+	 * <code>generateHash</code> generates the password hash from a clear text string.
+	 * 
+	 * @param pwd Clear text string input
+	 * @return hex encoded password hash
+	 * 
+	 * @since 2.1.1
+	 */
+	static final public String generateHash(String pwd) {
+		String encryptedPwd="00000000";
+		String password = pwd;
+		
+		// if there is no password or the length is 0, then skip this and return "00000000" as default
+		// otherwise process the password
+		if(password != null && password.length() > 0) {
+			int hi=0;	// hi order word
+			int lo=0;	// lo order word
+
+			// Truncate the password to 15 characters.
+			if(password.length() > 15) {
+				password = password.substring(0,15);
+			}
+
+			// compute key's high-order word
+			// initialize to table value
+			hi = initialCodeArray[password.length()-1];
+			
+			int idxF = 0;	// forward index
+			int idxR = password.length()-1; // reverse index
+			// process each character left to right.
+			// check each bit and if it is set, xor the hi word with 
+			// the table entry for the position in password and bit position.
+			for(; idxF<password.length(); idxF++,idxR--) {
+				int ch = password.charAt(idxF);
+				if((ch & 0x0001)!= 0) {
+					hi = hi ^ encryptionMatrix[idxR][0];
+				}
+				if((ch & 0x0002)!= 0) {
+					hi = hi ^ encryptionMatrix[idxR][1];
+				}
+				if((ch & 0x0004)!= 0) {
+					hi = hi ^ encryptionMatrix[idxR][2];
+				}
+				if((ch & 0x0008)!= 0) {
+					hi = hi ^ encryptionMatrix[idxR][3];
+				}
+				if((ch & 0x0010)!= 0) {
+					hi = hi ^ encryptionMatrix[idxR][4];
+				}
+				if((ch & 0x0020)!= 0) {
+					hi = hi ^ encryptionMatrix[idxR][5];
+				}
+				if((ch & 0x0040)!= 0) {
+					hi = hi ^ encryptionMatrix[idxR][6];
+				}
+			}
+			// Compute Key's low-order word
+			idxF = password.length()-1;
+			lo = 0;
+			// low order word is computed in reverse.
+			for(;idxF>= 0; idxF--) {
+				int ch = password.charAt(idxF);
+				lo = (((lo >> 14) & 0x001) | (( lo << 1) & 0x7fff)) ^ ch;
+			}
+			// finally incorporate the password length into the low word and use value from formula
+			lo = (((lo >> 14) & 0x001) | (( lo << 1) & 0x7fff)) ^ password.length() ^ 0xCE4B;
+			
+			// correct for little-endian - 
+			// Java always uses big-endian. According to tests - RTF wants little-endian but is not documented
+			encryptedPwd = Integer.toHexString(lo).substring(2,4) + Integer.toHexString(lo).substring(0,2);
+			encryptedPwd += Integer.toHexString(hi).substring(2,4) + Integer.toHexString(hi).substring(0,2);
+		}
+		return encryptedPwd;
+	}
+}
+
+
Index: src/core/com/lowagie/text/rtf/parser/properties/RtfPropertyListener.java
===================================================================
--- src/core/com/lowagie/text/rtf/parser/properties/RtfPropertyListener.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/parser/properties/RtfPropertyListener.java	(revision 0)
@@ -0,0 +1,69 @@
+/* 
+ * $Id: RtfPropertyListener.java 3373 2008-05-12 16:21:24Z xlv $
+ *
+ * Copyright 2007 by Howard Shank (hgshank@yahoo.com)
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+package com.lowagie.text.rtf.parser.properties;
+
+import java.util.EventListener;
+
+/**
+ * <code>RtfPropertyListener</code> interface for handling events.
+ * 
+ * @author Howard Shank (hgshank@yahoo.com)
+ * 
+ *  @since 2.0.8
+ */
+public interface RtfPropertyListener extends EventListener {
+	/**
+	 * 
+	 */
+	public void beforePropertyChange(String propertyName);
+	/**
+	 * 
+	 */
+	public void afterPropertyChange(String propertyName);
+}
Index: src/core/com/lowagie/text/rtf/document/RtfDocumentHeader.java
===================================================================
--- src/core/com/lowagie/text/rtf/document/RtfDocumentHeader.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/document/RtfDocumentHeader.java	(revision 0)
@@ -0,0 +1,341 @@
+/*
+ * $Id: RtfDocumentHeader.java 3580 2008-08-06 15:52:00Z howard_s $
+ *
+ * Copyright 2003, 2004 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.rtf.document;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import com.lowagie.text.DocWriter;
+import com.lowagie.text.HeaderFooter;
+import com.lowagie.text.rtf.RtfElement;
+import com.lowagie.text.rtf.document.output.RtfNilOutputStream;
+import com.lowagie.text.rtf.headerfooter.RtfHeaderFooter;
+import com.lowagie.text.rtf.headerfooter.RtfHeaderFooterGroup;
+import com.lowagie.text.rtf.list.RtfList;
+import com.lowagie.text.rtf.list.RtfListTable;
+import com.lowagie.text.rtf.style.RtfColor;
+import com.lowagie.text.rtf.style.RtfColorList;
+import com.lowagie.text.rtf.style.RtfFont;
+import com.lowagie.text.rtf.style.RtfFontList;
+import com.lowagie.text.rtf.style.RtfParagraphStyle;
+import com.lowagie.text.rtf.style.RtfStylesheetList;
+
+
+/**
+ * The RtfDocumentHeader contains all classes required for the generation of
+ * the document header area.
+ * 
+ * @version $Id: RtfDocumentHeader.java 3580 2008-08-06 15:52:00Z howard_s $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Thomas Bickel (tmb99@inode.at)
+ * @author Howard Shank (hgshank@yahoo.com)
+ */
+public class RtfDocumentHeader extends RtfElement {
+    /**
+     * Constant for the title page
+     */
+    private static final byte[] TITLE_PAGE = DocWriter.getISOBytes("\\titlepg");
+    /**
+     * Constant for facing pages
+     */
+    private static final byte[] FACING_PAGES = DocWriter.getISOBytes("\\facingp");
+    
+    /**
+     * The code page to use
+     */
+    private RtfCodePage codePage = null;
+    /**
+     * Stores all the colors used in the document
+     */
+    private RtfColorList colorList = null;
+    /**
+     * Stores all the fonts used in the document
+     */
+    private RtfFontList fontList = null;
+    /**
+     * Manages List tables
+     */
+    private RtfListTable listTable = null;
+    /**
+     * Stores all paragraph styles used in the document.
+     */
+    private RtfStylesheetList stylesheetList = null;
+    /**
+     * Generator string in document
+     */
+    private RtfGenerator generator = null;
+    /**
+     * The information group with author/subject/keywords/title/producer/creationdate data
+     */
+    private RtfInfoGroup infoGroup = null;
+    /**
+     * The protection settings
+     * Author: Howard Shank (hgshank@yahoo.com)
+     * @since 2.1.1
+     */
+    private RtfProtectionSetting protectionSetting = null;
+    /**
+     * The page settings
+     */
+    private RtfPageSetting pageSetting = null;
+    /**
+     * The current RtfHeaderFooterGroup for the header
+     */
+    private HeaderFooter header = null;
+    /**
+     * The current RtfHeaderFooterGroup for the footer
+     */
+    private HeaderFooter footer = null;
+
+    /**
+     * Constructs a RtfDocumentHeader for a RtfDocument
+     * 
+     * @param doc The RtfDocument this RtfDocumentHeader belongs to
+     */
+    protected RtfDocumentHeader(RtfDocument doc) {
+        super(doc);
+    }
+
+    /**
+     * initializes the RtfDocumentHeader.
+     */
+    protected void init() {
+        this.codePage = new RtfCodePage(this.document);
+        this.colorList = new RtfColorList(this.document);
+        this.fontList = new RtfFontList(this.document);
+        this.listTable = new RtfListTable(this.document);
+        this.stylesheetList = new RtfStylesheetList(this.document);
+        this.infoGroup = new RtfInfoGroup(this.document);
+        this.protectionSetting = new RtfProtectionSetting(this.document);
+        this.pageSetting = new RtfPageSetting(this.document);
+        this.header = new RtfHeaderFooterGroup(this.document, RtfHeaderFooter.TYPE_HEADER);
+        this.footer = new RtfHeaderFooterGroup(this.document, RtfHeaderFooter.TYPE_FOOTER);
+        this.generator = new RtfGenerator(this.document);
+    }
+    
+    /**
+     * Writes the contents of the document header area.
+     */    
+    public void writeContent(final OutputStream result) throws IOException
+    {
+        try {
+            // This is so that all color, font and similar information is processed once, before
+            // the header section is written.
+            writeSectionDefinition(new RtfNilOutputStream());
+            
+            this.codePage.writeDefinition(result);
+            this.fontList.writeDefinition(result);
+            this.colorList.writeDefinition(result);
+            this.stylesheetList.writeDefinition(result);
+            this.listTable.writeDefinition(result);
+            this.generator.writeContent(result);
+            this.infoGroup.writeContent(result);
+            this.protectionSetting.writeDefinition(result);
+            this.pageSetting.writeDefinition(result);
+            
+            writeSectionDefinition(result);
+        } catch(IOException ioe) {
+            ioe.printStackTrace();
+        }
+    }        
+
+    /**
+     * Writes the section definition data
+     * @param result
+     */
+    public void writeSectionDefinition(final OutputStream result) 
+    {
+        try {
+            RtfHeaderFooterGroup header = convertHeaderFooter(this.header, RtfHeaderFooter.TYPE_HEADER);
+            RtfHeaderFooterGroup footer = convertHeaderFooter(this.footer, RtfHeaderFooter.TYPE_FOOTER);
+            if(header.hasTitlePage() || footer.hasTitlePage()) {
+                result.write(TITLE_PAGE);
+                header.setHasTitlePage();
+                footer.setHasTitlePage();
+            }
+            if(header.hasFacingPages() || footer.hasFacingPages()) {
+                result.write(FACING_PAGES);
+                header.setHasFacingPages();
+                footer.setHasFacingPages();
+            }
+            footer.writeContent(result);
+            header.writeContent(result);
+            pageSetting.writeSectionDefinition(result);
+        } catch(IOException ioe) {
+            ioe.printStackTrace();
+        }    	
+    }
+    
+    /**
+     * Gets the number of the specified RtfFont
+     *
+     * @param font The RtfFont for which to get the number
+     * @return The number of the font
+     */
+    public int getFontNumber(RtfFont font) {
+        return this.fontList.getFontNumber(font);
+    }
+
+    /**
+     * Gets the number of the specified RtfColor
+     * 
+     * @param color The RtfColor for which to get the number
+     * @return The number of the color
+     */
+    public int getColorNumber(RtfColor color) {
+        return this.colorList.getColorNumber(color);
+    }
+    
+    /**
+     * Gets the number of the specified RtfList
+     * 
+     * @param list The RtfList for which to get the number
+     * @return The number of the list
+     */
+    public int getListNumber(RtfList list) {
+        return this.listTable.getListNumber(list);
+    }
+    /**
+     * Gets the RtfParagraphStyle with the given style name.
+     * 
+     * @param styleName The style name of the RtfParagraphStyle to get. 
+     * @return The RtfParagraphStyle with the given style name or null.
+     */
+    public RtfParagraphStyle getRtfParagraphStyle(String styleName) {
+        return this.stylesheetList.getRtfParagraphStyle(styleName);
+    }
+    
+    /**
+     * Removes a RtfList from the list table
+     * 
+     * @param list The RtfList to remove
+     */
+    public void freeListNumber(RtfList list) {
+        this.listTable.freeListNumber(list);
+    }
+    
+    /**
+     * Gets the RtfPageSetting object of this RtfDocument
+     * 
+     * @return The RtfPageSetting object
+     */
+    public RtfPageSetting getPageSetting() {
+        return this.pageSetting;
+    }
+    
+    /**
+     * Adds an RtfInfoElement to the list of RtfInfoElements
+     * 
+     * @param rtfInfoElement The RtfInfoElement to add
+     */
+    public void addInfoElement(RtfInfoElement rtfInfoElement) {
+        this.infoGroup.add(rtfInfoElement);
+    }
+    
+    /**
+     * Sets the current header to use
+     * 
+     * @param header The HeaderFooter to use as header
+     */
+    public void setHeader(HeaderFooter header) {
+        this.header = header;
+    }
+    
+    /**
+     * Sets the current footer to use
+     * 
+     * @param footer The HeaderFooter to use as footer
+     */
+    public void setFooter(HeaderFooter footer) {
+        this.footer = footer;
+    }
+    
+    /**
+     * Registers the RtfParagraphStyle for further use in the document.
+     * 
+     * @param rtfParagraphStyle The RtfParagraphStyle to register.
+     */
+    public void registerParagraphStyle(RtfParagraphStyle rtfParagraphStyle) {
+        this.stylesheetList.registerParagraphStyle(rtfParagraphStyle);
+    }
+    
+    /**
+     * Converts a HeaderFooter into a RtfHeaderFooterGroup. Depending on which class
+     * the HeaderFooter is, the correct RtfHeaderFooterGroup is created.
+     * 
+     * @param hf The HeaderFooter to convert.
+     * @param type Whether the conversion is being done on a footer or header
+     * @return The converted RtfHeaderFooterGroup.
+     * @see com.lowagie.text.rtf.headerfooter.RtfHeaderFooter
+     * @see com.lowagie.text.rtf.headerfooter.RtfHeaderFooterGroup
+     */
+    private RtfHeaderFooterGroup convertHeaderFooter(HeaderFooter hf, int type) {
+        if(hf != null) {
+            if(hf instanceof RtfHeaderFooterGroup) {
+                return new RtfHeaderFooterGroup(this.document, (RtfHeaderFooterGroup) hf, type);
+            } else if(hf instanceof RtfHeaderFooter) {
+                return new RtfHeaderFooterGroup(this.document, (RtfHeaderFooter) hf, type);
+            } else {
+                return new RtfHeaderFooterGroup(this.document, hf, type);
+            }
+        } else {
+            return new RtfHeaderFooterGroup(this.document, type);
+        }
+    }
+    /**
+     * Get the <code>RtfListTable</code> object.
+     * 
+     * @return the ListTable object.
+     * @since 2.1.3
+     */
+    public RtfListTable getListTable() {
+    	return this.listTable;
+    }
+}
Index: src/core/com/lowagie/text/rtf/style/RtfParagraphStyle.java
===================================================================
--- src/core/com/lowagie/text/rtf/style/RtfParagraphStyle.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/style/RtfParagraphStyle.java	(revision 0)
@@ -0,0 +1,730 @@
+/*
+ * $Id: RtfParagraphStyle.java 3580 2008-08-06 15:52:00Z howard_s $
+ *
+ * Copyright 2001, 2002, 2003, 2004 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+package com.lowagie.text.rtf.style;
+
+import java.awt.Color;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import com.lowagie.text.DocWriter;
+import com.lowagie.text.Element;
+import com.lowagie.text.Font;
+import com.lowagie.text.rtf.RtfBasicElement;
+import com.lowagie.text.rtf.document.RtfDocument;
+import com.lowagie.text.rtf.text.RtfParagraph;
+
+/**
+ * The RtfParagraphStyle stores all style/formatting attributes of a RtfParagraph.
+ * Additionally it also supports the style name system available in RTF. The RtfParagraphStyle
+ * is a Font and can thus be used as such. To use the stylesheet functionality
+ * it needs to be set as the font of a Paragraph. Otherwise it will work like a
+ * RtfFont. It also supports inheritance of styles.
+ * 
+ * @version $Id: RtfParagraphStyle.java 3580 2008-08-06 15:52:00Z howard_s $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Thomas Bickel (tmb99@inode.at)
+ */
+public class RtfParagraphStyle extends RtfFont {
+
+    /**
+     * Constant for left alignment
+     */
+    public static final byte[] ALIGN_LEFT = DocWriter.getISOBytes("\\ql");
+    /**
+     * Constant for right alignment
+     */
+    public static final byte[] ALIGN_RIGHT = DocWriter.getISOBytes("\\qr");
+    /**
+     * Constant for center alignment
+     */
+    public static final byte[] ALIGN_CENTER = DocWriter.getISOBytes("\\qc");
+    /**
+     * Constant for justified alignment
+     */
+    public static final byte[] ALIGN_JUSTIFY = DocWriter.getISOBytes("\\qj");
+    /**
+     * Constant for the first line indentation
+     */
+    public static final byte[] FIRST_LINE_INDENT = DocWriter.getISOBytes("\\fi");
+    /**
+     * Constant for left indentation
+     */
+    public static final byte[] INDENT_LEFT = DocWriter.getISOBytes("\\li");
+    /**
+     * Constant for right indentation
+     */
+    public static final byte[] INDENT_RIGHT = DocWriter.getISOBytes("\\ri");
+    /**
+     * Constant for keeping the paragraph together on one page
+     */
+    public static final byte[] KEEP_TOGETHER = DocWriter.getISOBytes("\\keep");
+    /**
+     * Constant for keeping the paragraph together with the next one on one page
+     */
+    public static final byte[] KEEP_TOGETHER_WITH_NEXT = DocWriter.getISOBytes("\\keepn");
+    /**
+     * Constant for the space after the paragraph.
+     */
+    public static final byte[] SPACING_AFTER = DocWriter.getISOBytes("\\sa");
+    /**
+     * Constant for the space before the paragraph.
+     */
+    public static final byte[] SPACING_BEFORE = DocWriter.getISOBytes("\\sb");
+
+    /**
+     * The NORMAL/STANDARD style.
+     */
+    public static final RtfParagraphStyle STYLE_NORMAL = new RtfParagraphStyle("Normal", "Arial", 12, Font.NORMAL, Color.black);
+    /**
+     * The style for level 1 headings.
+     */
+    public static final RtfParagraphStyle STYLE_HEADING_1 = new RtfParagraphStyle("heading 1", "Normal");
+    /**
+     * The style for level 2 headings.
+     */
+    public static final RtfParagraphStyle STYLE_HEADING_2 = new RtfParagraphStyle("heading 2", "Normal");
+    /**
+     * The style for level 3 headings.
+     */
+    public static final RtfParagraphStyle STYLE_HEADING_3 = new RtfParagraphStyle("heading 3", "Normal");
+
+    /**
+     * Initializes the properties of the styles.
+     */
+    static {
+        STYLE_HEADING_1.setSize(16);
+        STYLE_HEADING_1.setStyle(Font.BOLD);
+        STYLE_HEADING_2.setSize(14);
+        STYLE_HEADING_2.setStyle(Font.BOLDITALIC);
+        STYLE_HEADING_3.setSize(13);
+        STYLE_HEADING_3.setStyle(Font.BOLD);
+    }
+    
+    /**
+     * No modification has taken place when compared to the RtfParagraphStyle this RtfParagraphStyle
+     * is based on. These modification markers are used to determine what needs to be
+     * inherited and what not from the parent RtfParagraphStyle.
+     */
+    private static final int MODIFIED_NONE = 0;
+    /**
+     * The alignment has been modified.
+     */
+    private static final int MODIFIED_ALIGNMENT = 1;
+    /**
+     * The left indentation has been modified.
+     */
+    private static final int MODIFIED_INDENT_LEFT = 2;
+    /**
+     * The right indentation has been modified.
+     */
+    private static final int MODIFIED_INDENT_RIGHT = 4;
+    /**
+     * The spacing before a paragraph has been modified.
+     */
+    private static final int MODIFIED_SPACING_BEFORE = 8;
+    /**
+     * The spacing after a paragraph has been modified.
+     */
+    private static final int MODIFIED_SPACING_AFTER = 16;
+    /**
+     * The font name has been modified.
+     */
+    private static final int MODIFIED_FONT_NAME = 32;
+    /**
+     * The font style has been modified.
+     */
+    private static final int MODIFIED_FONT_SIZE = 64;
+    /**
+     * The font size has been modified.
+     */
+    private static final int MODIFIED_FONT_STYLE = 128;
+    /**
+     * The font color has been modified.
+     */
+    private static final int MODIFIED_FONT_COLOR = 256;
+    /**
+     * The line leading has been modified. 
+     */
+    private static final int MODIFIED_LINE_LEADING = 512;
+    /**
+     * The paragraph keep together setting has been modified.
+     */
+    private static final int MODIFIED_KEEP_TOGETHER = 1024;
+    /**
+     * The paragraph keep together with next setting has been modified.
+     */
+    private static final int MODIFIED_KEEP_TOGETHER_WITH_NEXT = 2048;
+    
+    /**
+     * The alignment of the paragraph.
+     */
+    private int alignment = Element.ALIGN_LEFT;
+    /**
+     * The indentation for the first line
+     */
+    private int firstLineIndent = 0;
+    /**
+     * The left indentation of the paragraph.
+     */
+    private int indentLeft = 0;
+    /**
+     * The right indentation of the paragraph.
+     */
+    private int indentRight = 0;
+    /**
+     * The spacing before a paragraph.
+     */
+    private int spacingBefore = 0;
+    /**
+     * The spacing after a paragraph.
+     */
+    private int spacingAfter = 0;
+    /**
+     * The line leading of the paragraph.
+     */
+    private int lineLeading = 0;
+    /**
+     * Whether this RtfParagraph must stay on one page.
+     */
+    private boolean keepTogether = false;
+    /**
+     * Whether this RtfParagraph must stay on the same page as the next paragraph.
+     */
+    private boolean keepTogetherWithNext = false;
+    /**
+     * The name of this RtfParagraphStyle.
+     */
+    private String styleName = "";
+    /**
+     * The name of the RtfParagraphStyle this RtfParagraphStyle is based on.
+     */
+    private String basedOnName = null;
+    /**
+     * The RtfParagraphStyle this RtfParagraphStyle is based on.
+     */
+    private RtfParagraphStyle baseStyle = null;
+    /**
+     * Which properties have been modified when compared to the base style.
+     */
+    private int modified = MODIFIED_NONE;
+    /**
+     * The number of this RtfParagraphStyle in the stylesheet list.
+     */
+    private int styleNumber = -1;
+    
+    /**
+     * Constructs a new RtfParagraphStyle with the given attributes.
+     * 
+     * @param styleName The name of this RtfParagraphStyle.
+     * @param fontName The name of the font to use for this RtfParagraphStyle.
+     * @param fontSize The size of the font to use for this RtfParagraphStyle.
+     * @param fontStyle The style of the font to use for this RtfParagraphStyle.
+     * @param fontColor The color of the font to use for this RtfParagraphStyle.
+     */
+    public RtfParagraphStyle(String styleName, String fontName, int fontSize, int fontStyle, Color fontColor) {
+        super(null, new RtfFont(fontName, fontSize, fontStyle, fontColor));
+        this.styleName = styleName;
+    }
+    
+    /**
+     * Constructs a new RtfParagraphStyle that is based on an existing RtfParagraphStyle.
+     * 
+     * @param styleName The name of this RtfParagraphStyle.
+     * @param basedOnName The name of the RtfParagraphStyle this RtfParagraphStyle is based on.
+     */
+    public RtfParagraphStyle(String styleName, String basedOnName) {
+        super(null, new Font());
+        this.styleName = styleName;
+        this.basedOnName = basedOnName;
+    }
+    
+    /**
+     * Constructs a RtfParagraphStyle from another RtfParagraphStyle.
+     * 
+     * INTERNAL USE ONLY
+     * 
+     * @param doc The RtfDocument this RtfParagraphStyle belongs to.
+     * @param style The RtfParagraphStyle to copy settings from.
+     */
+    public RtfParagraphStyle(RtfDocument doc, RtfParagraphStyle style) {
+        super(doc, style);
+        this.document = doc;
+        this.styleName = style.getStyleName();
+        this.alignment = style.getAlignment();
+        this.firstLineIndent = (int)(style.getFirstLineIndent() * RtfBasicElement.TWIPS_FACTOR);
+        this.indentLeft = (int) (style.getIndentLeft() * RtfBasicElement.TWIPS_FACTOR);
+        this.indentRight = (int) (style.getIndentRight() * RtfBasicElement.TWIPS_FACTOR);
+        this.spacingBefore = (int) (style.getSpacingBefore() * RtfBasicElement.TWIPS_FACTOR);
+        this.spacingAfter = (int) (style.getSpacingAfter() * RtfBasicElement.TWIPS_FACTOR);
+        this.lineLeading = (int) (style.getLineLeading() * RtfBasicElement.TWIPS_FACTOR);
+        this.keepTogether = style.getKeepTogether();
+        this.keepTogetherWithNext = style.getKeepTogetherWithNext();
+        this.basedOnName = style.basedOnName;
+        this.modified = style.modified;
+        this.styleNumber = style.getStyleNumber();
+
+        if(this.document != null) {
+            setRtfDocument(this.document);
+        }
+    }
+
+    /**
+     * Gets the name of this RtfParagraphStyle.
+     * 
+     * @return The name of this RtfParagraphStyle.
+     */
+    public String getStyleName() {
+        return this.styleName;
+    }
+    
+    /**
+     * Gets the name of the RtfParagraphStyle this RtfParagraphStyle is based on.
+     * 
+     * @return The name of the base RtfParagraphStyle.
+     */
+    public String getBasedOnName() {
+        return this.basedOnName;
+    }
+    
+    /**
+     * Gets the alignment of this RtfParagraphStyle.
+     * 
+     * @return The alignment of this RtfParagraphStyle.
+     */
+    public int getAlignment() {
+        return this.alignment;
+    }
+
+    /**
+     * Sets the alignment of this RtfParagraphStyle.
+     * 
+     * @param alignment The alignment to use.
+     */
+    public void setAlignment(int alignment) {
+        this.modified = this.modified | MODIFIED_ALIGNMENT;
+        this.alignment = alignment;
+    }
+    
+    /**
+     * Gets the first line indentation of this RtfParagraphStyle.
+     * 
+     * @return The first line indentation of this RtfParagraphStyle.
+     */
+    public int getFirstLineIndent() {
+        return this.firstLineIndent;
+    }
+    
+    /**
+     * Sets the first line indentation of this RtfParagraphStyle. It
+     * is relative to the left indentation.
+     * 
+     * @param firstLineIndent The first line indentation to use.
+     */
+    public void setFirstLineIndent(int firstLineIndent) {
+        this.firstLineIndent = firstLineIndent;
+    }
+    
+    /**
+     * Gets the left indentation of this RtfParagraphStyle.
+     * 
+     * @return The left indentation of this RtfParagraphStyle.
+     */
+    public int getIndentLeft() {
+        return this.indentLeft;
+    }
+
+    /**
+     * Sets the left indentation of this RtfParagraphStyle.
+     * 
+     * @param indentLeft The left indentation to use.
+     */
+    public void setIndentLeft(int indentLeft) {
+        this.modified = this.modified | MODIFIED_INDENT_LEFT;
+        this.indentLeft = indentLeft;
+    }
+    
+    /**
+     * Gets the right indentation of this RtfParagraphStyle.
+     * 
+     * @return The right indentation of this RtfParagraphStyle.
+     */
+    public int getIndentRight() {
+        return this.indentRight;
+    }
+
+    /**
+     * Sets the right indentation of this RtfParagraphStyle.
+     * 
+     * @param indentRight The right indentation to use.
+     */
+    public void setIndentRight(int indentRight) {
+        this.modified = this.modified | MODIFIED_INDENT_RIGHT;
+        this.indentRight = indentRight;
+    }
+    
+    /**
+     * Gets the space before the paragraph of this RtfParagraphStyle..
+     * 
+     * @return The space before the paragraph.
+     */
+    public int getSpacingBefore() {
+        return this.spacingBefore;
+    }
+
+    /**
+     * Sets the space before the paragraph of this RtfParagraphStyle.
+     * 
+     * @param spacingBefore The space before to use.
+     */
+    public void setSpacingBefore(int spacingBefore) {
+        this.modified = this.modified | MODIFIED_SPACING_BEFORE;
+        this.spacingBefore = spacingBefore;
+    }
+    
+    /**
+     * Gets the space after the paragraph of this RtfParagraphStyle.
+     * 
+     * @return The space after the paragraph.
+     */
+    public int getSpacingAfter() {
+        return this.spacingAfter;
+    }
+    
+    /**
+     * Sets the space after the paragraph of this RtfParagraphStyle.
+     * 
+     * @param spacingAfter The space after to use.
+     */
+    public void setSpacingAfter(int spacingAfter) {
+        this.modified = this.modified | MODIFIED_SPACING_AFTER;
+        this.spacingAfter = spacingAfter;
+    }
+    
+    /**
+     * Sets the font name of this RtfParagraphStyle.
+     * 
+     * @param fontName The font name to use 
+     */
+    public void setFontName(String fontName) {
+        this.modified = this.modified | MODIFIED_FONT_NAME;
+        super.setFontName(fontName);
+    }
+    
+    /**
+     * Sets the font size of this RtfParagraphStyle.
+     * 
+     * @param fontSize The font size to use.
+     */
+    public void setSize(float fontSize) {
+        this.modified = this.modified | MODIFIED_FONT_SIZE;
+        super.setSize(fontSize);
+    }
+    
+    /**
+     * Sets the font style of this RtfParagraphStyle.
+     * 
+     * @param fontStyle The font style to use.
+     */
+    public void setStyle(int fontStyle) {
+        this.modified = this.modified | MODIFIED_FONT_STYLE;
+        super.setStyle(fontStyle);
+    }
+    
+    /**
+     * Sets the color of this RtfParagraphStyle.
+     * 
+     * @param color The Color to use.
+     */
+    public void setColor(Color color) {
+        this.modified = this.modified | MODIFIED_FONT_COLOR;
+        super.setColor(color);
+    }
+    
+    /**
+     * Gets the line leading of this RtfParagraphStyle.
+     * 
+     * @return The line leading of this RtfParagraphStyle.
+     */
+    public int getLineLeading() {
+        return this.lineLeading;
+    }
+    
+    /**
+     * Sets the line leading of this RtfParagraphStyle.
+     * 
+     * @param lineLeading The line leading to use.
+     */
+    public void setLineLeading(int lineLeading) {
+        this.lineLeading = lineLeading;
+        this.modified = this.modified | MODIFIED_LINE_LEADING;
+    }
+    
+    /**
+     * Gets whether the lines in the paragraph should be kept together in
+     * this RtfParagraphStyle.
+     * 
+     * @return Whether the lines in the paragraph should be kept together.
+     */
+    public boolean getKeepTogether() {
+        return this.keepTogether;
+    }
+    
+    /**
+     * Sets whether the lines in the paragraph should be kept together in
+     * this RtfParagraphStyle.
+     * 
+     * @param keepTogether Whether the lines in the paragraph should be kept together.
+     */
+    public void setKeepTogether(boolean keepTogether) {
+        this.keepTogether = keepTogether;
+        this.modified = this.modified | MODIFIED_KEEP_TOGETHER;
+    }
+    
+    /**
+     * Gets whether the paragraph should be kept together with the next in
+     * this RtfParagraphStyle.
+     * 
+     * @return Whether the paragraph should be kept together with the next.
+     */
+    public boolean getKeepTogetherWithNext() {
+        return this.keepTogetherWithNext;
+    }
+    
+    /**
+     * Sets whether the paragraph should be kept together with the next in
+     * this RtfParagraphStyle.
+     * 
+     * @param keepTogetherWithNext Whether the paragraph should be kept together with the next.
+     */
+    public void setKeepTogetherWithNext(boolean keepTogetherWithNext) {
+        this.keepTogetherWithNext = keepTogetherWithNext;
+        this.modified = this.modified | MODIFIED_KEEP_TOGETHER_WITH_NEXT;
+    }
+    
+    /**
+     * Handles the inheritance of paragraph style settings. All settings that
+     * have not been modified will be inherited from the base RtfParagraphStyle.
+     * If this RtfParagraphStyle is not based on another one, then nothing happens.
+     */
+    public void handleInheritance() {
+        if(this.basedOnName != null && this.document.getDocumentHeader().getRtfParagraphStyle(this.basedOnName) != null) {
+            this.baseStyle = this.document.getDocumentHeader().getRtfParagraphStyle(this.basedOnName);
+            this.baseStyle.handleInheritance();
+            if(!((this.modified & MODIFIED_ALIGNMENT) == MODIFIED_ALIGNMENT)) {
+                this.alignment = this.baseStyle.getAlignment();
+            }
+            if(!((this.modified & MODIFIED_INDENT_LEFT) == MODIFIED_INDENT_LEFT)) {
+                this.indentLeft = this.baseStyle.getIndentLeft();
+            }
+            if(!((this.modified & MODIFIED_INDENT_RIGHT) == MODIFIED_INDENT_RIGHT)) {
+                this.indentRight = this.baseStyle.getIndentRight();
+            }
+            if(!((this.modified & MODIFIED_SPACING_BEFORE) == MODIFIED_SPACING_BEFORE)) {
+                this.spacingBefore = this.baseStyle.getSpacingBefore();
+            }
+            if(!((this.modified & MODIFIED_SPACING_AFTER) == MODIFIED_SPACING_AFTER)) {
+                this.spacingAfter = this.baseStyle.getSpacingAfter();
+            }
+            if(!((this.modified & MODIFIED_FONT_NAME) == MODIFIED_FONT_NAME)) {
+                setFontName(this.baseStyle.getFontName());
+            }
+            if(!((this.modified & MODIFIED_FONT_SIZE) == MODIFIED_FONT_SIZE)) {
+                setSize(this.baseStyle.getFontSize());
+            }
+            if(!((this.modified & MODIFIED_FONT_STYLE) == MODIFIED_FONT_STYLE)) {
+                setStyle(this.baseStyle.getFontStyle());
+            }
+            if(!((this.modified & MODIFIED_FONT_COLOR) == MODIFIED_FONT_COLOR)) {
+                setColor(this.baseStyle.getColor());
+            }
+            if(!((this.modified & MODIFIED_LINE_LEADING) == MODIFIED_LINE_LEADING)) {
+                setLineLeading(this.baseStyle.getLineLeading());
+            }
+            if(!((this.modified & MODIFIED_KEEP_TOGETHER) == MODIFIED_KEEP_TOGETHER)) {
+                setKeepTogether(this.baseStyle.getKeepTogether());
+            }
+            if(!((this.modified & MODIFIED_KEEP_TOGETHER_WITH_NEXT) == MODIFIED_KEEP_TOGETHER_WITH_NEXT)) {
+                setKeepTogetherWithNext(this.baseStyle.getKeepTogetherWithNext());
+            }
+        }
+    }
+    
+    /**
+     * Writes the settings of this RtfParagraphStyle.
+     * 
+     * @param result The <code>OutputStream</code> to write to.
+     * @throws IOException On i/o errors.
+     */
+    private void writeParagraphSettings(final OutputStream result) throws IOException {
+        if(this.keepTogether) {
+            result.write(RtfParagraphStyle.KEEP_TOGETHER);
+        }
+        if(this.keepTogetherWithNext) {
+            result.write(RtfParagraphStyle.KEEP_TOGETHER_WITH_NEXT);
+        }
+        switch (alignment) {
+            case Element.ALIGN_LEFT:
+                result.write(RtfParagraphStyle.ALIGN_LEFT);
+                break;
+            case Element.ALIGN_RIGHT:
+                result.write(RtfParagraphStyle.ALIGN_RIGHT);
+                break;
+            case Element.ALIGN_CENTER:
+                result.write(RtfParagraphStyle.ALIGN_CENTER);
+                break;
+            case Element.ALIGN_JUSTIFIED:
+            case Element.ALIGN_JUSTIFIED_ALL:
+                result.write(RtfParagraphStyle.ALIGN_JUSTIFY);
+                break;
+        }
+        result.write(FIRST_LINE_INDENT);
+        result.write(intToByteArray(this.firstLineIndent));
+        result.write(RtfParagraphStyle.INDENT_LEFT);
+        result.write(intToByteArray(indentLeft));
+        result.write(RtfParagraphStyle.INDENT_RIGHT);
+        result.write(intToByteArray(indentRight));
+        if(this.spacingBefore > 0) {
+            result.write(RtfParagraphStyle.SPACING_BEFORE);
+            result.write(intToByteArray(this.spacingBefore));
+        }
+        if(this.spacingAfter > 0) {
+            result.write(RtfParagraphStyle.SPACING_AFTER);
+            result.write(intToByteArray(this.spacingAfter));
+        }
+        if(this.lineLeading > 0) {
+            result.write(RtfParagraph.LINE_SPACING);
+            result.write(intToByteArray(this.lineLeading));
+        }            
+    }
+
+    /**
+     * Writes the definition of this RtfParagraphStyle for the stylesheet list.
+     */
+    public void writeDefinition(final OutputStream result) throws IOException 
+    {
+        result.write(DocWriter.getISOBytes("{"));
+        result.write(DocWriter.getISOBytes("\\style"));
+        result.write(DocWriter.getISOBytes("\\s"));
+        result.write(intToByteArray(this.styleNumber));
+        result.write(RtfBasicElement.DELIMITER);
+        writeParagraphSettings(result);
+        super.writeBegin(result);
+        result.write(RtfBasicElement.DELIMITER);
+        result.write(DocWriter.getISOBytes(this.styleName));
+        result.write(DocWriter.getISOBytes(";"));
+        result.write(DocWriter.getISOBytes("}"));
+        this.document.outputDebugLinebreak(result);   	
+    }
+    
+    /**
+     * Writes the start information of this RtfParagraphStyle.
+     *
+     * @param result The <code>OutputStream</code> to write to.
+     * @throws IOException On i/o errors.
+     */
+    public void writeBegin(final OutputStream result) throws IOException {
+        result.write(DocWriter.getISOBytes("\\s"));
+        result.write(intToByteArray(this.styleNumber));
+        writeParagraphSettings(result);
+    }
+    
+    /**
+     * Unused
+     * 
+     * @param result The <code>OutputStream</code> that nothing is written to
+     * @throws IOException On i/o errors.
+     */
+    public void writeEnd(final OutputStream result) throws IOException {
+    }
+    
+    /**
+     * unused
+     */
+    public void writeContent(final OutputStream out) throws IOException
+    {    	
+    }
+    
+    /**
+     * Tests whether two RtfParagraphStyles are equal. Equality
+     * is determined via the name.
+     */
+    public boolean equals(Object o) {
+        if(!(o instanceof RtfParagraphStyle)) {
+            return false;
+        }
+        RtfParagraphStyle paragraphStyle = (RtfParagraphStyle) o;
+        boolean result = this.getStyleName().equals(paragraphStyle.getStyleName());
+        return result;
+    }
+    
+    /**
+     * Gets the hash code of this RtfParagraphStyle.
+     */
+    public int hashCode() {
+        return this.styleName.hashCode();
+    }
+    
+    /**
+     * Gets the number of this RtfParagraphStyle in the stylesheet list.
+     * 
+     * @return The number of this RtfParagraphStyle in the stylesheet list.
+     */
+    private int getStyleNumber() {
+        return this.styleNumber;
+    }
+    
+    /**
+     * Sets the number of this RtfParagraphStyle in the stylesheet list.
+     * 
+     * @param styleNumber The number to use.
+     */
+    protected void setStyleNumber(int styleNumber) {
+        this.styleNumber = styleNumber;
+    }
+}
Index: src/core/com/lowagie/text/rtf/style/RtfStylesheetList.java
===================================================================
--- src/core/com/lowagie/text/rtf/style/RtfStylesheetList.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/style/RtfStylesheetList.java	(revision 0)
@@ -0,0 +1,165 @@
+/*
+ * $Id: RtfStylesheetList.java 3580 2008-08-06 15:52:00Z howard_s $
+ *
+ * Copyright 2001, 2002, 2003, 2004 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.rtf.style;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.Iterator;
+
+import com.lowagie.text.DocWriter;
+import com.lowagie.text.rtf.RtfBasicElement;
+import com.lowagie.text.rtf.RtfElement;
+import com.lowagie.text.rtf.RtfExtendedElement;
+import com.lowagie.text.rtf.document.RtfDocument;
+
+/**
+ * The RtfStylesheetList stores the RtfParagraphStyles that are used in the document.
+ * 
+ * @version $Id: RtfStylesheetList.java 3580 2008-08-06 15:52:00Z howard_s $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Thomas Bickel (tmb99@inode.at)
+ */
+public class RtfStylesheetList extends RtfElement implements RtfExtendedElement {
+
+    /**
+     * The HashMap containing the RtfParagraphStyles.
+     */
+    private HashMap styleMap = null;
+    /**
+     * Whether the default settings have been loaded.
+     */
+    private boolean defaultsLoaded = false;
+    
+    /**
+     * Constructs a new RtfStylesheetList for the RtfDocument.
+     * 
+     * @param doc The RtfDocument this RtfStylesheetList belongs to.
+     */
+    public RtfStylesheetList(RtfDocument doc) {
+        super(doc);
+        this.styleMap = new HashMap();
+    }
+
+    /**
+     * unused
+     */
+    public void writeContent(OutputStream out) throws IOException
+    {	
+    }
+    
+    /**
+     * Register a RtfParagraphStyle with this RtfStylesheetList.
+     * 
+     * @param rtfParagraphStyle The RtfParagraphStyle to add.
+     */
+    public void registerParagraphStyle(RtfParagraphStyle rtfParagraphStyle) {
+        RtfParagraphStyle tempStyle = new RtfParagraphStyle(this.document, rtfParagraphStyle);
+        tempStyle.handleInheritance();
+        tempStyle.setStyleNumber(this.styleMap.size());
+        this.styleMap.put(tempStyle.getStyleName(), tempStyle);
+    }
+
+    /**
+     * Registers all default styles. If styles with the given name have already been registered,
+     * then they are NOT overwritten.
+     */
+    private void registerDefaultStyles() {
+        defaultsLoaded = true;
+        if(!this.styleMap.containsKey(RtfParagraphStyle.STYLE_NORMAL.getStyleName())) {
+            registerParagraphStyle(RtfParagraphStyle.STYLE_NORMAL);
+        }
+        if(!this.styleMap.containsKey(RtfParagraphStyle.STYLE_HEADING_1.getStyleName())) {
+            registerParagraphStyle(RtfParagraphStyle.STYLE_HEADING_1);
+        }
+        if(!this.styleMap.containsKey(RtfParagraphStyle.STYLE_HEADING_2.getStyleName())) {
+            registerParagraphStyle(RtfParagraphStyle.STYLE_HEADING_2);
+        }
+        if(!this.styleMap.containsKey(RtfParagraphStyle.STYLE_HEADING_3.getStyleName())) {
+            registerParagraphStyle(RtfParagraphStyle.STYLE_HEADING_3);
+        }
+    }
+
+    /**
+     * Gets the RtfParagraphStyle with the given name. Makes sure that the defaults
+     * have been loaded.
+     * 
+     * @param styleName The name of the RtfParagraphStyle to get.
+     * @return The RtfParagraphStyle with the given name or null.
+     */
+    public RtfParagraphStyle getRtfParagraphStyle(String styleName) {
+        if(!defaultsLoaded) {
+            registerDefaultStyles();
+        }
+        if(this.styleMap.containsKey(styleName)) {
+            return (RtfParagraphStyle) this.styleMap.get(styleName);
+        } else {
+            return null;
+        }
+    }
+    
+    /**
+     * Writes the definition of the stylesheet list.
+     */
+    public void writeDefinition(final OutputStream result) throws IOException
+    {
+        result.write(DocWriter.getISOBytes("{"));
+        result.write(DocWriter.getISOBytes("\\stylesheet"));
+        result.write(RtfBasicElement.DELIMITER);
+        this.document.outputDebugLinebreak(result);
+        Iterator it = this.styleMap.values().iterator();
+        while(it.hasNext()) {
+        	RtfParagraphStyle rps = (RtfParagraphStyle)it.next();
+        	rps.writeDefinition(result);
+        }
+        result.write(DocWriter.getISOBytes("}"));
+        this.document.outputDebugLinebreak(result);  	
+    }
+}
Index: src/core/com/lowagie/text/rtf/field/RtfTableOfContents.java
===================================================================
--- src/core/com/lowagie/text/rtf/field/RtfTableOfContents.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/field/RtfTableOfContents.java	(revision 0)
@@ -0,0 +1,116 @@
+/*
+ * $Id: RtfTableOfContents.java 3580 2008-08-06 15:52:00Z howard_s $
+ *
+ * Copyright 2004 by Mark Hall
+ * Uses code Copyright 2002
+ *   Steffen.Stundzig (Steffen.Stundzig@smb-tec.com) 
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.rtf.field;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import com.lowagie.text.DocWriter;
+import com.lowagie.text.Font;
+
+
+
+/**
+ * The RtfTableOfContents together with multiple RtfTOCEntry objects generates a table 
+ * of contents. The table of contents will display no entries in the viewing program
+ * and the user will have to update it first. A text to inform the user of this is
+ * displayed instead.
+ * 
+ * @version $Id: RtfTableOfContents.java 3580 2008-08-06 15:52:00Z howard_s $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Steffen.Stundzig (Steffen.Stundzig@smb-tec.com) 
+ * @author Thomas Bickel (tmb99@inode.at)
+ */
+public class RtfTableOfContents extends RtfField {
+
+	/**
+	 * field inst content
+	 */
+	private final static String FIELD_INST = "TOC \\\\f \\\\h \\\\u \\\\o \"1-5\" ";
+    /**
+     * The default text to display
+     */
+    private String defaultText = "Table of Contents - Click to update";
+    
+    /**
+     * Constructs a RtfTableOfContents. The default text is the text that is displayed
+     * before the user updates the table of contents
+     * 
+     * @param defaultText The default text to display
+     */
+    public RtfTableOfContents(String defaultText) {
+        super(null, new Font());
+        this.defaultText = defaultText;
+    }
+    
+    /**
+     * Writes the field instruction content
+     * 
+     * @param result The <code>OutputStream</code> to write to.
+     * @throws IOException on i/o errors.
+     */ 
+    protected void writeFieldInstContent(final OutputStream result) throws IOException 
+    {
+    	result.write(DocWriter.getISOBytes(FIELD_INST));
+    }
+
+    /**
+     * Writes the field result content
+     * 
+     * @param out The <code>OutputStream</code> to write to.
+     * @throws IOException on i/o errors.
+     */
+    protected void writeFieldResultContent(final OutputStream out) throws IOException 
+    {
+    	document.filterSpecialChar(out, defaultText, true, true);
+    }    
+}
Index: src/core/com/lowagie/text/rtf/document/output/RtfNilOutputStream.java
===================================================================
--- src/core/com/lowagie/text/rtf/document/output/RtfNilOutputStream.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/document/output/RtfNilOutputStream.java	(revision 0)
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2007 Thomas Bickel
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.rtf.document.output;
+
+import java.io.OutputStream;
+
+/**
+ * The RtfNilOutputStream is a dummy output stream that sends all
+ * bytes to the big byte bucket in the sky. It is used to improve
+ * speed in those situations where processing is required, but
+ * the results are not needed.
+ * 
+ * @version $Id: RtfNilOutputStream.java 3361 2008-05-11 12:28:57Z hallm $
+ * @author Thomas Bickel (tmb99@inode.at)
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ */
+public final class RtfNilOutputStream extends OutputStream
+{
+    /**
+     * The number of bytes theoretically written is stored.
+     */
+    private long size = 0;
+    
+    /**
+     * Constructs a new <code>RtfNilOutputStream</code>.
+     */
+    public RtfNilOutputStream()
+    {           
+    }
+    
+    /**
+     * Gets the number of bytes that were written.
+     * 
+     * @return The number of bytes that were written.
+     */
+    public long getSize()
+    {
+        return size;
+    }
+    
+    /**
+     * Write an int. The size is incremented, but the actual data is thrown away.
+     */
+    public void write(int b)
+    {
+        size++;
+    }
+    
+    /**
+     * Write a <code>byte[]</code>. The size is incremented, but the actual data is thrown away.
+     */
+    public void write(byte[] b, int off, int len)
+    {
+        if (b == null) {
+            throw new NullPointerException();
+        } else if ((off < 0) || (off > b.length) || (len < 0) ||
+               ((off + len) > b.length) || ((off + len) < 0)) {
+            throw new IndexOutOfBoundsException();
+        }
+        size += len;
+    }
+}
\ No newline at end of file
Index: src/core/com/lowagie/text/rtf/table/RtfBorder.java
===================================================================
--- src/core/com/lowagie/text/rtf/table/RtfBorder.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/table/RtfBorder.java	(revision 0)
@@ -0,0 +1,566 @@
+/*
+ * $Id: RtfBorder.java 3580 2008-08-06 15:52:00Z howard_s $
+ *
+ * Copyright 2001, 2002, 2003, 2004 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.rtf.table;
+
+import java.awt.Color;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import com.lowagie.text.DocWriter;
+import com.lowagie.text.rtf.RtfElement;
+import com.lowagie.text.rtf.document.RtfDocument;
+import com.lowagie.text.rtf.style.RtfColor;
+
+
+/**
+ * The RtfBorder handle one row or cell border.
+ * INTERNAL USE ONLY
+ * 
+ * @version $Id: RtfBorder.java 3580 2008-08-06 15:52:00Z howard_s $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Thomas Bickel (tmb99@inode.at)
+ */
+public class RtfBorder extends RtfElement {
+
+    /**
+     * Constant for the left row border
+     */
+    protected static final byte[] ROW_BORDER_LEFT = DocWriter.getISOBytes("\\trbrdrl");
+    /**
+     * Constant for the top row border
+     */
+    protected static final byte[] ROW_BORDER_TOP = DocWriter.getISOBytes("\\trbrdrt");
+    /**
+     * Constant for the right row border
+     */
+    protected static final byte[] ROW_BORDER_RIGHT = DocWriter.getISOBytes("\\trbrdrr");
+    /**
+     * Constant for the bottom row border
+     */
+    protected static final byte[] ROW_BORDER_BOTTOM = DocWriter.getISOBytes("\\trbrdrb");
+    /**
+     * Constant for the horizontal line
+     */
+    protected static final byte[] ROW_BORDER_HORIZONTAL = DocWriter.getISOBytes("\\trbrdrh");
+    /**
+     * Constant for the vertical line
+     */
+    protected static final byte[] ROW_BORDER_VERTICAL = DocWriter.getISOBytes("\\trbrdrv");
+    /**
+     * Constant for the left cell border
+     */
+    protected static final byte[] CELL_BORDER_LEFT = DocWriter.getISOBytes("\\clbrdrl");
+    /**
+     * Constant for the top cell border
+     */
+    protected static final byte[] CELL_BORDER_TOP = DocWriter.getISOBytes("\\clbrdrt");
+    /**
+     * Constant for the right cell border
+     */
+    protected static final byte[] CELL_BORDER_RIGHT = DocWriter.getISOBytes("\\clbrdrr");
+    /**
+     * Constant for the bottom cell border
+     */
+    protected static final byte[] CELL_BORDER_BOTTOM = DocWriter.getISOBytes("\\clbrdrb");
+    /**
+     * Constant for the border width
+     */
+    protected static final byte[] BORDER_WIDTH = DocWriter.getISOBytes("\\brdrw");
+    /**
+     * Constant for the border color number
+     */
+    protected static final byte[] BORDER_COLOR_NUMBER = DocWriter.getISOBytes("\\brdrcf");
+    /**
+     * Constant for the single border style
+     */
+    protected static final byte[] BORDER_STYLE_SINGLE = DocWriter.getISOBytes("\\brdrs");
+    /**
+     * Constant for the double thick border style
+     */
+    protected static final byte[] BORDER_STYLE_DOUBLE_THICK	= DocWriter.getISOBytes("\\brdrth");
+    /**
+     * Constant for the shadowed border style
+     */
+    protected static final byte[] BORDER_STYLE_SHADOWED = DocWriter.getISOBytes("\\brdrsh");
+    /**
+     * Constant for the dotted border style
+     */
+    protected static final byte[] BORDER_STYLE_DOTTED = DocWriter.getISOBytes("\\brdrdot");
+    /**
+     * Constant for the dashed border style
+     */
+    protected static final byte[] BORDER_STYLE_DASHED = DocWriter.getISOBytes("\\brdrdash");
+    /**
+     * Constant for the hairline border style
+     */
+    protected static final byte[] BORDER_STYLE_HAIRLINE = DocWriter.getISOBytes("\\brdrhair");
+    /**
+     * Constant for the double border style
+     */
+    protected static final byte[] BORDER_STYLE_DOUBLE = DocWriter.getISOBytes("\\brdrdb");
+    /**
+     * Constant for the dot dash border style
+     */
+    protected static final byte[] BORDER_STYLE_DOT_DASH = DocWriter.getISOBytes("\\brdrdashd");
+    /**
+     * Constant for the dot dot dash border style
+     */
+    protected static final byte[] BORDER_STYLE_DOT_DOT_DASH	= DocWriter.getISOBytes("\\brdrdashdd");
+    /**
+     * Constant for the triple border style
+     */
+    protected static final byte[] BORDER_STYLE_TRIPLE = DocWriter.getISOBytes("\\brdrtriple");
+    /**
+     * Constant for the thick thin border style
+     */
+    protected static final byte[] BORDER_STYLE_THICK_THIN = DocWriter.getISOBytes("\\brdrtnthsg");
+    /**
+     * Constant for the thin thick border style
+     */
+    protected static final byte[] BORDER_STYLE_THIN_THICK = DocWriter.getISOBytes("\\brdrthtnsg");
+    /**
+     * Constant for the thin thick thin border style
+     */
+    protected static final byte[] BORDER_STYLE_THIN_THICK_THIN = DocWriter.getISOBytes("\\brdrtnthtnsg");
+    /**
+     * Constant for the thick thin medium border style
+     */
+    protected static final byte[] BORDER_STYLE_THICK_THIN_MED = DocWriter.getISOBytes("\\brdrtnthmg");
+    /**
+     * Constant for the thin thick medium border style
+     */
+    protected static final byte[] BORDER_STYLE_THIN_THICK_MED = DocWriter.getISOBytes("\\brdrthtnmg");
+    /**
+     * Constant for the thin thick thin medium border style
+     */
+    protected static final byte[] BORDER_STYLE_THIN_THICK_THIN_MED = DocWriter.getISOBytes("\\brdrtnthtnmg");
+    /**
+     * Constant for the thick thin large border style
+     */
+    protected static final byte[] BORDER_STYLE_THICK_THIN_LARGE = DocWriter.getISOBytes("\\brdrtnthlg");
+    /**
+     * Constant for the thin thick large border style
+     */
+    protected static final byte[] BORDER_STYLE_THIN_THICK_LARGE	= DocWriter.getISOBytes("\\brdrthtnlg");
+    /**
+     * Constant for the thin thick thin large border style
+     */
+    protected static final byte[] BORDER_STYLE_THIN_THICK_THIN_LARGE = DocWriter.getISOBytes("\\brdrtnthtnlg");
+    /**
+     * Constant for the wavy border style
+     */
+    protected static final byte[] BORDER_STYLE_WAVY = DocWriter.getISOBytes("\\brdrwavy");
+    /**
+     * Constant for the double wavy border style
+     */
+    protected static final byte[] BORDER_STYLE_DOUBLE_WAVY = DocWriter.getISOBytes("\\brdrwavydb");
+    /**
+     * Constant for the striped border style
+     */
+    protected static final byte[] BORDER_STYLE_STRIPED = DocWriter.getISOBytes("\\brdrdashdotstr");
+    /**
+     * Constant for the embossed border style
+     */
+    protected static final byte[] BORDER_STYLE_EMBOSS = DocWriter.getISOBytes("\\brdremboss");
+    /**
+     * Constant for the engraved border style
+     */
+    protected static final byte[] BORDER_STYLE_ENGRAVE = DocWriter.getISOBytes("\\brdrengrave");
+
+    /**
+     * Constant for a row border
+     */
+    protected static final int ROW_BORDER = 1;
+    /**
+     * Constant for a cell border
+     */
+    protected static final int CELL_BORDER = 2;
+    
+    /**
+     * This border is no border :-)
+     */
+    protected static final int NO_BORDER = 0;
+    /**
+     * Constant for a left border
+     */
+    protected static final int LEFT_BORDER = 1;
+    /**
+     * Constant for a top border
+     */
+    protected static final int TOP_BORDER = 2;
+    /**
+     * Constant for a right border
+     */
+    protected static final int RIGHT_BORDER = 4;
+    /**
+     * Constant for a bottom border
+     */
+    protected static final int BOTTOM_BORDER = 8;
+    /**
+     * Constant for a box (left, top, right, bottom) border 
+     */
+    protected static final int BOX_BORDER = 15;
+    /**
+     * Constant for a vertical line
+     */
+    protected static final int VERTICAL_BORDER = 16;
+    /**
+     * Constant for a horizontal line
+     */
+    protected static final int HORIZONTAL_BORDER = 32;
+    
+    /**
+     * Constant for a border with no border
+     */
+    public static final int BORDER_NONE = 0;
+    /**
+     * Constant for a single border
+     */
+    public static final int BORDER_SINGLE = 1;
+    /**
+     * Constant for a double thick border
+     */
+    public static final int BORDER_DOUBLE_THICK = 2;
+    /**
+     * Constant for a shadowed border
+     */
+    public static final int BORDER_SHADOWED = 3;
+    /**
+     * Constant for a dotted border
+     */
+    public static final int BORDER_DOTTED = 4;
+    /**
+     * Constant for a dashed border
+     */
+    public static final int BORDER_DASHED = 5;
+    /**
+     * Constant for a hairline border
+     */
+    public static final int BORDER_HAIRLINE = 6;
+    /**
+     * Constant for a double border
+     */
+    public static final int BORDER_DOUBLE = 7;
+    /**
+     * Constant for a dot dash border
+     */
+    public static final int BORDER_DOT_DASH = 8;
+    /**
+     * Constant for a dot dot dash border
+     */
+    public static final int BORDER_DOT_DOT_DASH = 9;
+    /**
+     * Constant for a triple border
+     */
+    public static final int BORDER_TRIPLE = 10;
+    /**
+     * Constant for a thick thin border
+     */
+    public static final int BORDER_THICK_THIN = 11;
+    /**
+     * Constant for a thin thick border
+     */
+    public static final int BORDER_THIN_THICK = 12;
+    /**
+     * Constant for a thin thick thin border
+     */
+    public static final int BORDER_THIN_THICK_THIN = 13;
+    /**
+     * Constant for a thick thin medium border
+     */
+    public static final int BORDER_THICK_THIN_MED = 14;
+    /**
+     * Constant for a thin thick medium border
+     */
+    public static final int BORDER_THIN_THICK_MED = 15;
+    /**
+     * Constant for a thin thick thin medium border
+     */
+    public static final int BORDER_THIN_THICK_THIN_MED = 16;
+    /**
+     * Constant for a thick thin large border
+     */
+    public static final int BORDER_THICK_THIN_LARGE = 17;
+    /**
+     * Constant for a thin thick large border
+     */
+    public static final int BORDER_THIN_THICK_LARGE = 18;
+    /**
+     * Constant for a thin thick thin large border
+     */
+    public static final int BORDER_THIN_THICK_THIN_LARGE = 19;
+    /**
+     * Constant for a wavy border
+     */
+    public static final int BORDER_WAVY = 20;
+    /**
+     * Constant for a double wavy border
+     */
+    public static final int BORDER_DOUBLE_WAVY = 21;
+    /**
+     * Constant for a striped border
+     */
+    public static final int BORDER_STRIPED = 22;
+    /**
+     * Constant for an embossed border
+     */
+    public static final int BORDER_EMBOSS = 23;
+    /**
+     * Constant for an engraved border
+     */
+    public static final int BORDER_ENGRAVE = 24;
+    
+    /**
+     * The type of this RtfBorder
+     */
+    private int borderType = ROW_BORDER;
+    /**
+     * The position of this RtfBorder
+     */
+    private int borderPosition = NO_BORDER;
+    /**
+     * The style of this RtfBorder
+     */
+    private int borderStyle = BORDER_NONE;
+    /**
+     * The width of this RtfBorder
+     */
+    private int borderWidth = 20;
+    /**
+     * The color of this RtfBorder
+     */
+    private RtfColor borderColor = null;
+    
+    /**
+     * Makes a copy of the given RtfBorder
+     * 
+     * @param doc The RtfDocument this RtfBorder belongs to
+     * @param borderType The border type of this RtfBorder
+     * @param border The RtfBorder to copy
+     */
+    protected RtfBorder(RtfDocument doc, int borderType, RtfBorder border) {
+        super(doc);
+        this.borderType = borderType;
+        this.borderPosition = border.getBorderPosition();
+        this.borderStyle = border.getBorderStyle();
+        this.borderWidth = border.getBorderWidth();
+        this.borderColor = new RtfColor(this.document, border.getBorderColor());
+    }
+    
+    /**
+     * Constructs a RtfBorder
+     * 
+     * @param doc The RtfDocument this RtfBorder belongs to
+     * @param borderType The type of border this RtfBorder is
+     * @param borderPosition The position of this RtfBorder
+     * @param borderStyle The style of this RtfBorder
+     * @param borderWidth The width of this RtfBorder
+     * @param borderColor The color of this RtfBorder
+     */
+    protected RtfBorder(RtfDocument doc, int borderType, int borderPosition, int borderStyle, float borderWidth, Color borderColor) {
+        super(doc);
+        this.borderType = borderType;
+        this.borderPosition = borderPosition;
+        this.borderStyle = borderStyle;
+        this.borderWidth = (int) Math.min((borderWidth * TWIPS_FACTOR), 75);
+        if(this.borderWidth == 0) {
+            this.borderStyle = BORDER_NONE;
+        }
+        if(borderColor == null) {
+            this.borderColor = new RtfColor(this.document, new Color(0, 0, 0));
+        } else {
+            this.borderColor = new RtfColor(this.document, borderColor);
+        }
+    }
+    
+    /**
+     * Writes the RtfBorder settings
+     */
+    public void writeContent(final OutputStream result) throws IOException
+    {
+        if(this.borderStyle == BORDER_NONE || this.borderPosition == NO_BORDER || this.borderWidth == 0) {
+            return;
+        }
+
+    	if(this.borderType == ROW_BORDER) {
+            switch(this.borderPosition) {
+                case LEFT_BORDER:
+                    result.write(ROW_BORDER_LEFT);
+                	break;
+                case TOP_BORDER:
+                    result.write(ROW_BORDER_TOP);
+                    break;
+                case RIGHT_BORDER:
+                    result.write(ROW_BORDER_RIGHT);
+                    break;
+                case BOTTOM_BORDER:
+                    result.write(ROW_BORDER_BOTTOM);
+                    break;
+                case HORIZONTAL_BORDER:
+                    result.write(ROW_BORDER_HORIZONTAL);
+                    break;
+                case VERTICAL_BORDER:
+                    result.write(ROW_BORDER_VERTICAL);
+                    break;
+                default:
+                    return;
+            }
+            result.write(writeBorderStyle());
+            result.write(BORDER_WIDTH);
+            result.write(intToByteArray(this.borderWidth));
+            result.write(BORDER_COLOR_NUMBER);
+            result.write(intToByteArray(this.borderColor.getColorNumber()));
+            this.document.outputDebugLinebreak(result);
+        } else if(this.borderType == CELL_BORDER) {
+            switch(this.borderPosition) {
+                case LEFT_BORDER:
+                    result.write(CELL_BORDER_LEFT);
+                	break;
+                case TOP_BORDER:
+                    result.write(CELL_BORDER_TOP);
+                    break;
+                case RIGHT_BORDER:
+                    result.write(CELL_BORDER_RIGHT);
+                    break;
+                case BOTTOM_BORDER:
+                    result.write(CELL_BORDER_BOTTOM);
+                    break;
+                default:
+                    return;
+            }
+            result.write(writeBorderStyle());
+            result.write(BORDER_WIDTH);
+            result.write(intToByteArray(this.borderWidth));
+            result.write(BORDER_COLOR_NUMBER);
+            result.write(intToByteArray(this.borderColor.getColorNumber()));
+            this.document.outputDebugLinebreak(result);
+        }    	
+    }
+     
+    /**
+     * Writes the style of this RtfBorder
+     * 
+     * @return A byte array containing the style of this RtfBorder
+     */
+    private byte[] writeBorderStyle() {
+        switch(this.borderStyle) {
+            case BORDER_NONE                    : return new byte[0];
+            case BORDER_SINGLE 					: return BORDER_STYLE_SINGLE;
+            case BORDER_DOUBLE_THICK	 		: return BORDER_STYLE_DOUBLE_THICK;
+            case BORDER_SHADOWED 				: return BORDER_STYLE_SHADOWED;
+            case BORDER_DOTTED   				: return BORDER_STYLE_DOTTED;
+            case BORDER_DASHED   				: return BORDER_STYLE_DASHED;
+            case BORDER_HAIRLINE   				: return BORDER_STYLE_HAIRLINE;
+            case BORDER_DOUBLE 		  			: return BORDER_STYLE_DOUBLE;
+            case BORDER_DOT_DASH   				: return BORDER_STYLE_DOT_DASH;
+            case BORDER_DOT_DOT_DASH			: return BORDER_STYLE_DOT_DOT_DASH;
+            case BORDER_TRIPLE					: return BORDER_STYLE_TRIPLE;
+            case BORDER_THICK_THIN				: return BORDER_STYLE_THICK_THIN;
+            case BORDER_THIN_THICK				: return BORDER_STYLE_THIN_THICK;
+            case BORDER_THIN_THICK_THIN			: return BORDER_STYLE_THIN_THICK_THIN;
+            case BORDER_THICK_THIN_MED			: return BORDER_STYLE_THICK_THIN_MED;
+            case BORDER_THIN_THICK_MED			: return BORDER_STYLE_THIN_THICK_MED;
+            case BORDER_THIN_THICK_THIN_MED		: return BORDER_STYLE_THIN_THICK_THIN_MED;
+            case BORDER_THICK_THIN_LARGE		: return BORDER_STYLE_THICK_THIN_LARGE;
+            case BORDER_THIN_THICK_LARGE		: return BORDER_STYLE_THIN_THICK_LARGE;
+            case BORDER_THIN_THICK_THIN_LARGE	: return BORDER_STYLE_THIN_THICK_THIN_LARGE;
+            case BORDER_WAVY					: return BORDER_STYLE_WAVY;
+            case BORDER_DOUBLE_WAVY				: return BORDER_STYLE_DOUBLE_WAVY;
+            case BORDER_STRIPED					: return BORDER_STYLE_STRIPED;
+            case BORDER_EMBOSS					: return BORDER_STYLE_EMBOSS;
+            case BORDER_ENGRAVE					: return BORDER_STYLE_ENGRAVE;
+            default                             : return BORDER_STYLE_SINGLE;
+        }
+    }
+    
+    /**
+     * Gets the color of this RtfBorder
+     * 
+     * @return Returns RtfColor of this RtfBorder
+     */
+    protected RtfColor getBorderColor() {
+        return borderColor;
+    }
+
+    /**
+     * Gets the position of this RtfBorder
+     * @return Returns the position of this RtfBorder
+     */
+    protected int getBorderPosition() {
+        return borderPosition;
+    }
+
+    /**
+     * Gets the style of this RtfBorder
+     * 
+     * @return Returns the style of this RtfBorder
+     */
+    protected int getBorderStyle() {
+        return borderStyle;
+    }
+
+    /**
+     * Gets the type of this RtfBorder
+     * 
+     * @return Returns the type of this RtfBorder
+     */
+    protected int getBorderType() {
+        return borderType;
+    }
+
+    /**
+     * Gets the width of this RtfBorder
+     * 
+     * @return Returns the width of this RtfBorder
+     */
+    protected int getBorderWidth() {
+        return borderWidth;
+    }
+}
Index: src/core/com/lowagie/text/rtf/parser/properties/RtfCtrlWordPropertyType.java
===================================================================
--- src/core/com/lowagie/text/rtf/parser/properties/RtfCtrlWordPropertyType.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/parser/properties/RtfCtrlWordPropertyType.java	(revision 0)
@@ -0,0 +1,59 @@
+/* $Id: RtfCtrlWordPropertyType.java 3373 2008-05-12 16:21:24Z xlv $
+ *
+ * Copyright 2007 by Howard Shank (hgshank@yahoo.com)
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+package com.lowagie.text.rtf.parser.properties;
+
+/**
+ * @since 2.1.0
+ */
+public class RtfCtrlWordPropertyType {
+	public static final int UNIDENTIFIED = -1;
+	public static final int PROPERTY = 0;
+	public static final int CHARACTER = 1;
+	public static final int SPECIAL = 2;
+	public static final int DESTINATION = 3;
+}
Index: src/core/com/lowagie/text/rtf/parser/destinations/RtfDestinationListTable.java
===================================================================
--- src/core/com/lowagie/text/rtf/parser/destinations/RtfDestinationListTable.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/parser/destinations/RtfDestinationListTable.java	(revision 0)
@@ -0,0 +1,400 @@
+/*
+ * $Id: RtfDestinationListTable.java 3735 2009-02-26 01:44:03Z xlv $
+ *
+ * Copyright 2007 by Howard Shank (hgshank@yahoo.com)
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.rtf.parser.destinations;
+
+import com.lowagie.text.Element;
+import com.lowagie.text.rtf.list.RtfList;
+import com.lowagie.text.rtf.list.RtfListLevel;
+import com.lowagie.text.rtf.parser.RtfImportMgr;
+import com.lowagie.text.rtf.parser.RtfParser;
+import com.lowagie.text.rtf.parser.ctrlwords.RtfCtrlWordData;
+
+/**
+ * <code>RtfDestinationListTable</code> handles data destined for the List
+ * Table destination
+ * 
+ * @author Howard Shank (hgshank@yahoo.com)
+ * @since 2.1.0
+ */
+public class RtfDestinationListTable extends RtfDestination {
+	/**
+	 * The RtfImportHeader to add List mappings to.
+	 */
+	private RtfImportMgr importHeader = null;
+
+	private RtfList newList = null;
+	
+	private int currentLevel = -1;
+	private RtfListLevel currentListLevel = null;
+	private int currentListMappingNumber = 0;
+	private int currentSubGroupCount = 0;
+	
+	public RtfDestinationListTable() {
+		super(null);
+	}
+
+	public RtfDestinationListTable(RtfParser parser) {
+		super(parser);
+		this.importHeader = parser.getImportManager();
+	}
+
+	public void setParser(RtfParser parser) {
+		this.rtfParser = parser;
+		this.importHeader = parser.getImportManager();
+		this.setToDefaults();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see com.lowagie.text.rtf.parser.destinations.RtfDestination#handleOpenNewGroup()
+	 */
+	public boolean handleOpeningSubGroup() {
+		this.currentSubGroupCount++;
+		return true;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see com.lowagie.text.rtf.direct.RtfDestination#closeDestination()
+	 */
+	public boolean closeDestination() {
+//		RtfListTable t = this.rtfParser.getRtfDocument().getDocumentHeader().getListTable();
+//		List newlist = new List(List.UNORDERED, List.NUMERICAL, 0xb7);
+//		// newlist.set
+//		newList = new RtfList(this.rtfParser.getRtfDocument(), newlist);
+//		this.rtfParser.getRtfDocument().add(newList);
+//		//newList.set
+//		// mylist.
+//		// this.rtfParser.setTokeniserStateSkipGroup();
+
+//		// may have to create an import mapping for lists because
+		// there may be existing lists in the document with a duplicate ID.
+		if (this.newList != null) {
+			this.rtfParser.getRtfDocument().add(this.newList);
+		}
+		return true;
+	}
+
+	public boolean handleControlWord(RtfCtrlWordData ctrlWordData) {
+		boolean result = true;
+		boolean skipCtrlWord = false;
+
+		if (this.rtfParser.isImport()) {
+			skipCtrlWord = true;
+			if (ctrlWordData.ctrlWord.equals("listtable")) {
+				result = true;
+				this.currentListMappingNumber = 0;
+				
+			} else
+				/* Picture info for icons/images for lists */
+				if (ctrlWordData.ctrlWord.equals("listpicture"))/* DESTINATION */{
+					skipCtrlWord = true;
+					// this.rtfParser.setTokeniserStateSkipGroup();
+					result = true;
+				} else
+					/* list */
+					if (ctrlWordData.ctrlWord.equals("list")) /* DESTINATION */{
+						skipCtrlWord = true;
+						this.newList = new RtfList(this.rtfParser.getRtfDocument());
+						this.newList.setListType(RtfList.LIST_TYPE_NORMAL);	// set default
+						this.currentLevel = -1;
+						this.currentListMappingNumber++;
+						this.currentSubGroupCount = 0;
+						result = true;
+					} else if (ctrlWordData.ctrlWord.equals("listtemplateid")) /* // List item*/ {
+						// ignore this because it gets regenerated in every document
+						skipCtrlWord = true;
+						result = true;
+					} else if (ctrlWordData.ctrlWord.equals("listsimple")) /* // List item*/ {
+						// is value 0 or 1
+						if(ctrlWordData.hasParam && ctrlWordData.param == "1") {
+							this.newList.setListType(RtfList.LIST_TYPE_SIMPLE);
+						} else
+						{
+							this.newList.setListType(RtfList.LIST_TYPE_NORMAL);
+						}
+						skipCtrlWord = true;
+						result = true;
+						// this gets set internally. Don't think it should be imported
+					} else if (ctrlWordData.ctrlWord.equals("listhybrid")) /* // List item*/ {
+						this.newList.setListType(RtfList.LIST_TYPE_HYBRID);
+						skipCtrlWord = true;
+						result = true;
+						// this gets set internally. Don't think it should be imported
+					} else if (ctrlWordData.ctrlWord.equals("listrestarthdn")) /* // List item*/ {
+						skipCtrlWord = true;
+						result = true;
+					} else if (ctrlWordData.ctrlWord.equals("listid")) {	// List item cannot be between -1 and -5
+						// needs to be mapped for imports and is recreated
+						// we have the new id and the old id. Just add it to the mapping table here.
+						skipCtrlWord = true;
+						result = true;
+					} else if (ctrlWordData.ctrlWord.equals("listname"))/* // List item*/ {
+						this.newList.setName(ctrlWordData.param);
+						skipCtrlWord = true;
+						result = true;
+					} else if (ctrlWordData.ctrlWord.equals("liststyleid"))/* // List item*/ {
+						skipCtrlWord = true;
+						result = true;
+					} else if (ctrlWordData.ctrlWord.equals("liststylename"))/* // List item*/ {
+						skipCtrlWord = true;
+						result = true;
+					} else
+						/* listlevel */
+						if (ctrlWordData.ctrlWord.equals("listlevel")) /* DESTINATION There are 1 or 9 listlevels per list */{
+							this.currentLevel++;
+							this.currentListLevel = this.newList.getListLevel(this.currentLevel);
+							this.currentListLevel.setTentative(false);
+							skipCtrlWord = true;
+							result = true;
+						} else if (ctrlWordData.ctrlWord.equals("leveljc")) { // listlevel item justify
+							// this is the old number. Only use it if the current type is not set
+							if( this.currentListLevel.getAlignment()== RtfListLevel.LIST_TYPE_UNKNOWN) {
+								switch(ctrlWordData.intValue()) {
+								case 0:
+									this.currentListLevel.setAlignment(Element.ALIGN_LEFT);
+									break;
+								case 1:
+									this.currentListLevel.setAlignment(Element.ALIGN_CENTER);
+									break;
+								case 2:
+									this.currentListLevel.setAlignment(Element.ALIGN_RIGHT);
+									break;
+								}
+							}
+							skipCtrlWord = true;
+							result = true;
+						} else if (ctrlWordData.ctrlWord.equals("leveljcn")) { // listlevel item
+							//justify
+							// if this exists, use it and it overrides the old setting
+							switch(ctrlWordData.intValue()) {
+							case 0:
+								this.currentListLevel.setAlignment(Element.ALIGN_LEFT);
+								break;
+							case 1:
+								this.currentListLevel.setAlignment(Element.ALIGN_CENTER);
+								break;
+							case 2:
+								this.currentListLevel.setAlignment(Element.ALIGN_RIGHT);
+								break;
+							}
+							skipCtrlWord = true;
+							result = true;
+						} else if (ctrlWordData.ctrlWord.equals("levelstartat")) {
+							this.currentListLevel.setListStartAt(ctrlWordData.intValue());
+							skipCtrlWord = true;
+							result = true;
+						} else if (ctrlWordData.ctrlWord.equals("lvltentative")) {
+							this.currentListLevel.setTentative(true);
+							skipCtrlWord = true;
+							result = true;
+						} else if (ctrlWordData.ctrlWord.equals("levelold")) {
+							// old style. ignore
+							skipCtrlWord = true;
+							result = true;
+						} else if (ctrlWordData.ctrlWord.equals("levelprev")) {
+							// old style. ignore
+							skipCtrlWord = true;
+							result = true;
+						} else if (ctrlWordData.ctrlWord.equals("levelprevspace")) {
+							// old style. ignore
+							skipCtrlWord = true;
+							result = true;
+						} else if (ctrlWordData.ctrlWord.equals("levelspace")) {
+							skipCtrlWord = true;
+							result = true;
+						} else if (ctrlWordData.ctrlWord.equals("levelindent")) {
+							skipCtrlWord = true;
+							result = true;
+						} else if (ctrlWordData.ctrlWord.equals("leveltext")) {/* FIX */
+							skipCtrlWord = true;
+							result = true;
+						}  else if (ctrlWordData.ctrlWord.equals("levelfollow")) {
+							this.currentListLevel.setLevelFollowValue(ctrlWordData.intValue());
+							skipCtrlWord = true;
+							result = true;
+						} else if (ctrlWordData.ctrlWord.equals("levellegal")) {
+							this.currentListLevel.setLegal(ctrlWordData.param=="1"?true:false);
+							skipCtrlWord = true;
+							result = true;
+						} else if (ctrlWordData.ctrlWord.equals("levelnorestart")) {
+							skipCtrlWord = true;
+							result = true;
+						} else if (ctrlWordData.ctrlWord.equals("chrfmt")) {/* FIX */
+							// set an attribute pair
+							skipCtrlWord = true;
+							result = true;
+						} else if (ctrlWordData.ctrlWord.equals("levelpicture")) {
+							skipCtrlWord = true;
+							result = true;
+						} else if (ctrlWordData.ctrlWord.equals("li")) {
+							// set an attribute pair
+							skipCtrlWord = true;
+							result = true;
+						} else if (ctrlWordData.ctrlWord.equals("fi")) {
+							// set an attribute pair
+							skipCtrlWord = true;
+							result = true;
+						} else if (ctrlWordData.ctrlWord.equals("jclisttab")) {
+							// set an attribute pair
+							skipCtrlWord = true;
+							result = true;
+						} else if (ctrlWordData.ctrlWord.equals("tx")) {
+							// set an attribute pair
+							skipCtrlWord = true;
+							result = true;
+						} else
+							/* number */
+							if (ctrlWordData.ctrlWord.equals("levelnfc")) /* old style */ {
+								if( this.currentListLevel.getListType()== RtfListLevel.LIST_TYPE_UNKNOWN) {
+									this.currentListLevel.setListType(ctrlWordData.intValue()+RtfListLevel.LIST_TYPE_BASE);
+								}
+								skipCtrlWord = true;
+								result = true;
+							} else if (ctrlWordData.ctrlWord.equals("levelnfcn")) /* new style takes priority over levelnfc.*/ {
+								this.currentListLevel.setListType(ctrlWordData.intValue()+RtfListLevel.LIST_TYPE_BASE);
+								skipCtrlWord = true;
+								result = true;
+							} else
+									/* level text */
+									if (ctrlWordData.ctrlWord.equals("leveltemplateid")) {
+										// ignore. this value is regenerated in each document.
+										skipCtrlWord = true;
+										result = true;
+									} else
+										/* levelnumber */
+										if (ctrlWordData.ctrlWord.equals("levelnumbers")) {
+											skipCtrlWord = true;
+											result = true;
+										}
+		}
+
+		if (this.rtfParser.isConvert()) {
+			if (ctrlWordData.ctrlWord.equals("shppict")) {
+				result = true;
+			}
+			if (ctrlWordData.ctrlWord.equals("nonshppict")) {
+				skipCtrlWord = true;
+				this.rtfParser.setTokeniserStateSkipGroup();
+				result = true;
+			}
+		}
+		if (!skipCtrlWord) {
+			switch (this.rtfParser.getConversionType()) {
+			case RtfParser.TYPE_IMPORT_FULL:
+				// writeBuffer();
+				// writeText(ctrlWordData.toString());
+				result = true;
+				break;
+			case RtfParser.TYPE_IMPORT_FRAGMENT:
+				// writeBuffer();
+				// writeText(ctrlWordData.toString());
+				result = true;
+				break;
+			case RtfParser.TYPE_CONVERT:
+				result = true;
+				break;
+			default: // error because is should be an import or convert
+				result = false;
+			break;
+			}
+		}
+
+		return result;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see com.lowagie.text.rtf.direct.RtfDestination#handleGroupEnd()
+	 */
+	public boolean handleCloseGroup() {
+		this.currentSubGroupCount--;
+		if(this.newList != null && this.currentSubGroupCount == 0) {
+			this.importHeader.importList(Integer.toString(this.currentListMappingNumber), 
+					Integer.toString(this.newList.getListNumber()));
+			this.rtfParser.getRtfDocument().add(this.newList);
+		}
+		return true;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see com.lowagie.text.rtf.direct.RtfDestination#handleGroupStart()
+	 */
+	public boolean handleOpenGroup() {
+		// TODO Auto-generated method stub
+		return true;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see com.lowagie.text.rtf.direct.RtfDestination#handleCharacter(int)
+	 */
+	public boolean handleCharacter(int ch) {
+		// TODO Auto-generated method stub
+		return true;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see com.lowagie.text.rtf.parser.destinations.RtfDestination#setToDefaults()
+	 */
+	public void setToDefaults() {
+		// TODO Auto-generated method stub
+
+	}
+
+}
Index: src/core/com/lowagie/text/rtf/field/RtfAnchor.java
===================================================================
--- src/core/com/lowagie/text/rtf/field/RtfAnchor.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/field/RtfAnchor.java	(revision 0)
@@ -0,0 +1,123 @@
+/*
+ * $Id: RtfAnchor.java 3580 2008-08-06 15:52:00Z howard_s $
+ *
+ * Copyright 2004 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.rtf.field;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import com.lowagie.text.Anchor;
+import com.lowagie.text.DocWriter;
+import com.lowagie.text.rtf.document.RtfDocument;
+import com.lowagie.text.rtf.text.RtfPhrase;
+
+
+/**
+ * The RtfAnchor is the RTF representation of an Anchor object.
+ * 
+ * @version $Id: RtfAnchor.java 3580 2008-08-06 15:52:00Z howard_s $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Werner Daehn (Werner.Daehn@BusinessObjects.com)
+ * @author Thomas Bickel (tmb99@inode.at)
+ */
+public class RtfAnchor extends RtfField 
+{
+    /**
+     * Constant for a hyperlink
+     */
+    private static final byte[] HYPERLINK = DocWriter.getISOBytes("HYPERLINK");
+    
+    /**
+     * The url of this RtfAnchor
+     */
+    private String url = "";
+    /**
+     * The RtfPhrase to display for the url
+     */
+    private RtfPhrase content = null;
+
+    /**
+     * Constructs a RtfAnchor based on a RtfField
+     * 
+     * @param doc The RtfDocument this RtfAnchor belongs to
+     * @param anchor The Anchor this RtfAnchor is based on
+     */
+    public RtfAnchor(RtfDocument doc, Anchor anchor) {
+        super(doc);
+        this.url = anchor.getReference();
+        this.content = new RtfPhrase(doc, anchor);
+    }
+    
+    /**
+     * Write the field instructions for this RtfAnchor. Sets the field
+     * type to HYPERLINK and then writes the url.
+     *
+     * @param result The <code>OutputStream</code> to write to.
+     * @throws IOException on i/o errors.
+     */
+    protected void writeFieldInstContent(OutputStream result) throws IOException 
+    {
+        result.write(HYPERLINK);
+        result.write(DELIMITER);
+        this.document.filterSpecialChar(result, url, true, true);
+    }
+    
+    /**
+     * Write the field result for this RtfAnchor. Writes the content
+     * of the RtfPhrase.
+     * 
+     * @param result The <code>OutputStream</code> to write to.
+     * @throws IOException on i/o errors.
+     */
+    protected void writeFieldResultContent(OutputStream result) throws IOException 
+    {
+        content.writeContent(result);
+    }
+    
+}
Index: src/core/com/lowagie/text/xml/XmlToPdf.java
===================================================================
--- src/core/com/lowagie/text/xml/XmlToPdf.java	(revision 0)
+++ src/core/com/lowagie/text/xml/XmlToPdf.java	(revision 0)
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2002 by Matt Benson.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.xml;
+
+
+import java.io.OutputStream;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+
+import com.lowagie.text.Document;
+import com.lowagie.text.DocumentException;
+import com.lowagie.text.pdf.PdfWriter;
+
+
+/**
+ * PDF-specific subclass of <code>XmlToXXX</code>.
+ *
+ * @version 1.0
+ * @author <a href="mailto:orangeherbert@users.sourceforge.net">Matt Benson</a>
+ */
+public class XmlToPdf
+ extends XmlToXXX
+{
+	
+/**
+ * Construct an <CODE>XmlToPdf</CODE> with the default page size.
+ */
+	public XmlToPdf()
+	{
+		super();
+	}//end default constructor
+	
+	
+/**
+ * Construct an <CODE>XmlToPdf</CODE> with the specified page size.
+ * @param pageSize   <CODE>String</CODE> page size name from
+ * <CODE>com.lowagie.text.PageSize</CODE>.
+ */
+	public XmlToPdf(String pageSize)
+	{
+		super(pageSize);
+	}//end constructor(String)
+	
+	
+/**
+ * Add a <CODE>DocWriter</CODE> for the specified <CODE>Document</CODE> and
+ * <CODE>OutputStream</CODE>.
+ * @param doc The document to which content will be added
+ * @param out The outputstream to which the PDF will be sent
+ * @throws DocumentException if document errors occur.
+ */	
+	protected final void addWriter(Document doc, OutputStream out)
+	 throws DocumentException
+	{
+		PdfWriter.getInstance(doc, out);
+	}//end addWriter
+	
+	
+/**
+ * Main method of the <CODE>XmlToPdf</CODE> class.
+ * @param args   <CODE>String[]</CODE> of command-line arguments.
+ */
+	public static void main(String[] args)
+	{
+		int code = 0;
+		
+		if (args.length > 1)
+		{
+			try
+			{
+				XmlToPdf x;
+				if (args.length > 2)
+				{
+					x = new XmlToPdf(args[2]);
+				}//end if at least 3 args
+				else
+				{
+					x = new XmlToPdf();
+				}//end else, only 2 args
+				
+				x.parse(new FileInputStream(args[0]), new FileOutputStream(args[1]));
+			}//end try to do everything
+			catch (Exception ex)
+			{
+				code = 2;
+				ex.printStackTrace(System.err);
+			}//end catch Exception
+		}//end if at least 2 args
+		else
+		{
+			code = 1;
+			System.err.println(
+			 "Usage:  XmlToPdf [XML file in] [PDF file out] [optional page size]");
+		}//end else, not enough arguments
+		
+		System.exit(code);
+	}//end main
+	
+}//end class XmlToPdf
Index: src/core/com/lowagie/text/rtf/RtfAddableElement.java
===================================================================
--- src/core/com/lowagie/text/rtf/RtfAddableElement.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/RtfAddableElement.java	(revision 0)
@@ -0,0 +1,138 @@
+/*
+ * $Id:RtfAddableElement.java 3126 2008-02-07 20:30:46Z hallm $
+ *
+ * Copyright 2001, 2002, 2003, 2004 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ * Co-Developer of the code is Mark Hall. Portions created by the Co-Developer are
+ * Copyright (C) 2006 by Mark Hall. All Rights Reserved
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.rtf;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import com.lowagie.text.Chunk;
+import com.lowagie.text.DocWriter;
+import com.lowagie.text.Font;
+import com.lowagie.text.rtf.document.RtfDocument;
+
+/**
+ * The RtfAddableElement is the superclass for all rtf specific elements
+ * that need to be added to an iText document. It is an extension of Chunk
+ * and it also implements RtfBasicElement. It is an abstract class thus it
+ * cannot be instantiated itself and has to be subclassed to be used.
+ * 
+ * @version $Id:RtfAddableElement.java 3126 2008-02-07 20:30:46Z hallm $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Thomas Bickel (tmb99@inode.at)
+ */
+public abstract class RtfAddableElement extends Chunk implements RtfBasicElement {
+
+	/**
+	 * The RtfDocument this RtfAddableElement belongs to.
+	 */
+	protected RtfDocument doc = null;
+	/**
+	 * Whether this RtfAddableElement is contained in a table.
+	 */
+	protected boolean inTable = false;
+	/**
+	 * Whether this RtfAddableElement is contained in a header.
+	 */
+	protected boolean inHeader = false;
+	
+	/**
+	 * Constructs a new RtfAddableElement. The Chunk content is
+	 * set to an empty string and the font to the default Font().
+	 */
+	public RtfAddableElement() {
+		super("", new Font());
+	}
+
+	/**
+     * Writes the element content to the given output stream.
+	 */
+    public abstract void writeContent(OutputStream out) throws IOException;
+	
+	/**
+	 * Sets the RtfDocument this RtfAddableElement belongs to.
+	 */
+	public void setRtfDocument(RtfDocument doc) {
+		this.doc = doc;
+	}
+
+	/**
+	 * Sets whether this RtfAddableElement is contained in a table.
+	 */
+	public void setInTable(boolean inTable) {
+		this.inTable = inTable;
+	}
+
+	/**
+	 * Sets whether this RtfAddableElement is contained in a header/footer.
+	 */
+	public void setInHeader(boolean inHeader) {
+		this.inHeader = inHeader;
+	}
+
+    /**
+     * Transforms an integer into its String representation and then returns the bytes
+     * of that string.
+     *
+     * @param i The integer to convert
+     * @return A byte array representing the integer
+     */
+    public byte[] intToByteArray(int i) {
+        return DocWriter.getISOBytes(Integer.toString(i));
+    }
+    
+    /**
+     *  RtfAddableElement subclasses are never assumed to be empty.
+     */
+    public boolean isEmpty() {
+        return false;
+    }
+}
Index: src/core/com/lowagie/text/rtf/field/RtfTOCEntry.java
===================================================================
--- src/core/com/lowagie/text/rtf/field/RtfTOCEntry.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/field/RtfTOCEntry.java	(revision 0)
@@ -0,0 +1,155 @@
+/*
+ * $Id: RtfTOCEntry.java 3580 2008-08-06 15:52:00Z howard_s $
+ *
+ * Copyright 2004 by Mark Hall
+ * Uses code Copyright 2002
+ *   Steffen.Stundzig (Steffen.Stundzig@smb-tec.com) 
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.rtf.field;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import com.lowagie.text.DocWriter;
+import com.lowagie.text.Font;
+
+
+/**
+ * The RtfTOCEntry is used together with the RtfTableOfContents to generate a table of
+ * contents. Add the RtfTOCEntry in those locations in the document where table of
+ * contents entries should link to 
+ * 
+ * @version $Id: RtfTOCEntry.java 3580 2008-08-06 15:52:00Z howard_s $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Steffen.Stundzig (Steffen.Stundzig@smb-tec.com) 
+ * @author Thomas Bickel (tmb99@inode.at)
+ */
+public class RtfTOCEntry extends RtfField {
+
+    /**
+     * Constant for the beginning of hidden text
+     */
+    private static final byte[] TEXT_HIDDEN_ON = DocWriter.getISOBytes("\\v");
+    /**
+     * Constant for the end of hidden text
+     */
+    private static final byte[] TEXT_HIDDEN_OFF = DocWriter.getISOBytes("\\v0");
+    /**
+     * Constant for a TOC entry with page numbers
+     */
+    private static final byte[] TOC_ENTRY_PAGE_NUMBER = DocWriter.getISOBytes("\\tc");
+    /**
+     * Constant for a TOC entry without page numbers
+     */
+    private static final byte[] TOC_ENTRY_NO_PAGE_NUMBER = DocWriter.getISOBytes("\\tcn");
+    
+    /**
+     * The entry text of this RtfTOCEntry
+     */
+    private String entry = "";
+    /**
+     * Whether to show page numbers in the table of contents
+     */
+    private boolean showPageNumber = true;
+    
+    /**
+     * Constructs a RtfTOCEntry with a certain entry text.
+     * 
+     * @param entry The entry text to display
+     */
+    public RtfTOCEntry(String entry) {
+        super(null, new Font());
+        if(entry != null) {
+            this.entry = entry;
+        }
+    }
+    
+    /**
+     * Writes the content of the <code>RtfTOCEntry</code>.
+     * 
+     * @param result The <code>OutputStream</code> to write to.
+     * @throws IOException on i/o errors.
+     */ 
+    public void writeContent(final OutputStream result) throws IOException
+    {    	
+        result.write(TEXT_HIDDEN_ON);
+        result.write(OPEN_GROUP);
+        if(this.showPageNumber) {
+            result.write(TOC_ENTRY_PAGE_NUMBER);
+        } else {
+            result.write(TOC_ENTRY_NO_PAGE_NUMBER);
+        }
+        result.write(DELIMITER);
+        this.document.filterSpecialChar(result, this.entry, true, false);
+        result.write(CLOSE_GROUP);
+        result.write(TEXT_HIDDEN_OFF);
+    }
+    
+    /**
+     * Sets whether to display a page number in the table of contents, or not
+     * 
+     * @param showPageNumber Whether to display a page number or not
+     */
+    public void setShowPageNumber(boolean showPageNumber) {
+        this.showPageNumber = showPageNumber;
+    }
+    
+    /**
+     * unused
+     */
+    protected void writeFieldInstContent(OutputStream out) throws IOException 
+    {
+    }
+
+    /**
+     * unused
+     */
+    protected void writeFieldResultContent(OutputStream out) throws IOException
+    {
+    }
+
+}
Index: src/core/com/lowagie/text/rtf/text/RtfParagraph.java
===================================================================
--- src/core/com/lowagie/text/rtf/text/RtfParagraph.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/text/RtfParagraph.java	(revision 0)
@@ -0,0 +1,208 @@
+/*
+ * $Id: RtfParagraph.java 3670 2009-02-01 09:13:48Z blowagie $
+ *
+ * Copyright 2001, 2002, 2003, 2004 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.rtf.text;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import com.lowagie.text.Chunk;
+import com.lowagie.text.DocWriter;
+import com.lowagie.text.DocumentException;
+import com.lowagie.text.Element;
+import com.lowagie.text.Paragraph;
+import com.lowagie.text.rtf.RtfBasicElement;
+import com.lowagie.text.rtf.RtfElement;
+import com.lowagie.text.rtf.document.RtfDocument;
+import com.lowagie.text.rtf.graphic.RtfImage;
+import com.lowagie.text.rtf.style.RtfFont;
+import com.lowagie.text.rtf.style.RtfParagraphStyle;
+
+
+/**
+ * The RtfParagraph is an extension of the RtfPhrase that adds alignment and
+ * indentation properties. It wraps a Paragraph.
+ * 
+ * @version $Id: RtfParagraph.java 3670 2009-02-01 09:13:48Z blowagie $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Thomas Bickel (tmb99@inode.at)
+ */
+public class RtfParagraph extends RtfPhrase {
+
+    /**
+     * Constant for the end of a paragraph
+     */
+    public static final byte[] PARAGRAPH = DocWriter.getISOBytes("\\par");
+    
+    /**
+     * An optional RtfParagraphStyle to use for styling.
+     */
+    protected RtfParagraphStyle paragraphStyle = null;
+    
+    /**
+     * Constructs a RtfParagraph belonging to a RtfDocument based on a Paragraph.
+     * 
+     * @param doc The RtfDocument this RtfParagraph belongs to
+     * @param paragraph The Paragraph that this RtfParagraph is based on
+     */
+    public RtfParagraph(RtfDocument doc, Paragraph paragraph) {
+        super(doc);
+        RtfFont baseFont = null;
+        if(paragraph.getFont() instanceof RtfParagraphStyle) {
+            this.paragraphStyle = this.document.getDocumentHeader().getRtfParagraphStyle(((RtfParagraphStyle) paragraph.getFont()).getStyleName());
+            baseFont = this.paragraphStyle;
+        } else {
+            baseFont = new RtfFont(this.document, paragraph.getFont());
+            this.paragraphStyle = new RtfParagraphStyle(this.document, this.document.getDocumentHeader().getRtfParagraphStyle("Normal"));
+            this.paragraphStyle.setAlignment(paragraph.getAlignment());
+            this.paragraphStyle.setFirstLineIndent((int) (paragraph.getFirstLineIndent() * RtfElement.TWIPS_FACTOR));
+            this.paragraphStyle.setIndentLeft((int) (paragraph.getIndentationLeft() * RtfElement.TWIPS_FACTOR));
+            this.paragraphStyle.setIndentRight((int) (paragraph.getIndentationRight() * RtfElement.TWIPS_FACTOR));
+            this.paragraphStyle.setSpacingBefore((int) (paragraph.getSpacingBefore() * RtfElement.TWIPS_FACTOR));
+            this.paragraphStyle.setSpacingAfter((int) (paragraph.getSpacingAfter() * RtfElement.TWIPS_FACTOR));
+            if(paragraph.hasLeading()) {
+                this.paragraphStyle.setLineLeading((int) (paragraph.getLeading() * RtfElement.TWIPS_FACTOR));
+            }
+            this.paragraphStyle.setKeepTogether(paragraph.getKeepTogether());
+        }        
+        for(int i = 0; i < paragraph.size(); i++) {
+            Element chunk = (Element) paragraph.get(i);
+            if(chunk instanceof Chunk) {
+                ((Chunk) chunk).setFont(baseFont.difference(((Chunk) chunk).getFont()));
+            } else if(chunk instanceof RtfImage) {
+                ((RtfImage) chunks.get(i)).setAlignment(this.paragraphStyle.getAlignment());
+            }
+            try {
+                RtfBasicElement[] rtfElements = doc.getMapper().mapElement(chunk);
+                for(int j = 0; j < rtfElements.length; j++) {
+                    chunks.add(rtfElements[j]);
+                }
+            } catch(DocumentException de) {
+            }
+        }
+    }
+    
+    /**
+     * Set whether this RtfParagraph must stay on the same page as the next one.
+     *  
+     * @param keepTogetherWithNext Whether this RtfParagraph must keep together with the next.
+     */
+    public void setKeepTogetherWithNext(boolean keepTogetherWithNext) {
+        this.paragraphStyle.setKeepTogetherWithNext(keepTogetherWithNext);
+    }
+    
+    /**
+     * Writes the content of this RtfParagraph. First paragraph specific data is written
+     * and then the RtfChunks of this RtfParagraph are added.
+     */    
+    public void writeContent(final OutputStream result) throws IOException
+    {
+        result.write(PARAGRAPH_DEFAULTS);
+        result.write(PLAIN);
+
+        if(inTable) {
+            result.write(IN_TABLE);
+        }
+        
+        if(this.paragraphStyle != null) {
+            this.paragraphStyle.writeBegin(result);
+        }
+        result.write(DocWriter.getISOBytes("\\plain"));
+        
+        for(int i = 0; i < chunks.size(); i++) {
+        	RtfBasicElement rbe = (RtfBasicElement)chunks.get(i);
+        	rbe.writeContent(result);
+        }
+        
+        if(this.paragraphStyle != null) {
+            this.paragraphStyle.writeEnd(result);
+        }
+        
+        if(!inTable) {
+            result.write(PARAGRAPH);
+        }
+        this.document.outputDebugLinebreak(result);
+    }        
+    
+    /**
+     * Gets the left indentation of this RtfParagraph.
+     * 
+     * @return The left indentation.
+     */
+    public int getIndentLeft() {
+        return this.paragraphStyle.getIndentLeft();
+    }
+    
+    /**
+     * Sets the left indentation of this RtfParagraph.
+     * 
+     * @param indentLeft The left indentation to use.
+     */
+    public void setIndentLeft(int indentLeft) {
+        this.paragraphStyle.setIndentLeft(indentLeft);
+    }
+    
+    /**
+     * Gets the right indentation of this RtfParagraph.
+     * 
+     * @return The right indentation.
+     */
+    public int getIndentRight()  {
+        return this.paragraphStyle.getIndentRight();
+    }
+    
+    /**
+     * Sets the right indentation of this RtfParagraph.
+     * 
+     * @param indentRight The right indentation to use.
+     */
+    public void setIndentRight(int indentRight) {
+        this.paragraphStyle.setIndentRight(indentRight);
+    }
+}
Index: src/core/com/lowagie/text/xml/XmlToRtf.java
===================================================================
--- src/core/com/lowagie/text/xml/XmlToRtf.java	(revision 0)
+++ src/core/com/lowagie/text/xml/XmlToRtf.java	(revision 0)
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2002 by Matt Benson.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.xml;
+
+
+import java.io.OutputStream;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+
+import com.lowagie.text.Document;
+import com.lowagie.text.DocumentException;
+import com.lowagie.text.rtf.RtfWriter2;
+
+
+/**
+ * RTF-specific subclass of <code>XmlToXXX</code>.
+ *
+ * @version 1.0
+ * @author <a href="mailto:orangeherbert@users.sourceforge.net">Matt Benson</a>
+ */
+public class XmlToRtf
+ extends XmlToXXX
+{
+
+/**
+ * Construct an <CODE>XmlToRtf</CODE> with the default page size.
+ */
+	public XmlToRtf()
+	{
+		super();
+	}//end default constructor
+
+
+/**
+ * Construct an <CODE>XmlToRtf</CODE> with the specified page size.
+ * @param pageSize   <CODE>String</CODE> page size name from
+ * <CODE>com.lowagie.text.PageSize</CODE>.
+ */
+	public XmlToRtf(String pageSize)
+	{
+		super(pageSize);
+	}//end constructor(String)
+
+
+/**
+ * Add a <CODE>DocWriter</CODE> for the specified <CODE>Document</CODE> and
+ * <CODE>OutputStream</CODE>.
+ * @param doc The document to which content will be added
+ * @param out The outputstream to which RTF will be sent
+ * @throws DocumentException if document errors occur.
+ */
+	protected final void addWriter(Document doc, OutputStream out)
+	 throws DocumentException
+	{
+		RtfWriter2.getInstance(doc, out);
+	}//end addWriter
+
+
+/**
+ * Main method of the <CODE>XmlToRtf</CODE> class.
+ * @param args   <CODE>String[]</CODE> of command-line arguments.
+ */
+	public static void main(String[] args)
+	{
+		int code = 0;
+
+		if (args.length > 1)
+		{
+			try
+			{
+				XmlToRtf x;
+				if (args.length > 2)
+				{
+					x = new XmlToRtf(args[2]);
+				}//end if at least 3 args
+				else
+				{
+					x = new XmlToRtf();
+				}//end else, only 2 args
+
+				x.parse(new FileInputStream(args[0]), new FileOutputStream(args[1]));
+			}//end try to do everything
+			catch (Exception ex)
+			{
+				code = 2;
+				ex.printStackTrace(System.err);
+			}//end catch Exception
+		}//end if at least 2 args
+		else
+		{
+			code = 1;
+			System.err.println(
+			 "Usage:  XmlToRtf [XML file in] [PDF file out] [optional page size]");
+		}//end else, not enough arguments
+
+		System.exit(code);
+	}//end main
+
+}//end class XmlToRtf
Index: src/core/com/lowagie/text/rtf/list/RtfList.java
===================================================================
--- src/core/com/lowagie/text/rtf/list/RtfList.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/list/RtfList.java	(revision 0)
@@ -0,0 +1,705 @@
+/*
+ * $Id: RtfList.java 4006 2009-07-07 08:34:10Z blowagie $
+ *
+ * Copyright 2008 Howard Shank (hgshank@yahoo.com)
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.rtf.list;
+
+import java.awt.Color;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.security.InvalidParameterException;
+import java.util.ArrayList;
+
+import com.lowagie.text.Chunk;
+import com.lowagie.text.DocWriter;
+import com.lowagie.text.DocumentException;
+import com.lowagie.text.Element;
+import com.lowagie.text.Font;
+import com.lowagie.text.List;
+import com.lowagie.text.ListItem;
+import com.lowagie.text.RomanList;
+import com.lowagie.text.factories.RomanAlphabetFactory;
+import com.lowagie.text.factories.RomanNumberFactory;
+import com.lowagie.text.rtf.RtfBasicElement;
+import com.lowagie.text.rtf.RtfElement;
+import com.lowagie.text.rtf.RtfExtendedElement;
+import com.lowagie.text.rtf.document.RtfDocument;
+import com.lowagie.text.rtf.style.RtfFont;
+import com.lowagie.text.rtf.style.RtfFontList;
+import com.lowagie.text.rtf.text.RtfParagraph;
+
+
+/**
+ * The RtfList stores one List. It also provides the methods to write the
+ * list declaration and the list data.
+ *  
+ * @version $Id: RtfList.java 4006 2009-07-07 08:34:10Z blowagie $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Howard Shank (hgshank@yahoo.com)
+ * @since 2.1.3
+ */
+public class RtfList extends RtfElement implements RtfExtendedElement {
+
+
+    /**
+     * Constant for the list number
+     * @since 2.1.3
+     */
+    public static final byte[] LIST_NUMBER = DocWriter.getISOBytes("\\ls");
+
+    /**
+     * Constant for the list
+     */
+    private static final byte[] LIST = DocWriter.getISOBytes("\\list");
+    /**
+     * Constant for the list id
+     * @since 2.1.3
+     */
+    public static final byte[] LIST_ID = DocWriter.getISOBytes("\\listid");
+    /**
+     * Constant for the list template id
+     */
+    private static final byte[] LIST_TEMPLATE_ID = DocWriter.getISOBytes("\\listtemplateid");
+    /**
+     * Constant for the simple list
+     */
+    private static final byte[] LIST_SIMPLE = DocWriter.getISOBytes("\\listsimple");
+    /**
+     * Constant for the hybrid list
+     */
+    private static final byte[] LIST_HYBRID = DocWriter.getISOBytes("\\listhybrid");
+    /**
+     * Constant to indicate if the list restarts at each section. Word 7 compatiblity
+     */
+    private static final byte[] LIST_RESTARTHDN = DocWriter.getISOBytes("\\listrestarthdn");
+    /**
+     * Constant for the name of this list
+     */
+    private static final byte[] LIST_NAME = DocWriter.getISOBytes("\\listname");
+    /**
+     * Constant for the identifier of the style of this list. Mutually exclusive with \\liststylename
+     */
+    private static final byte[] LIST_STYLEID = DocWriter.getISOBytes("\\liststyleid");
+    /**
+     * Constant for the identifier of the style of this list. Mutually exclusive with \\liststyleid
+     */
+    private static final byte[] LIST_STYLENAME = DocWriter.getISOBytes("\\liststylename");
+
+    // character properties
+    /**
+     * Constant for the list level value
+     * @since 2.1.3
+     */
+    public static final byte[] LIST_LEVEL_NUMBER = DocWriter.getISOBytes("\\ilvl");
+    
+    
+	/**
+     * Constant for the old list text
+     * @since 2.1.3
+     */
+    public static final byte[] LIST_TEXT = DocWriter.getISOBytes("\\listtext");
+    /**
+     * Constant for the old list number end
+     * @since 2.1.3
+     */
+    public static final byte[] LIST_NUMBER_END = DocWriter.getISOBytes(".");
+    
+    
+
+    /**
+     * Constant for a tab character
+     * @since 2.1.3
+     */
+    public static final byte[] TAB = DocWriter.getISOBytes("\\tab");
+    
+    /**
+     * The subitems of this RtfList
+     */
+    private ArrayList items;
+    
+    /**
+     * The parent list if there is one.
+     */
+    private RtfList parentList = null;
+
+    /**
+     * The list id
+     */
+    private int listID = -1;
+    
+    /**
+     * List type of NORMAL - no control word
+     * @since 2.1.3
+     */
+    public static final int LIST_TYPE_NORMAL = 0;				/*  Normal list type */
+    
+    /**
+     * List type of listsimple
+     * @since 2.1.3
+     */
+    public static final int LIST_TYPE_SIMPLE = 1;				/*  Simple list type */
+    
+    /**
+     * List type of listhybrid
+     * @since 2.1.3
+     */
+    public static final int LIST_TYPE_HYBRID = 2;				/*  Hybrid list type */
+    
+    /**
+     * This RtfList type
+     */
+    private int listType = LIST_TYPE_HYBRID;
+    
+    /**
+     * The name of the list if it exists 
+     */
+    private String name = null;
+    
+    /**
+     * The list number of this RtfList
+     */
+    private int listNumber = -1;
+
+    /**
+     * The RtfList lists managed by this RtfListTable
+     */
+    private ArrayList listLevels = null;;
+
+    
+    /**
+     * Constructs an empty RtfList object.
+     * @since 2.1.3
+     */
+    public RtfList() {
+    	super(null);
+        createDefaultLevels();
+    }
+    
+    /**
+     * Set the document.
+     * @param doc The RtfDocument
+     * @since 2.1.3
+     */
+    public void setDocument(RtfDocument doc) {
+    	this.document = doc;
+        // get the list number or create a new one adding it to the table
+        this.listNumber = document.getDocumentHeader().getListNumber(this); 
+
+    	
+    }
+    /**
+     * Constructs an empty RtfList object.
+     * @param doc The RtfDocument this RtfList belongs to
+     * @since 2.1.3
+     */
+    public RtfList(RtfDocument doc) {
+        super(doc);
+        createDefaultLevels();
+        // get the list number or create a new one adding it to the table
+        this.listNumber = document.getDocumentHeader().getListNumber(this); 
+
+    }
+
+    
+    /**
+     * Constructs a new RtfList for the specified List.
+     * 
+     * @param doc The RtfDocument this RtfList belongs to
+     * @param list The List this RtfList is based on
+     * @since 2.1.3
+     */
+    public RtfList(RtfDocument doc, List list) {
+        // setup the listlevels
+        // Then, setup the list data below
+        
+        // setup 1 listlevel if it's a simple list
+        // setup 9 if it's a regular list
+        // setup 9 if it's a hybrid list (default)
+        super(doc);
+
+        createDefaultLevels();
+        
+        this.items = new ArrayList();		// list content
+        RtfListLevel ll = (RtfListLevel)this.listLevels.get(0);
+        
+        // get the list number or create a new one adding it to the table
+        this.listNumber = document.getDocumentHeader().getListNumber(this); 
+        
+        if(list.getSymbolIndent() > 0 && list.getIndentationLeft() > 0) {
+            ll.setFirstIndent((int) (list.getSymbolIndent() * RtfElement.TWIPS_FACTOR * -1));
+            ll.setLeftIndent((int) ((list.getIndentationLeft() + list.getSymbolIndent()) * RtfElement.TWIPS_FACTOR));
+        } else if(list.getSymbolIndent() > 0) {
+        	ll.setFirstIndent((int) (list.getSymbolIndent() * RtfElement.TWIPS_FACTOR * -1));
+        	ll.setLeftIndent((int) (list.getSymbolIndent() * RtfElement.TWIPS_FACTOR));
+        } else if(list.getIndentationLeft() > 0) {
+        	ll.setFirstIndent(0);
+        	ll.setLeftIndent((int) (list.getIndentationLeft() * RtfElement.TWIPS_FACTOR));
+        } else {
+        	ll.setFirstIndent(0);
+        	ll.setLeftIndent(0);
+        }
+        ll.setRightIndent((int) (list.getIndentationRight() * RtfElement.TWIPS_FACTOR));
+        ll.setSymbolIndent((int) ((list.getSymbolIndent() + list.getIndentationLeft()) * RtfElement.TWIPS_FACTOR));
+        ll.correctIndentation();
+        ll.setTentative(false);
+        
+        if (list instanceof RomanList) {
+			if (list.isLowercase()) {
+				ll.setListType(RtfListLevel.LIST_TYPE_LOWER_ROMAN);
+			} else {
+				ll.setListType(RtfListLevel.LIST_TYPE_UPPER_ROMAN);
+			}
+		} else if (list.isNumbered()) {
+			ll.setListType(RtfListLevel.LIST_TYPE_NUMBERED);
+		} else if (list.isLettered()) {
+			if (list.isLowercase()) {
+				ll.setListType(RtfListLevel.LIST_TYPE_LOWER_LETTERS);
+			} else {
+				ll.setListType(RtfListLevel.LIST_TYPE_UPPER_LETTERS);
+			}
+		} 
+		else {
+//			Paragraph p = new Paragraph();
+//			p.add(new Chunk(list.getPreSymbol()) );
+//			p.add(list.getSymbol());
+//			p.add(new Chunk(list.getPostSymbol()) );
+//			ll.setBulletChunk(list.getSymbol());
+			ll.setBulletCharacter(list.getPreSymbol() + list.getSymbol().getContent() + list.getPostSymbol());
+			ll.setListType(RtfListLevel.LIST_TYPE_BULLET);
+		}
+        
+        // now setup the actual list contents.
+        for(int i = 0; i < list.getItems().size(); i++) {
+            try {
+                Element element = (Element) list.getItems().get(i);
+                
+                if(element.type() == Element.CHUNK) {
+                    element = new ListItem((Chunk) element);
+                }
+                if(element instanceof ListItem) {
+                    ll.setAlignment(((ListItem) element).getAlignment());
+                }
+                RtfBasicElement[] rtfElements = doc.getMapper().mapElement(element);
+                for(int j = 0; j < rtfElements.length; j++) {
+                    RtfBasicElement rtfElement = rtfElements[j];
+                    if(rtfElement instanceof RtfList) {
+                        ((RtfList) rtfElement).setParentList(this);
+                    } else if(rtfElement instanceof RtfListItem) {
+                        ((RtfListItem) rtfElement).setParent(ll);
+                    }
+                    ll.setFontNumber( new RtfFont(document, new Font(Font.TIMES_ROMAN, 10, Font.NORMAL, new Color(0, 0, 0))) );
+                    if (list.getSymbol() != null && list.getSymbol().getFont() != null && !list.getSymbol().getContent().startsWith("-") && list.getSymbol().getContent().length() > 0) {
+                        // only set this to bullet symbol is not default
+                        ll.setBulletFont( list.getSymbol().getFont());
+                        ll.setBulletCharacter(list.getSymbol().getContent().substring(0, 1));
+                    } else
+                	 if (list.getSymbol() != null && list.getSymbol().getFont() != null) {
+                     	ll.setBulletFont(list.getSymbol().getFont());
+                	 
+                	 } else {
+                    	ll.setBulletFont(new Font(Font.SYMBOL, 10, Font.NORMAL, new Color(0, 0, 0)));
+                    } 
+                    items.add(rtfElement);
+                }
+
+            } catch(DocumentException de) {
+                de.printStackTrace();
+            }
+        }
+    }
+    
+    /**
+     * Writes the definition part of this list level
+     * @param result
+     * @throws IOException
+     * @since 2.1.3
+     */
+    public void writeDefinition(final OutputStream result) throws IOException
+    {
+        result.write(OPEN_GROUP);
+        result.write(LIST);
+        result.write(LIST_TEMPLATE_ID);
+        result.write(intToByteArray(document.getRandomInt()));
+
+        int levelsToWrite = -1;
+        
+        switch(this.listType) {
+        case LIST_TYPE_NORMAL:
+        	levelsToWrite = listLevels.size();
+        	break;
+        case LIST_TYPE_SIMPLE:
+            result.write(LIST_SIMPLE);
+            result.write(intToByteArray(1)); 
+        	levelsToWrite = 1;
+        	break;
+        case LIST_TYPE_HYBRID:
+            result.write(LIST_HYBRID);
+        	levelsToWrite = listLevels.size();
+        	break;
+    	default:
+    		break;
+        }
+        this.document.outputDebugLinebreak(result);
+
+        // TODO: Figure out hybrid because multi-level hybrid does not work.
+        // Seems hybrid is mixed type all single level - Simple = single level
+        // SIMPLE1/HYRBID
+        // 1. Line 1
+        // 2. Line 2
+        // MULTI-LEVEL LISTS Are Simple0 - 9 levels (0-8) all single digit
+        // 1. Line 1
+        // 1.1. Line 1.1
+        // 1.2. Line 1.2
+        // 2. Line 2
+         
+        // write the listlevels here
+        for(int i = 0; i<levelsToWrite; i++) {
+        	((RtfListLevel)listLevels.get(i)).writeDefinition(result);
+            this.document.outputDebugLinebreak(result);
+        }
+        
+        result.write(LIST_ID);
+        result.write(intToByteArray(this.listID));
+        result.write(CLOSE_GROUP);
+        this.document.outputDebugLinebreak(result);
+        if(items != null) {
+        for(int i = 0; i < items.size(); i++) {
+            RtfElement rtfElement = (RtfElement) items.get(i);
+            if(rtfElement instanceof RtfList) {
+            	RtfList rl = (RtfList)rtfElement;
+            	rl.writeDefinition(result);
+                break;
+            } else if(rtfElement instanceof RtfListItem) {
+            	RtfListItem rli = (RtfListItem) rtfElement;
+            	if(rli.writeDefinition(result)) break;
+            }
+        }    
+        }
+    }
+    
+    /**
+     * Writes the content of the RtfList
+     * @since 2.1.3
+    */    
+    public void writeContent(final OutputStream result) throws IOException
+    {
+        if(!this.inTable) {
+            result.write(OPEN_GROUP);
+        }
+        
+        int itemNr = 0;
+        if(items != null) {
+        for(int i = 0; i < items.size(); i++) {
+        	
+            RtfElement thisRtfElement = (RtfElement) items.get(i);
+           //thisRtfElement.writeContent(result);
+            if(thisRtfElement instanceof RtfListItem) {
+                itemNr++;
+            	RtfListItem rtfElement = (RtfListItem)thisRtfElement;
+            	RtfListLevel listLevel =  rtfElement.getParent();
+                if(listLevel.getListLevel() == 0) {
+                    correctIndentation();
+                }
+                
+                if(i == 0) {
+                	listLevel.writeListBeginning(result);
+                    writeListNumbers(result);
+                }
+
+                writeListTextBlock(result, itemNr, listLevel);
+                
+                rtfElement.writeContent(result);
+                
+                if(i < (items.size() - 1) || !this.inTable || listLevel.getListType() > 0) { // TODO Fix no paragraph on last list item in tables
+                    result.write(RtfParagraph.PARAGRAPH);
+                }
+                this.document.outputDebugLinebreak(result);
+            } else if(thisRtfElement instanceof RtfList) {
+            	((RtfList)thisRtfElement).writeContent(result);
+//            	((RtfList)thisRtfElement).writeListBeginning(result);
+                writeListNumbers(result);
+                this.document.outputDebugLinebreak(result);
+            }
+        }
+        }
+        if(!this.inTable) {
+            result.write(CLOSE_GROUP);
+        }
+        result.write(RtfParagraph.PARAGRAPH_DEFAULTS);
+    }        
+    /**
+     * 
+     * @param result
+     * @param itemNr
+     * @param listLevel
+     * @throws IOException
+     * @since 2.1.3
+     */
+    protected void writeListTextBlock(final OutputStream result, int itemNr, RtfListLevel listLevel) 
+    throws IOException {
+    	result.write(OPEN_GROUP);
+        result.write(RtfList.LIST_TEXT);
+        result.write(RtfParagraph.PARAGRAPH_DEFAULTS);
+        if(this.inTable) {
+            result.write(RtfParagraph.IN_TABLE);
+        }
+        result.write(RtfFontList.FONT_NUMBER);
+        if(listLevel.getListType() != RtfListLevel.LIST_TYPE_BULLET) {
+            result.write(intToByteArray(listLevel.getFontNumber().getFontNumber()));
+        } else {
+            result.write(intToByteArray(listLevel.getFontBullet().getFontNumber()));
+        }
+        listLevel.writeIndentation(result);
+        result.write(DELIMITER);
+        if(listLevel.getListType() != RtfListLevel.LIST_TYPE_BULLET) {
+            switch(listLevel.getListType()) {
+                case RtfListLevel.LIST_TYPE_NUMBERED      : result.write(intToByteArray(itemNr)); break;
+                case RtfListLevel.LIST_TYPE_UPPER_LETTERS : result.write(DocWriter.getISOBytes(RomanAlphabetFactory.getUpperCaseString(itemNr))); break;
+                case RtfListLevel.LIST_TYPE_LOWER_LETTERS : result.write(DocWriter.getISOBytes(RomanAlphabetFactory.getLowerCaseString(itemNr))); break;
+                case RtfListLevel.LIST_TYPE_UPPER_ROMAN   : result.write(DocWriter.getISOBytes(RomanNumberFactory.getUpperCaseString(itemNr))); break;
+                case RtfListLevel.LIST_TYPE_LOWER_ROMAN   : result.write(DocWriter.getISOBytes(RomanNumberFactory.getLowerCaseString(itemNr))); break;
+            }
+            result.write(LIST_NUMBER_END);
+        } else {
+            this.document.filterSpecialChar(result, listLevel.getBulletCharacter(), true, false);
+        }
+        result.write(TAB);
+        result.write(CLOSE_GROUP);
+    }
+
+    /**
+     * Writes only the list number and list level number.
+     * 
+     * @param result The <code>OutputStream</code> to write to
+     * @throws IOException On i/o errors.
+     * @since 2.1.3
+     */
+    protected void writeListNumbers(final OutputStream result) throws IOException {
+        result.write(RtfList.LIST_NUMBER);
+        result.write(intToByteArray(listNumber));
+    }
+    /**
+     * Create a default set of listlevels
+     * @since 2.1.3
+     */
+    protected void createDefaultLevels() {
+        this.listLevels = new ArrayList();	// listlevels
+        for(int i=0; i<=8; i++) {
+            // create a list level
+            RtfListLevel ll = new RtfListLevel(this.document);
+            ll.setListType(RtfListLevel.LIST_TYPE_NUMBERED);
+        	ll.setFirstIndent(0);
+        	ll.setLeftIndent(0);
+        	ll.setLevelTextNumber(i);
+            ll.setTentative(true);
+            ll.correctIndentation();
+            this.listLevels.add(ll);
+        }
+
+    }
+    /**
+     * Gets the id of this list
+     * 
+     * @return Returns the list number.
+     * @since 2.1.3
+     */
+    public int getListNumber() {
+        return listNumber;
+    }
+    
+    /**
+     * Sets the id of this list
+     * 
+     * @param listNumber The list number to set.
+     * @since 2.1.3
+     */
+    public void setListNumber(int listNumber) {
+        this.listNumber = listNumber;
+    }
+    
+    /**
+     * Sets whether this RtfList is in a table. Sets the correct inTable setting for all
+     * child elements.
+     * 
+     * @param inTable <code>True</code> if this RtfList is in a table, <code>false</code> otherwise
+     * @since 2.1.3
+     */
+    public void setInTable(boolean inTable) {
+        super.setInTable(inTable);
+        for(int i = 0; i < this.items.size(); i++) {
+        	((RtfBasicElement) this.items.get(i)).setInTable(inTable);
+        }
+        for(int i = 0; i < this.listLevels.size(); i++) {
+        	((RtfListLevel) this.listLevels.get(i)).setInTable(inTable);
+        }
+    }
+    
+    /**
+     * Sets whether this RtfList is in a header. Sets the correct inTable setting for all
+     * child elements.
+     * 
+     * @param inHeader <code>True</code> if this RtfList is in a header, <code>false</code> otherwise
+     * @since 2.1.3
+     */
+    public void setInHeader(boolean inHeader) {
+        super.setInHeader(inHeader);
+        for(int i = 0; i < this.items.size(); i++) {
+            ((RtfBasicElement) this.items.get(i)).setInHeader(inHeader);
+        }
+    }
+
+    /**
+     * Correct the indentation of this RtfList by adding left/first line indentation
+     * from the parent RtfList. Also calls correctIndentation on all child RtfLists.
+     * @since 2.1.3
+     */
+    protected void correctIndentation() {
+    	// TODO: Fix
+//        if(this.parentList != null) {
+//            this.leftIndent = this.leftIndent + this.parentList.getLeftIndent() + this.parentList.getFirstIndent();
+//        }
+        for(int i = 0; i < this.items.size(); i++) {
+            if(this.items.get(i) instanceof RtfList) {
+                ((RtfList) this.items.get(i)).correctIndentation();
+            } else if(this.items.get(i) instanceof RtfListItem) {
+                ((RtfListItem) this.items.get(i)).correctIndentation();
+            }
+        }
+    }
+
+
+	/**
+	 * Set the list ID number
+	 * @param id
+     * @since 2.1.3
+	 */
+	public void setID(int id) {
+		this.listID = id;
+	}
+	/**
+	 * Get the list ID number
+	 * @return this list id
+     * @since 2.1.3
+	 */
+	public int getID() {
+		return this.listID;
+	}
+
+	/**
+	 * @return the listType
+	 * @see RtfList#LIST_TYPE_NORMAL
+	 * @see RtfList#LIST_TYPE_SIMPLE
+	 * @see RtfList#LIST_TYPE_HYBRID
+     * @since 2.1.3
+	 */
+	public int getListType() {
+		return listType;
+	}
+
+	/**
+	 * @param listType the listType to set
+	 * @see RtfList#LIST_TYPE_NORMAL
+	 * @see RtfList#LIST_TYPE_SIMPLE
+	 * @see RtfList#LIST_TYPE_HYBRID
+     * @since 2.1.3
+	 */
+	public void setListType(int listType) throws InvalidParameterException {
+		if(listType == LIST_TYPE_NORMAL || 
+				listType == LIST_TYPE_SIMPLE || 
+				listType == LIST_TYPE_HYBRID ) {
+			this.listType = listType;
+		}
+		else {
+			throw new InvalidParameterException("Invalid listType value.");
+		}
+	}
+
+	/**
+	 * @return the parentList
+     * @since 2.1.3
+	 */
+	public RtfList getParentList() {
+		return parentList;
+	}
+
+	/**
+	 * @param parentList the parentList to set
+     * @since 2.1.3
+	 */
+	public void setParentList(RtfList parentList) {
+		this.parentList = parentList;
+	}
+
+	/**
+	 * @return the name
+     * @since 2.1.3
+	 */
+	public String getName() {
+		return name;
+	}
+
+	/**
+	 * @param name the name to set
+     * @since 2.1.3
+	 */
+	public void setName(String name) {
+		this.name = name;
+	}
+	/**
+	 * @return the list at the index
+     * @since 2.1.3
+	 */
+	public RtfListLevel getListLevel(int index) {
+		if(listLevels != null) {
+		return (RtfListLevel)this.listLevels.get(index);
+		}
+		else
+			return null;
+	}
+
+}
Index: src/core/com/lowagie/text/rtf/parser/destinations/RtfDestinationNull.java
===================================================================
--- src/core/com/lowagie/text/rtf/parser/destinations/RtfDestinationNull.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/parser/destinations/RtfDestinationNull.java	(revision 0)
@@ -0,0 +1,156 @@
+/*
+ * $Id: RtfDestinationNull.java 3373 2008-05-12 16:21:24Z xlv $
+ *
+ * Copyright 2007 by Howard Shank (hgshank@yahoo.com)
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+ 
+package com.lowagie.text.rtf.parser.destinations;
+
+import com.lowagie.text.rtf.parser.RtfParser;
+import com.lowagie.text.rtf.parser.ctrlwords.RtfCtrlWordData;
+
+/**
+ * <code>RtfDestinationNull</code> is for discarded entries. They go nowhere.
+ * If a control word destination is unknown or ignored, this is the destination
+ * that should be set.
+ * 
+ * All methods return true indicating they were handled.
+ * 
+ * This is a unique destination in that it is a singleton.
+ * 
+ * @author Howard Shank (hgshank@yahoo.com)
+ * @since 2.0.8
+ */
+public final class RtfDestinationNull extends RtfDestination {
+	private static RtfDestinationNull instance = null;
+	private static Object lock = new Object();
+	/**
+	 * Constructs a new RtfDestinationNull.
+	 * 
+	 * This constructor is hidden for internal use only.
+	 */
+	private RtfDestinationNull() {
+		super();
+	}
+	/**
+	 * Constructs a new RtfDestinationNull.
+	 * 
+	 * This constructor is hidden for internal use only.
+	 * 
+	 * @param parser Unused value
+	 */
+	private RtfDestinationNull(RtfParser parser) {
+		super(null);
+	}
+	/**
+	 * Get the singleton instance of RtfDestinationNull object.
+	 */
+	static public RtfDestinationNull getInstance() {
+		synchronized(lock)
+		{
+			if(instance == null)
+				instance = new RtfDestinationNull();
+			return instance;
+		}
+	}
+	/* (non-Javadoc)
+	 * @see com.lowagie.text.rtf.parser.destinations.RtfDestination#handleOpenNewGroup()
+	 */
+	public boolean handleOpeningSubGroup() {
+		return true;
+	}
+	
+	/* (non-Javadoc)
+	 * @see com.lowagie.text.rtf.direct.RtfDestination#setDefaults()
+	 */
+	public void setToDefaults() {
+	}
+
+	// Interface definitions
+	
+	/* (non-Javadoc)
+	 * @see com.lowagie.text.rtf.direct.RtfDestination#closeDestination()
+	 */
+	public boolean closeDestination() {
+		return true;
+	}
+	/* (non-Javadoc)
+	 * @see com.lowagie.text.rtf.direct.RtfDestination#handleGroupEnd()
+	 */
+	public boolean handleCloseGroup() {
+		//this.rtfParser.setTokeniserStateNormal();
+		return true;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.lowagie.text.rtf.direct.RtfDestination#handleGroupStart()
+	 */
+	public boolean handleOpenGroup() {
+		//this.rtfParser.setTokeniserStateSkipGroup();
+		return true;
+	}
+	/* (non-Javadoc)
+	 * @see com.lowagie.text.rtf.direct.RtfDestination#handleCharacter(char[])
+	 */
+	public boolean handleCharacter(int ch) {
+		return true;
+	}
+	/* (non-Javadoc)
+	 * @see com.lowagie.text.rtf.parser.destinations.RtfDestination#handleControlWord(com.lowagie.text.rtf.parser.ctrlwords.RtfCtrlWordData)
+	 */
+	public boolean handleControlWord(RtfCtrlWordData ctrlWordData) {
+		return true;
+	}
+	
+	public static String getName() {
+		return RtfDestinationNull.class.getName();
+	}
+	
+	public int getNewTokeniserState() {
+		return RtfParser.TOKENISER_SKIP_GROUP;
+	}
+
+}
Index: src/core/com/lowagie/text/rtf/parser/ctrlwords/RtfCtrlWordData.java
===================================================================
--- src/core/com/lowagie/text/rtf/parser/ctrlwords/RtfCtrlWordData.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/parser/ctrlwords/RtfCtrlWordData.java	(revision 0)
@@ -0,0 +1,157 @@
+/* $Id: RtfCtrlWordData.java 3373 2008-05-12 16:21:24Z xlv $
+ *
+ * Copyright 2007 by Howard Shank (hgshank@yahoo.com)
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.rtf.parser.ctrlwords;
+
+
+/**
+ * The control word and parameter information as parsed by the parser.
+ * Contains the control word,
+ * Flag indicating if there is a parameter. 
+ * The parameter value as a string.
+ * Flag indicating the parameter is positive or negative.
+ * 
+ * @author Howard Shank (hgshank@yahoo.com)
+ * @since 2.0.8
+ */
+public class RtfCtrlWordData implements Cloneable {
+	public String prefix = "";
+	public String suffix = "";
+	/**
+	 * The control word found by the parser
+	 */
+	public String ctrlWord = "";
+	/**
+	 * Flag indicating if this keyword has a parameter.
+	 */
+	public boolean hasParam = false;
+	/**
+	 * The parameter for the control word.
+	 */
+	public String param = "";
+	/**
+	 * Flag indicating if parameter is positive or negative.
+	 */
+	public boolean isNeg = false;
+	/**
+	 * Flag indicating a new group
+	 */
+	public boolean newGroup = false;
+	/**
+	 * Flag indicating if this object has been modified.
+	 */
+	public boolean modified = false;
+	
+	public int ctrlWordType = RtfCtrlWordType.UNIDENTIFIED;
+	public String specialHandler = "";
+	
+	/**
+	 * Return the parameter value as an integer (int) value.
+	 * 
+	 * @return
+	 * 		Returns the parameter value as an int vlaue.
+	 */
+	public int intValue() {
+		int value;
+		value = Integer.parseInt(this.param);
+		if(this.isNeg) value = (-value);
+		return value;
+	}
+	/**
+	 * Return the parameter value as an Integer object.
+	 * 
+	 * @return
+	 * 		Returns the parameter value as an Integer object.
+	 */
+	public Integer toInteger() {
+		Integer value;
+		value = new Integer(this.isNeg ? Integer.parseInt(this.param)*-1 : Integer.parseInt(this.param));
+		return value;
+	}
+	
+
+	/**
+	 *  Return the parameter value as a long value
+	 *  
+	 * @return
+	 * 		Returns the parameter value as a long value
+	 */
+	public long longValue() {
+		long value;
+		value = Long.parseLong(this.param);
+		if(this.isNeg) value = (-value);
+		return value;
+	}
+	/**
+	 *  Return the parameter value as a Long object
+	 *  
+	 * @return
+	 * 		Returns the parameter value as a Long object.
+	 */
+	public Long toLong() {
+		Long value;
+		value = new Long(this.isNeg ? Long.parseLong(this.param)*-1 : Long.parseLong(this.param));
+		return value;
+	}
+	
+	public String toString() {
+		String out = "";
+		out = this.prefix + this.ctrlWord;
+		if(this.hasParam) {
+			if(this.isNeg) out += "-";
+			out += this.param; 
+		}
+		out += this.suffix;
+		return out;
+	}
+	
+	public Object clone() throws CloneNotSupportedException{
+		Object cl = (RtfCtrlWordData)super.clone();
+		return cl;
+	}
+}
Index: src/core/com/lowagie/text/rtf/field/RtfTotalPageNumber.java
===================================================================
--- src/core/com/lowagie/text/rtf/field/RtfTotalPageNumber.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/field/RtfTotalPageNumber.java	(revision 0)
@@ -0,0 +1,131 @@
+/*
+ * $Id: RtfTotalPageNumber.java 3580 2008-08-06 15:52:00Z howard_s $
+ *
+ * Copyright 2005 Jose Hurtado <a href="mailto:jose.hurtado@gft.com">jose.hurtado@gft.com</a>
+ * Parts Copyright 2005 Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.rtf.field;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import com.lowagie.text.DocWriter;
+import com.lowagie.text.Font;
+import com.lowagie.text.rtf.document.RtfDocument;
+
+/**
+ * The RtfTotalPageNumber provides the total number of pages field in rtf documents.
+ * 
+ * @version $Id: RtfTotalPageNumber.java 3580 2008-08-06 15:52:00Z howard_s $
+ * @author Jose Hurtado (jose.hurtado@gft.com)
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Thomas Bickel (tmb99@inode.at)
+ */
+public class RtfTotalPageNumber extends RtfField {
+
+    /**
+     * Constant for arabic total page numbers.
+     */
+    private static final byte[] ARABIC_TOTAL_PAGES = DocWriter.getISOBytes("NUMPAGES \\\\* Arabic");
+    
+    /**
+     * Constructs a RtfTotalPageNumber. This can be added anywhere to add a total number of pages field.
+     */
+    public RtfTotalPageNumber() {
+        super(null);
+    }
+    
+    /**
+     * Constructs a RtfTotalPageNumber with a specified Font. This can be added anywhere
+     * to add a total number of pages field.
+     * @param font
+     */
+    public RtfTotalPageNumber(Font font) {
+        super(null, font);
+    }
+    
+    /**
+     * Constructs a RtfTotalPageNumber object.
+     * 
+     * @param doc The RtfDocument this RtfTotalPageNumber belongs to
+     */
+    public RtfTotalPageNumber(RtfDocument doc) {
+        super(doc);
+    }
+    
+    /**
+     * Constructs a RtfTotalPageNumber object with a specific font.
+     * 
+     * @param doc The RtfDocument this RtfTotalPageNumber belongs to
+     * @param font The Font to use
+     */
+    public RtfTotalPageNumber(RtfDocument doc, Font font) {
+        super(doc, font);
+    }
+    
+    /**
+     * Writes the field NUMPAGES instruction with Arabic format: "NUMPAGES \\\\* Arabic".
+     * 
+     * @param result The <code>OutputStream</code> to write to.
+     * @throws IOException on i/o errors.
+     */ 
+    protected void writeFieldInstContent(OutputStream result) throws IOException 
+    {
+    	result.write(ARABIC_TOTAL_PAGES);
+    }
+
+    /**
+     * Writes the field result content "1".
+     * 
+     * @param out The <code>OutputStream</code> to write to.
+     * @throws IOException on i/o errors.
+     */
+    protected void writeFieldResultContent(final OutputStream out) throws IOException 
+    {
+    	out.write(DocWriter.getISOBytes("1"));
+    }
+}
Index: src/core/com/lowagie/text/rtf/style/RtfFont.java
===================================================================
--- src/core/com/lowagie/text/rtf/style/RtfFont.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/style/RtfFont.java	(revision 0)
@@ -0,0 +1,745 @@
+/*
+ * $Id: RtfFont.java 4008 2009-07-07 09:56:52Z blowagie $
+ *
+ * Copyright 2001, 2002, 2003, 2004 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.rtf.style;
+
+import java.awt.Color;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import com.lowagie.text.DocWriter;
+import com.lowagie.text.Font;
+import com.lowagie.text.rtf.RtfExtendedElement;
+import com.lowagie.text.rtf.document.RtfDocument;
+
+/**
+ * The RtfFont class stores one font for an rtf document. It extends Font,
+ * so can be set as a font, to allow adding of fonts with arbitrary names.
+ * BaseFont fontname handling contributed by Craig Fleming. Various fixes
+ * Renaud Michel, Werner Daehn.
+ *
+ * Version: $Id: RtfFont.java 4008 2009-07-07 09:56:52Z blowagie $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Craig Fleming (rythos@rhana.dhs.org)
+ * @author Renaud Michel (r.michel@immedia.be)
+ * @author Werner Daehn (Werner.Daehn@BusinessObjects.com)
+ * @author Lidong Liu (tmslld@gmail.com)
+ * @author Thomas Bickel (tmb99@inode.at)
+ */
+public class RtfFont extends Font implements RtfExtendedElement {
+    /**
+     * Constant for the font family to use ("froman")
+     */
+    private static final byte[] FONT_FAMILY = DocWriter.getISOBytes("\\froman");
+    /**
+     * Constant for the charset
+     */
+    private static final byte[] FONT_CHARSET = DocWriter.getISOBytes("\\fcharset");
+    /**
+     * Constant for the font size
+     */
+    public static final byte[] FONT_SIZE = DocWriter.getISOBytes("\\fs");
+    /**
+     * Constant for the bold flag
+     */
+    private static final byte[] FONT_BOLD = DocWriter.getISOBytes("\\b");
+    /**
+     * Constant for the italic flag
+     */
+    private static final byte[] FONT_ITALIC = DocWriter.getISOBytes("\\i");
+    /**
+     * Constant for the underline flag
+     */
+    private static final byte[] FONT_UNDERLINE = DocWriter.getISOBytes("\\ul");
+    /**
+     * Constant for the strikethrough flag
+     */
+    private static final byte[] FONT_STRIKETHROUGH = DocWriter.getISOBytes("\\strike");
+    /**
+     * Constant for the double strikethrough flag
+     */
+    private static final byte[] FONT_DOUBLE_STRIKETHROUGH = DocWriter.getISOBytes("\\striked");
+    /**
+     * Constant for the shadow flag
+     */
+    private static final byte[] FONT_SHADOW = DocWriter.getISOBytes("\\shad");
+    /**
+     * Constant for the outline flag
+     */
+    private static final byte[] FONT_OUTLINE = DocWriter.getISOBytes("\\outl");
+    /**
+     * Constant for the embossed flag
+     */
+    private static final byte[] FONT_EMBOSSED = DocWriter.getISOBytes("\\embo");
+    /**
+     * Constant for the engraved flag
+     */
+    private static final byte[] FONT_ENGRAVED = DocWriter.getISOBytes("\\impr");
+    /**
+     * Constant for hidden text flag
+     */
+    private static final byte[] FONT_HIDDEN = DocWriter.getISOBytes("\\v");
+    
+    /**
+     * Constant for a plain font
+     */
+    public static final int STYLE_NONE = 0;
+    /**
+     * Constant for a bold font
+     */
+    public static final int STYLE_BOLD = 1;
+    /**
+     * Constant for an italic font
+     */
+    public static final int STYLE_ITALIC = 2;
+    /**
+     * Constant for an underlined font
+     */
+    public static final int STYLE_UNDERLINE = 4;
+    /**
+     * Constant for a strikethrough font
+     */
+    public static final int STYLE_STRIKETHROUGH = 8;
+    /**
+     * Constant for a double strikethrough font
+     */
+    public static final int STYLE_DOUBLE_STRIKETHROUGH = 16;
+    /**
+     * Constant for a shadowed font
+     */
+    public static final int STYLE_SHADOW = 32;
+    /**
+     * Constant for an outlined font
+     */
+    public static final int STYLE_OUTLINE = 64;
+    /**
+     * Constant for an embossed font
+     */
+    public static final int STYLE_EMBOSSED = 128;
+    /**
+     * Constant for an engraved font
+     */
+    public static final int STYLE_ENGRAVED = 256;
+    /**
+     * Constant for a font that hides the actual text.
+     */
+    public static final int STYLE_HIDDEN = 512;
+    
+    /**
+     * Default font
+     * @since 2.1.7
+     */
+    public static final String DEFAULT_FONT = "Times New Roman";
+
+    /**
+     * The font name. Defaults to "Times New Roman"
+     */
+    private String fontName = DEFAULT_FONT;
+    /**
+     * The font size. Defaults to 10
+     */
+    private int fontSize = 10;
+    /**
+     * The font style. Defaults to STYLE_NONE
+     */
+    private int fontStyle = STYLE_NONE;
+    /**
+     * The number of this font
+     */
+    private int fontNumber = 0;
+    /**
+     * The color of this font
+     */
+    private RtfColor color = null;
+    /**
+     * The character set to use for this font
+     */
+    private int charset = 0;
+    /**
+     * The RtfDocument this RtfFont belongs to.
+     */
+    protected RtfDocument document = null;
+    
+    /**
+     * Constructs a RtfFont with the given font name and all other properties
+     * at their default values.
+     * 
+     * @param fontName The font name to use
+     */
+    public RtfFont(String fontName) {
+        super(Font.UNDEFINED, Font.UNDEFINED, Font.UNDEFINED, null);
+        this.fontName = fontName;
+    }
+    
+    /**
+     * Constructs a RtfFont with the given font name and font size and all other
+     * properties at their default values.
+     * 
+     * @param fontName The font name to use
+     * @param size The font size to use
+     */
+    public RtfFont(String fontName, float size) {
+        super(Font.UNDEFINED, size, Font.UNDEFINED, null);
+        this.fontName = fontName;
+    }
+    
+    /**
+     * Constructs a RtfFont with the given font name, font size and font style and the
+     * default color.
+     * 
+     * @param fontName The font name to use
+     * @param size The font size to use
+     * @param style The font style to use
+     */
+    public RtfFont(String fontName, float size, int style) {
+        super(Font.UNDEFINED, size, style, null);
+        this.fontName = fontName;
+    }
+    
+    /**
+     * Constructs a RtfFont with the given font name, font size, font style and
+     * color.
+     * 
+     * @param fontName The font name to use
+     * @param size the font size to use
+     * @param style The font style to use
+     * @param color The font color to use
+     */
+    public RtfFont(String fontName, float size, int style, Color color) {
+        super(Font.UNDEFINED, size, style, color);
+        this.fontName = fontName;
+    }
+    
+    /**
+     * Constructs a RtfFont with the given font name, font size, font style, color
+     * and charset. This can be used when generating non latin-1 text.
+     * 
+     * @param fontName The font name to use
+     * @param size the font size to use
+     * @param style The font style to use
+     * @param color The font color to use
+     * @param charset The charset of the font content
+     */
+    public RtfFont(String fontName, float size, int style, Color color, int charset) {
+        this(fontName, size, style, color);
+        this.charset = charset;
+    }
+
+    /**
+     * Special constructor for the default font
+     *
+     * @param doc The RtfDocument this font appears in
+     * @param fontNumber The id of this font
+     */
+    protected RtfFont(RtfDocument doc, int fontNumber) {
+        this.document = doc;
+        this.fontNumber = fontNumber;
+        color = new RtfColor(doc, 0, 0, 0);
+    }
+
+    /**
+     * Constructs a RtfFont from a com.lowagie.text.Font
+     * @param doc The RtfDocument this font appears in
+     * @param font The Font to use as a base
+     */
+    public RtfFont(RtfDocument doc, Font font) {
+        this.document = doc;
+        if(font != null) {
+            if(font instanceof RtfFont) {
+                this.fontName = ((RtfFont) font).getFontName();
+                this.charset = ((RtfFont) font).getCharset();
+            } else {
+                setToDefaultFamily(font.getFamilyname());
+            }
+            if(font.getBaseFont() != null) {
+                String[][] fontNames = font.getBaseFont().getFullFontName();
+                for(int i = 0; i < fontNames.length; i++) {
+                    if(fontNames[i][2].equals("0")) {
+                        this.fontName = fontNames[i][3];
+                        break;
+                    } else if(fontNames[i][2].equals("1033") || fontNames[i][2].equals("")) {
+                        this.fontName = fontNames[i][3];
+                    }
+                }
+            }
+
+            if(this.fontName.equalsIgnoreCase("unknown")) {
+                this.fontName = DEFAULT_FONT;
+            }
+            
+            setSize(font.getSize());
+            setStyle(font.getStyle());
+            setColor(font.getColor());
+            if(document != null) {
+            	this.fontNumber = document.getDocumentHeader().getFontNumber(this);
+            }
+        }
+
+        if(document != null) {
+            setRtfDocument(document);
+        }
+    }
+
+    /**
+     * Writes the font definition
+     */
+    public void writeDefinition(final OutputStream result) throws IOException
+    {
+        result.write(FONT_FAMILY);
+        result.write(FONT_CHARSET);
+        result.write(intToByteArray(charset));
+        result.write(DELIMITER);
+        document.filterSpecialChar(result, fontName, true, false);
+    }
+    
+    /**
+     * Writes the font beginning
+     *
+     * @param result The <code>OutputStream</code> to write to.
+     * @throws IOException On i/o errors.
+     */
+    public void writeBegin(final OutputStream result) throws IOException {
+        if(this.fontNumber != Font.UNDEFINED) {
+            result.write(RtfFontList.FONT_NUMBER);
+            result.write(intToByteArray(fontNumber));
+        }
+        if(this.fontSize != Font.UNDEFINED) {
+            result.write(FONT_SIZE);
+            result.write(intToByteArray(fontSize * 2));
+        }
+        if(this.fontStyle != UNDEFINED) {
+            if((fontStyle & STYLE_BOLD) == STYLE_BOLD) {
+                result.write(FONT_BOLD);
+            }
+            if((fontStyle & STYLE_ITALIC) == STYLE_ITALIC) {
+                result.write(FONT_ITALIC);
+            }
+            if((fontStyle & STYLE_UNDERLINE) == STYLE_UNDERLINE) {
+                result.write(FONT_UNDERLINE);
+            }
+            if((fontStyle & STYLE_STRIKETHROUGH) == STYLE_STRIKETHROUGH) {
+                result.write(FONT_STRIKETHROUGH);
+            }
+            if((fontStyle & STYLE_HIDDEN) == STYLE_HIDDEN) {
+                result.write(FONT_HIDDEN);
+            }
+            if((fontStyle & STYLE_DOUBLE_STRIKETHROUGH) == STYLE_DOUBLE_STRIKETHROUGH) {
+                result.write(FONT_DOUBLE_STRIKETHROUGH);
+                result.write(intToByteArray(1));
+            }
+            if((fontStyle & STYLE_SHADOW) == STYLE_SHADOW) {
+                result.write(FONT_SHADOW);
+            }
+            if((fontStyle & STYLE_OUTLINE) == STYLE_OUTLINE) {
+                result.write(FONT_OUTLINE);
+            }
+            if((fontStyle & STYLE_EMBOSSED) == STYLE_EMBOSSED) {
+                result.write(FONT_EMBOSSED);
+            }
+            if((fontStyle & STYLE_ENGRAVED) == STYLE_ENGRAVED) {
+                result.write(FONT_ENGRAVED);
+            }
+        }
+        if(color != null) {
+            color.writeBegin(result);
+        }
+    }
+
+    /**
+     * Write the font end
+     *
+     * @param result The <code>OutputStream</code> to write to.
+     * @throws IOException On i/o errors.
+     */
+    public void writeEnd(final OutputStream result) throws IOException{
+        if(this.fontStyle != UNDEFINED) {
+            if((fontStyle & STYLE_BOLD) == STYLE_BOLD) {
+                result.write(FONT_BOLD);
+                result.write(intToByteArray(0));
+            }
+            if((fontStyle & STYLE_ITALIC) == STYLE_ITALIC) {
+                result.write(FONT_ITALIC);
+                result.write(intToByteArray(0));
+            }
+            if((fontStyle & STYLE_UNDERLINE) == STYLE_UNDERLINE) {
+                result.write(FONT_UNDERLINE);
+                result.write(intToByteArray(0));
+            }
+            if((fontStyle & STYLE_STRIKETHROUGH) == STYLE_STRIKETHROUGH) {
+                result.write(FONT_STRIKETHROUGH);
+                result.write(intToByteArray(0));
+            }
+            if((fontStyle & STYLE_HIDDEN) == STYLE_HIDDEN) {
+                result.write(FONT_HIDDEN);
+                result.write(intToByteArray(0));
+            }
+            if((fontStyle & STYLE_DOUBLE_STRIKETHROUGH) == STYLE_DOUBLE_STRIKETHROUGH) {
+                result.write(FONT_DOUBLE_STRIKETHROUGH);
+                result.write(intToByteArray(0));
+            }
+            if((fontStyle & STYLE_SHADOW) == STYLE_SHADOW) {
+                result.write(FONT_SHADOW);
+                result.write(intToByteArray(0));
+            }
+            if((fontStyle & STYLE_OUTLINE) == STYLE_OUTLINE) {
+                result.write(FONT_OUTLINE);
+                result.write(intToByteArray(0));
+            }
+            if((fontStyle & STYLE_EMBOSSED) == STYLE_EMBOSSED) {
+                result.write(FONT_EMBOSSED);
+                result.write(intToByteArray(0));
+            }
+            if((fontStyle & STYLE_ENGRAVED) == STYLE_ENGRAVED) {
+                result.write(FONT_ENGRAVED);
+                result.write(intToByteArray(0));
+            }
+        }
+    }
+
+    /**
+     * unused
+     */
+    public void writeContent(OutputStream out) throws IOException
+    {    	
+    }
+    
+    /**
+     * Tests for equality of RtfFonts. RtfFonts are equal if their fontName,
+     * fontSize, fontStyle and fontSuperSubscript are equal
+     * 
+     * @param obj The RtfFont to compare with this RtfFont
+     * @return <code>True</code> if the RtfFonts are equal, <code>false</code> otherwise
+     */
+    public boolean equals(Object obj) {
+        if(!(obj instanceof RtfFont)) {
+            return false;
+        }
+        RtfFont font = (RtfFont) obj;
+        boolean result = true;
+        result = result & this.fontName.equals(font.getFontName());
+
+        return result;
+    }
+
+    /**
+     * Returns the hash code of this RtfFont. The hash code is the hash code of the
+     * string containing the font name + font size + "-" + the font style + "-" + the
+     * font super/supscript value.
+     * 
+     * @return The hash code of this RtfFont
+     */
+    public int hashCode() {
+        return (this.fontName + this.fontSize + "-" + this.fontStyle).hashCode();
+    }
+    
+    /**
+     * Gets the font name of this RtfFont
+     * 
+     * @return The font name
+     */
+    public String getFontName() {
+        return this.fontName;
+    }
+
+    /**
+     * Sets the font name of this RtfFont.
+     * 
+     * @param fontName The font name to use 
+     */
+    protected void setFontName(String fontName) {
+        this.fontName = fontName;
+        if(document != null) {
+            this.fontNumber = document.getDocumentHeader().getFontNumber(this);
+        }
+    }
+    
+    /**
+     * @see com.lowagie.text.Font#getFamilyname()
+     */
+    public String getFamilyname() {
+        return this.fontName;
+    }
+    
+    /**
+     * @see com.lowagie.text.Font#setFamily(String)
+     */
+    public void setFamily(String family){
+        super.setFamily(family);
+        setToDefaultFamily(family);
+    }
+    
+    /**
+     * Sets the correct font name from the family name.
+     * 
+     * @param familyname The family name to set the name to.
+     */
+    private void setToDefaultFamily(String familyname){
+        switch (Font.getFamilyIndex(familyname)) {
+            case Font.COURIER:
+                this.fontName = "Courier";
+                break;
+            case Font.HELVETICA:
+                this.fontName = "Arial";
+                break;
+            case Font.SYMBOL:
+                this.fontName = "Symbol";
+                this.charset = 2;
+                break;
+            case Font.TIMES_ROMAN:
+                this.fontName = "Times New Roman";
+                break;
+            case Font.ZAPFDINGBATS:
+                this.fontName = "Windings";
+                break;
+            default:
+                this.fontName = familyname;
+        }
+    }
+    
+    /**
+     * Gets the font size of this RtfFont
+     * 
+     * @return The font size
+     */
+    public int getFontSize() {
+        return this.fontSize;
+    }
+    
+    /**
+     * @see com.lowagie.text.Font#setSize(float)
+     */
+    public void setSize(float size){
+        super.setSize(size);
+        this.fontSize = (int) getSize();
+    }
+
+    /**
+     * Gets the font style of this RtfFont
+     * 
+     * @return The font style
+     */
+    public int getFontStyle() {
+        return this.fontStyle;
+    }
+    
+    /**
+     * @see com.lowagie.text.Font#setStyle(int)
+     */
+    public void setStyle(int style){
+        super.setStyle(style);
+        this.fontStyle = getStyle();
+    }
+    
+    /**
+     * @see com.lowagie.text.Font#setStyle(String)
+     */
+    public void setStyle(String style) {
+        super.setStyle(style);
+        fontStyle = getStyle();
+    }
+
+    /**
+     * Gets the charset used for constructing this RtfFont.
+     * 
+     * @return The charset of this RtfFont.
+     */
+    public int getCharset() {
+        return charset;
+    }
+
+    /**
+     * Sets the charset used for constructing this RtfFont.
+     * 
+     * @param charset The charset to use.
+     */
+    public void setCharset(int charset) {
+        this.charset = charset;
+    }
+
+    /**
+     * Gets the font number of this RtfFont
+     * 
+     * @return The font number
+     */
+    public int getFontNumber() {
+        return fontNumber;
+    }
+
+    /**
+     * Sets the RtfDocument this RtfFont belongs to
+     * 
+     * @param doc The RtfDocument to use
+     */
+    public void setRtfDocument(RtfDocument doc) {
+        this.document = doc;
+        if(document != null) {
+            this.fontNumber = document.getDocumentHeader().getFontNumber(this);
+        }
+        if(this.color != null) {
+            this.color.setRtfDocument(this.document);
+        }
+    }
+
+    /**
+     * Unused
+     * @param inTable
+     */
+    public void setInTable(boolean inTable) {
+    }
+    
+    /**
+     * Unused
+     * @param inHeader
+     */
+    public void setInHeader(boolean inHeader) {
+    }
+    
+    /**
+     * @see com.lowagie.text.Font#setColor(Color)
+     */
+    public void setColor(Color color) {
+        super.setColor(color);
+        if(color != null) {
+            this.color = new RtfColor(document, color);
+        } else {
+            this.color = null;
+        }
+    }
+    
+    /**
+     * @see com.lowagie.text.Font#setColor(int, int, int)
+     */
+    public void setColor(int red, int green, int blue) {
+        super.setColor(red,green,blue);
+        this.color = new RtfColor(document, red, green, blue);
+    }
+
+    /**
+     * Transforms an integer into its String representation and then returns the bytes
+     * of that string.
+     *
+     * @param i The integer to convert
+     * @return A byte array representing the integer
+     */
+    protected byte[] intToByteArray(int i) {
+        return DocWriter.getISOBytes(Integer.toString(i));
+    }
+
+    /**
+     * Replaces the attributes that are equal to <VAR>null</VAR> with
+     * the attributes of a given font.
+     *
+     * @param font The surrounding font
+     * @return A RtfFont
+     */
+    public Font difference(Font font) {
+        String dFamilyname = font.getFamilyname();
+        if(dFamilyname == null || dFamilyname.trim().equals("") || dFamilyname.trim().equalsIgnoreCase("unknown")) {
+            dFamilyname = this.fontName;
+        }
+
+        float dSize = font.getSize();
+        if(dSize == Font.UNDEFINED) {
+            dSize = this.getSize();
+        }
+
+        int dStyle = Font.UNDEFINED;
+        if(this.getStyle() != Font.UNDEFINED && font.getStyle() != Font.UNDEFINED) {
+            dStyle = this.getStyle() | font.getStyle();
+        } else if(this.getStyle() != Font.UNDEFINED) {
+            dStyle = this.getStyle();
+        } else if(font.getStyle() != Font.UNDEFINED) {
+            dStyle = font.getStyle();
+        }
+
+        Color dColor = font.getColor();
+        if(dColor == null) {
+            dColor = this.getColor();
+        }
+        
+        int dCharset = this.charset;
+        if(font instanceof RtfFont) {
+            dCharset = ((RtfFont) font).getCharset();
+        }
+        
+        return new RtfFont(dFamilyname, dSize, dStyle, dColor, dCharset);
+    }
+    
+    /**
+     * The <code>RtfFont</code> is never a standard font.
+     * 
+     * @since 2.1.0
+     */
+    public boolean isStandardFont() {
+        return false;
+    }
+    
+    /**
+     * Compares this <code>RtfFont</code> to either a {@link com.lowagie.text.Font} or
+     * an <code>RtfFont</code>.
+     * 
+     * @since 2.1.0
+     */
+    public int compareTo(Object object) {
+        if (object == null) {
+            return -1;
+        }
+        if(object instanceof RtfFont) {
+            if(this.getFontName().compareTo(((RtfFont) object).getFontName()) != 0) {
+                return 1;
+            } else {
+                return super.compareTo(object);
+            }
+        } else if(object instanceof Font) {
+            return super.compareTo(object);
+        } else {
+            return -3;
+        }
+    }
+}
Index: src/core/com/lowagie/text/rtf/graphic/RtfImage.java
===================================================================
--- src/core/com/lowagie/text/rtf/graphic/RtfImage.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/graphic/RtfImage.java	(revision 0)
@@ -0,0 +1,402 @@
+/*
+ * $Id: RtfImage.java 3580 2008-08-06 15:52:00Z howard_s $
+ *
+ * Copyright 2001, 2002, 2003, 2004 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.rtf.graphic;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import com.lowagie.text.DocWriter;
+import com.lowagie.text.DocumentException;
+import com.lowagie.text.Element;
+import com.lowagie.text.Image;
+import com.lowagie.text.pdf.codec.wmf.MetaDo;
+import com.lowagie.text.rtf.RtfElement;
+import com.lowagie.text.rtf.document.RtfDocument;
+import com.lowagie.text.rtf.document.output.RtfByteArrayBuffer;
+import com.lowagie.text.rtf.style.RtfParagraphStyle;
+import com.lowagie.text.rtf.text.RtfParagraph;
+
+/**
+ * The RtfImage contains one image. Supported image types are jpeg, png, wmf, bmp.
+ * 
+ * @version $Id: RtfImage.java 3580 2008-08-06 15:52:00Z howard_s $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Paulo Soares
+ * @author Thomas Bickel (tmb99@inode.at)
+ */
+public class RtfImage extends RtfElement {
+    
+    /**
+     * Constant for the shape/picture group
+     */
+    private static final byte[] PICTURE_GROUP = DocWriter.getISOBytes("\\*\\shppict");
+    /**
+     * Constant for a picture
+     */
+    private static final byte[] PICTURE = DocWriter.getISOBytes("\\pict");
+    /**
+     * Constant for a jpeg image
+     */
+    private static final byte[] PICTURE_JPEG = DocWriter.getISOBytes("\\jpegblip");
+    /**
+     * Constant for a png image
+     */
+    private static final byte[] PICTURE_PNG = DocWriter.getISOBytes("\\pngblip");
+    /**
+     * Constant for a wmf image
+     */
+    private static final byte[] PICTURE_WMF = DocWriter.getISOBytes("\\wmetafile8");
+    /**
+     * Constant for the picture width
+     */
+    private static final byte[] PICTURE_WIDTH = DocWriter.getISOBytes("\\picw");
+    /**
+     * Constant for the picture height
+     */
+    private static final byte[] PICTURE_HEIGHT = DocWriter.getISOBytes("\\pich");
+    /**
+     * Constant for the picture width scale
+     */
+    private static final byte[] PICTURE_SCALED_WIDTH = DocWriter.getISOBytes("\\picwgoal");
+    /**
+     * Constant for the picture height scale
+     */
+    private static final byte[] PICTURE_SCALED_HEIGHT = DocWriter.getISOBytes("\\pichgoal");
+    /**
+     * Constant for horizontal picture scaling
+     */
+    private static final byte[] PICTURE_SCALE_X = DocWriter.getISOBytes("\\picscalex");
+    /**
+     * Constant for vertical picture scaling
+     */
+    private static final byte[] PICTURE_SCALE_Y = DocWriter.getISOBytes("\\picscaley");
+    /**
+     * "\bin" constant
+     */
+    private static final byte[] PICTURE_BINARY_DATA = DocWriter.getISOBytes("\\bin");
+    /**
+     * Constant for converting pixels to twips
+     */
+    private static final int PIXEL_TWIPS_FACTOR = 15;
+    
+    /**
+     * The type of image this is.
+     */
+    private final int imageType;
+    /**
+     * Binary image data.
+     */
+    private final byte[][] imageData;
+    /**
+     * The alignment of this picture
+     */
+    private int alignment = Element.ALIGN_LEFT;
+    /**
+     * The width of this picture
+     */
+    private float width = 0;
+    /**
+     * The height of this picture
+     */
+    private float height = 0;
+    /**
+     * The intended display width of this picture
+     */
+    private float plainWidth = 0;
+    /**
+     * The intended display height of this picture
+     */
+    private float plainHeight = 0;
+    /**
+     * Whether this RtfImage is a top level element and should
+     * be an extra paragraph.
+     */
+    private boolean topLevelElement = false;
+    
+    /**
+     * Constructs a RtfImage for an Image.
+     * 
+     * @param doc The RtfDocument this RtfImage belongs to
+     * @param image The Image that this RtfImage wraps
+     * @throws DocumentException If an error occurred accessing the image content
+     */
+    public RtfImage(RtfDocument doc, Image image) throws DocumentException
+    {
+        super(doc);
+        imageType = image.getOriginalType();
+        if (!(imageType == Image.ORIGINAL_JPEG || imageType == Image.ORIGINAL_BMP
+                || imageType == Image.ORIGINAL_PNG || imageType == Image.ORIGINAL_WMF || imageType == Image.ORIGINAL_GIF)) {
+            throw new DocumentException("Only BMP, PNG, WMF, GIF and JPEG images are supported by the RTF Writer");
+        }
+        alignment = image.getAlignment();
+        width = image.getWidth();
+        height = image.getHeight();
+        plainWidth = image.getPlainWidth();
+        plainHeight = image.getPlainHeight();
+        this.imageData = getImageData(image);
+    }
+    
+    /**
+     * Extracts the image data from the Image.
+     * 
+     * @param image The image for which to extract the content
+     * @return The raw image data, not formated
+     * @throws DocumentException If an error occurs accessing the image content
+     */
+    private byte[][] getImageData(Image image) throws DocumentException 
+    {
+    	final int WMF_PLACEABLE_HEADER_SIZE = 22;
+        final RtfByteArrayBuffer bab = new RtfByteArrayBuffer();
+        
+        try {
+            if(imageType == Image.ORIGINAL_BMP) {
+            	bab.append(MetaDo.wrapBMP(image));
+            } else {            	
+            	final byte[] iod = image.getOriginalData();
+            	if(iod == null) {
+            		
+                	final InputStream imageIn = image.getUrl().openStream();
+                    if(imageType == Image.ORIGINAL_WMF) { //remove the placeable header first
+                    	for(int k = 0; k < WMF_PLACEABLE_HEADER_SIZE; k++) {
+							if(imageIn.read() < 0) throw new EOFException("while removing wmf placeable header");
+						}
+                    }
+                    bab.write(imageIn);
+                	imageIn.close();
+                    
+                } else {
+                	
+                	if(imageType == Image.ORIGINAL_WMF) {
+                		//remove the placeable header                		
+                		bab.write(iod, WMF_PLACEABLE_HEADER_SIZE, iod.length - WMF_PLACEABLE_HEADER_SIZE);
+                	} else {
+                		bab.append(iod);
+                	}
+                	
+                }
+            }
+            
+            return bab.toByteArrayArray();
+            
+        } catch(IOException ioe) {
+            throw new DocumentException(ioe.getMessage());
+        }
+    }
+    
+    
+    /**
+     * lookup table used for converting bytes to hex chars.
+     * TODO Should probably be refactored into a helper class
+     */
+    public final static byte[] byte2charLUT = new byte[512]; //'0001020304050607 ... fafbfcfdfeff'
+    static {
+    	char c = '0';
+    	for(int k = 0; k < 16; k++) {
+    		for(int x = 0; x < 16; x++) {
+				byte2charLUT[((k*16)+x)*2] = byte2charLUT[(((x*16)+k)*2)+1] = (byte)c;
+			}
+    		if(++c == ':') c = 'a';
+		}
+    }
+    
+    /**
+     * Writes the image data to the given buffer as hex encoded text.
+     * 
+     * @param bab
+     * @throws IOException
+     */
+    private void writeImageDataHexEncoded(final OutputStream bab) throws IOException
+    {
+    	int cnt = 0;
+    	for(int k = 0; k < imageData.length; k++) {
+    		final byte[] chunk = imageData[k];
+			for(int x = 0; x < chunk.length; x++) {
+				bab.write(byte2charLUT, (chunk[x]&0xff)*2, 2);
+				if(++cnt == 64) {
+					bab.write('\n');
+					cnt = 0;
+				}
+			}
+		}    	
+   		if(cnt > 0) bab.write('\n');
+    }
+    
+    /**
+     * Returns the image raw data size in bytes.
+     * 
+     * @return the size in bytes
+     */
+    private int imageDataSize()
+    {
+		int size = 0;
+    	for(int k = 0; k < imageData.length; k++) {
+    		size += imageData[k].length;
+    	}   
+    	return size;
+    }
+    
+    /**
+     * Writes the RtfImage content
+     */ 
+    public void writeContent(final OutputStream result) throws IOException
+    {
+    	
+        if(this.topLevelElement) {
+            result.write(RtfParagraph.PARAGRAPH_DEFAULTS);
+            switch(alignment) {
+                case Element.ALIGN_LEFT:
+                    result.write(RtfParagraphStyle.ALIGN_LEFT);
+                    break;
+                case Element.ALIGN_RIGHT:
+                    result.write(RtfParagraphStyle.ALIGN_RIGHT);
+                    break;
+                case Element.ALIGN_CENTER:
+                    result.write(RtfParagraphStyle.ALIGN_CENTER);
+                    break;
+                case Element.ALIGN_JUSTIFIED:
+                    result.write(RtfParagraphStyle.ALIGN_JUSTIFY);
+                    break;
+            }
+        }
+        result.write(OPEN_GROUP);
+        result.write(PICTURE_GROUP);
+        result.write(OPEN_GROUP);
+        result.write(PICTURE);
+        switch(imageType) {
+        	case Image.ORIGINAL_JPEG:
+        	    result.write(PICTURE_JPEG);
+        		break;
+        	case Image.ORIGINAL_PNG:
+            case Image.ORIGINAL_GIF:
+        	    result.write(PICTURE_PNG);
+        		break;
+        	case Image.ORIGINAL_WMF:
+        	case Image.ORIGINAL_BMP:
+        	    result.write(PICTURE_WMF);
+        		break;
+        }
+        result.write(PICTURE_WIDTH);
+        result.write(intToByteArray((int) width));
+        result.write(PICTURE_HEIGHT);
+        result.write(intToByteArray((int) height));
+        if(this.document.getDocumentSettings().isWriteImageScalingInformation()) {
+            result.write(PICTURE_SCALE_X);
+            result.write(intToByteArray((int)(100 * plainWidth / width)));
+            result.write(PICTURE_SCALE_Y);
+            result.write(intToByteArray((int)(100 * plainHeight / height)));
+        }
+        if(this.document.getDocumentSettings().isImagePDFConformance()) {
+            result.write(PICTURE_SCALED_WIDTH);
+            result.write(intToByteArray((int) (plainWidth * RtfElement.TWIPS_FACTOR)));
+            result.write(PICTURE_SCALED_HEIGHT);
+            result.write(intToByteArray((int) (plainHeight * RtfElement.TWIPS_FACTOR)));
+        } else {
+            if(this.width != this.plainWidth || this.imageType == Image.ORIGINAL_BMP) {
+                result.write(PICTURE_SCALED_WIDTH);
+                result.write(intToByteArray((int) (plainWidth * PIXEL_TWIPS_FACTOR)));
+            }
+            if(this.height != this.plainHeight || this.imageType == Image.ORIGINAL_BMP) {
+                result.write(PICTURE_SCALED_HEIGHT);
+                result.write(intToByteArray((int) (plainHeight * PIXEL_TWIPS_FACTOR)));
+            }
+        }
+
+        if(this.document.getDocumentSettings().isImageWrittenAsBinary()) {
+        	//binary
+        	result.write('\n');
+        	result.write(PICTURE_BINARY_DATA);
+        	result.write(intToByteArray(imageDataSize()));
+            result.write(DELIMITER);
+            if(result instanceof RtfByteArrayBuffer) {
+            	((RtfByteArrayBuffer)result).append(imageData);
+            } else {
+            	for(int k = 0; k < imageData.length; k++) {
+					result.write(imageData[k]);
+				}
+            }
+        } else {
+        	//hex encoded
+            result.write(DELIMITER);
+        	result.write('\n');
+        	writeImageDataHexEncoded(result);
+        }
+        
+        result.write(CLOSE_GROUP);
+        result.write(CLOSE_GROUP);
+        if(this.topLevelElement) {
+            result.write(RtfParagraph.PARAGRAPH);
+            result.write(RtfParagraph.PARAGRAPH);
+        }
+        result.write('\n');    	
+    }
+    
+    /**
+     * Sets the alignment of this RtfImage. Uses the alignments from com.lowagie.text.Element.
+     * 
+     * @param alignment The alignment to use.
+     */
+    public void setAlignment(int alignment) {
+        this.alignment = alignment;
+    }
+    
+    /**
+     * Set whether this RtfImage should behave like a top level element
+     * and enclose itself in a paragraph.
+     * 
+     * @param topLevelElement Whether to behave like a top level element.
+     */
+    public void setTopLevelElement(boolean topLevelElement) {
+        this.topLevelElement = topLevelElement;
+    }
+    
+    
+}
Index: src/core/com/lowagie/text/xml/XmlToHtml.java
===================================================================
--- src/core/com/lowagie/text/xml/XmlToHtml.java	(revision 0)
+++ src/core/com/lowagie/text/xml/XmlToHtml.java	(revision 0)
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2002 by Matt Benson.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.xml;
+
+
+import java.io.OutputStream;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+
+import com.lowagie.text.Document;
+import com.lowagie.text.DocumentException;
+import com.lowagie.text.html.HtmlWriter;
+
+
+/**
+ * HTML-specific subclass of <code>XmlToXXX</code>.
+ *
+ * @version 1.0
+ * @author <a href="mailto:orangeherbert@users.sourceforge.net">Matt Benson</a>
+ */
+public class XmlToHtml
+ extends XmlToXXX
+{
+	
+/**
+ * Construct an <CODE>XmlToHtml</CODE> with the default page size.
+ */
+	public XmlToHtml()
+	{
+		super();
+	}//end default constructor
+	
+	
+/**
+ * Construct an <CODE>XmlToHtml</CODE> with the specified page size.
+ * @param pageSize   <CODE>String</CODE> page size name from
+ * <CODE>com.lowagie.text.PageSize</CODE>.
+ */
+	public XmlToHtml(String pageSize)
+	{
+		super(pageSize);
+	}//end constructor(String)
+	
+	
+/**
+ * Add a <CODE>DocWriter</CODE> for the specified <CODE>Document</CODE> and
+ * <CODE>OutputStream</CODE>.
+ * @param doc The document to which content will be added
+ * @param out The outputstream where the HTML will be sent to
+ * @throws DocumentException if document errors occur.
+ */	
+	protected final void addWriter(Document doc, OutputStream out)
+	 throws DocumentException
+	{
+		HtmlWriter.getInstance(doc, out);
+	}//end addWriter
+	
+	
+/**
+ * Main method of the <CODE>XmlToHtml</CODE> class.
+ * @param args   <CODE>String[]</CODE> of command-line arguments.
+ */
+	public static void main(String[] args)
+	{
+		int code = 0;
+		
+		if (args.length > 1)
+		{
+			try
+			{
+				XmlToHtml x;
+				if (args.length > 2)
+				{
+					x = new XmlToHtml(args[2]);
+				}//end if at least 3 args
+				else
+				{
+					x = new XmlToHtml();
+				}//end else, only 2 args
+				
+				x.parse(new FileInputStream(args[0]), new FileOutputStream(args[1]));
+			}//end try to do everything
+			catch (Exception ex)
+			{
+				code = 2;
+				ex.printStackTrace(System.err);
+			}//end catch Exception
+		}//end if at least 2 args
+		else
+		{
+			code = 1;
+			System.err.println(
+			 "Usage:  XmlToHtml [XML file in] [PDF file out] [optional page size]");
+		}//end else, not enough arguments
+		
+		System.exit(code);
+	}//end main
+	
+}//end class XmlToHtml
Index: src/core/com/lowagie/text/rtf/table/RtfRow.java
===================================================================
--- src/core/com/lowagie/text/rtf/table/RtfRow.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/table/RtfRow.java	(revision 0)
@@ -0,0 +1,428 @@
+/*
+ * $Id: RtfRow.java 3735 2009-02-26 01:44:03Z xlv $
+ *
+ * Copyright 2001, 2002, 2003, 2004, 2005 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.rtf.table;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+
+import com.lowagie.text.Cell;
+import com.lowagie.text.DocWriter;
+import com.lowagie.text.Element;
+import com.lowagie.text.Row;
+import com.lowagie.text.pdf.PdfPCell;
+import com.lowagie.text.pdf.PdfPRow;
+import com.lowagie.text.rtf.RtfElement;
+import com.lowagie.text.rtf.document.RtfDocument;
+
+
+/**
+ * The RtfRow wraps one Row for a RtfTable.
+ * INTERNAL USE ONLY
+ * 
+ * @version $Id: RtfRow.java 3735 2009-02-26 01:44:03Z xlv $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Steffen Stundzig
+ * @author Lorenz Maierhofer
+ * @author Thomas Bickel (tmb99@inode.at)
+ */
+public class RtfRow extends RtfElement {
+
+    /**
+     * Constant for the RtfRow beginning
+     */
+    private static final byte[] ROW_BEGIN = DocWriter.getISOBytes("\\trowd");
+    /**
+     * Constant for the RtfRow width style
+     */
+    private static final byte[] ROW_WIDTH_STYLE = DocWriter.getISOBytes("\\trftsWidth3");
+    /**
+     * Constant for the RtfRow width
+     */
+    private static final byte[] ROW_WIDTH = DocWriter.getISOBytes("\\trwWidth");
+    /**
+     * Constant to specify that this RtfRow are not to be broken across pages
+     */
+    private static final byte[] ROW_KEEP_TOGETHER = DocWriter.getISOBytes("\\trkeep");
+    /**
+     * Constant to specify that this is a header RtfRow
+     */
+    private static final byte[] ROW_HEADER_ROW = DocWriter.getISOBytes("\\trhdr");
+    /**
+     * Constant for left alignment of this RtfRow
+     */
+    private static final byte[] ROW_ALIGN_LEFT = DocWriter.getISOBytes("\\trql");
+    /**
+     * Constant for right alignment of this RtfRow
+     */
+    private static final byte[] ROW_ALIGN_RIGHT = DocWriter.getISOBytes("\\trqr");
+    /**
+     * Constant for center alignment of this RtfRow
+     */
+    private static final byte[] ROW_ALIGN_CENTER = DocWriter.getISOBytes("\\trqc");
+    /**
+     * Constant for justified alignment of this RtfRow
+     */
+    private static final byte[] ROW_ALIGN_JUSTIFIED = DocWriter.getISOBytes("\\trqj");
+    /**
+     * Constant for the graph style of this RtfRow
+     */
+    private static final byte[] ROW_GRAPH = DocWriter.getISOBytes("\\trgaph10");
+    /**
+     * Constant for the cell left spacing
+     */
+    private static final byte[] ROW_CELL_SPACING_LEFT = DocWriter.getISOBytes("\\trspdl");
+    /**
+     * Constant for the cell top spacing
+     */
+    private static final byte[] ROW_CELL_SPACING_TOP = DocWriter.getISOBytes("\\trspdt");
+    /**
+     * Constant for the cell right spacing
+     */
+    private static final byte[] ROW_CELL_SPACING_RIGHT = DocWriter.getISOBytes("\\trspdr");
+    /**
+     * Constant for the cell bottom spacing
+     */
+    private static final byte[] ROW_CELL_SPACING_BOTTOM = DocWriter.getISOBytes("\\trspdb");
+    /**
+     * Constant for the cell left spacing style
+     */
+    private static final byte[] ROW_CELL_SPACING_LEFT_STYLE = DocWriter.getISOBytes("\\trspdfl3");
+    /**
+     * Constant for the cell top spacing style
+     */
+    private static final byte[] ROW_CELL_SPACING_TOP_STYLE = DocWriter.getISOBytes("\\trspdft3");
+    /**
+     * Constant for the cell right spacing style
+     */
+    private static final byte[] ROW_CELL_SPACING_RIGHT_STYLE = DocWriter.getISOBytes("\\trspdfr3");
+    /**
+     * Constant for the cell bottom spacing style
+     */
+    private static final byte[] ROW_CELL_SPACING_BOTTOM_STYLE = DocWriter.getISOBytes("\\trspdfb3");
+    /**
+     * Constant for the cell left padding
+     */
+    private static final byte[] ROW_CELL_PADDING_LEFT = DocWriter.getISOBytes("\\trpaddl");
+    /**
+     * Constant for the cell right padding
+     */
+    private static final byte[] ROW_CELL_PADDING_RIGHT = DocWriter.getISOBytes("\\trpaddr");
+    /**
+     * Constant for the cell left padding style
+     */
+    private static final byte[] ROW_CELL_PADDING_LEFT_STYLE = DocWriter.getISOBytes("\\trpaddfl3");
+    /**
+     * Constant for the cell right padding style
+     */
+    private static final byte[] ROW_CELL_PADDING_RIGHT_STYLE = DocWriter.getISOBytes("\\trpaddfr3");
+    /**
+     * Constant for the end of a row
+     */
+    private static final byte[] ROW_END = DocWriter.getISOBytes("\\row");
+
+    /**
+     * The RtfTable this RtfRow belongs to
+     */
+    private RtfTable parentTable = null;
+    /**
+     * The cells of this RtfRow
+     */
+    private ArrayList cells = null;
+    /**
+     * The width of this row
+     */
+    private int width = 0;
+    /**
+     * The row number
+     */
+    private int rowNumber = 0;
+    
+    /**
+     * Constructs a RtfRow for a Row.
+     * 
+     * @param doc The RtfDocument this RtfRow belongs to
+     * @param rtfTable The RtfTable this RtfRow belongs to
+     * @param row The Row this RtfRow is based on
+     * @param rowNumber The number of this row
+     */
+    protected RtfRow(RtfDocument doc, RtfTable rtfTable, Row row, int rowNumber) {
+        super(doc);
+        this.parentTable = rtfTable;
+        this.rowNumber = rowNumber;
+        importRow(row);
+    }
+
+    /**
+     * Constructs a RtfRow for a Row.
+     * 
+     * @param doc The RtfDocument this RtfRow belongs to
+     * @param rtfTable The RtfTable this RtfRow belongs to
+     * @param row The Row this RtfRow is based on
+     * @param rowNumber The number of this row
+     * @since 2.1.3
+     */
+    protected RtfRow(RtfDocument doc, RtfTable rtfTable, PdfPRow row, int rowNumber) {
+        super(doc);
+        this.parentTable = rtfTable;
+        this.rowNumber = rowNumber;
+        importRow(row);
+    }
+    
+
+    /**
+     * Imports a Row and copies all settings
+     * 
+     * @param row The Row to import
+     */
+    private void importRow(Row row) {
+        this.cells = new ArrayList();
+        this.width = this.document.getDocumentHeader().getPageSetting().getPageWidth() - this.document.getDocumentHeader().getPageSetting().getMarginLeft() - this.document.getDocumentHeader().getPageSetting().getMarginRight();
+        this.width = (int) (this.width * this.parentTable.getTableWidthPercent() / 100);
+        
+        int cellRight = 0;
+        int cellWidth = 0;
+        for(int i = 0; i < row.getColumns(); i++) {
+            cellWidth = (int) (this.width * this.parentTable.getProportionalWidths()[i] / 100);
+            cellRight = cellRight + cellWidth;
+            
+            Cell cell = (Cell) row.getCell(i);
+            RtfCell rtfCell = new RtfCell(this.document, this, cell);
+            rtfCell.setCellRight(cellRight);
+            rtfCell.setCellWidth(cellWidth);
+            this.cells.add(rtfCell);
+        }
+    }
+    /**
+     * Imports a PdfPRow and copies all settings
+     * 
+     * @param row The PdfPRow to import
+     * @since 2.1.3
+     */
+    private void importRow(PdfPRow row) {
+        this.cells = new ArrayList();
+        this.width = this.document.getDocumentHeader().getPageSetting().getPageWidth() - this.document.getDocumentHeader().getPageSetting().getMarginLeft() - this.document.getDocumentHeader().getPageSetting().getMarginRight();
+        this.width = (int) (this.width * this.parentTable.getTableWidthPercent() / 100);
+        
+        int cellRight = 0;
+        int cellWidth = 0;
+        PdfPCell[] cells = row.getCells();
+        for(int i = 0; i < cells.length; i++) {
+            cellWidth = (int) (this.width * this.parentTable.getProportionalWidths()[i] / 100);
+            cellRight = cellRight + cellWidth;
+            
+            PdfPCell cell = cells[i];
+            RtfCell rtfCell = new RtfCell(this.document, this, cell);
+            rtfCell.setCellRight(cellRight);
+            rtfCell.setCellWidth(cellWidth);
+            this.cells.add(rtfCell);
+        }
+    }
+    /**
+     * Performs a second pass over all cells to handle cell row/column spanning.
+     */
+    protected void handleCellSpanning() {
+        RtfCell deletedCell = new RtfCell(true);
+        for(int i = 0; i < this.cells.size(); i++) {
+            RtfCell rtfCell = (RtfCell) this.cells.get(i);
+            if(rtfCell.getColspan() > 1) {
+                int cSpan = rtfCell.getColspan();
+                for(int j = i + 1; j < i + cSpan; j++) {
+                    if(j < this.cells.size()) {
+                        RtfCell rtfCellMerge = (RtfCell) this.cells.get(j);
+                        rtfCell.setCellRight(rtfCell.getCellRight() + rtfCellMerge.getCellWidth());
+                        rtfCell.setCellWidth(rtfCell.getCellWidth() + rtfCellMerge.getCellWidth());
+                        this.cells.set(j, deletedCell);
+                    }
+                }
+            }
+            if(rtfCell.getRowspan() > 1) {
+                ArrayList rows = this.parentTable.getRows();
+                for(int j = 1; j < rtfCell.getRowspan(); j++) {
+                    RtfRow mergeRow = (RtfRow) rows.get(this.rowNumber + j);
+                    if(this.rowNumber + j < rows.size()) {
+                        RtfCell rtfCellMerge = (RtfCell) mergeRow.getCells().get(i);
+                        rtfCellMerge.setCellMergeChild(rtfCell);
+                    }
+                    if(rtfCell.getColspan() > 1) {
+                        int cSpan = rtfCell.getColspan();
+                        for(int k = i + 1; k < i + cSpan; k++) {
+                            if(k < mergeRow.getCells().size()) {
+                                mergeRow.getCells().set(k, deletedCell);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Cleans the deleted RtfCells from the total RtfCells.
+     */
+    protected void cleanRow() {
+        int i = 0;
+        while(i < this.cells.size()) {
+            if(((RtfCell) this.cells.get(i)).isDeleted()) {
+                this.cells.remove(i);
+            } else {
+                i++;
+            }
+        }
+    }
+    
+    /**
+     * Writes the row definition/settings.
+     *
+     * @param result The <code>OutputStream</code> to write the definitions to.
+     */
+    private void writeRowDefinition(final OutputStream result) throws IOException {
+        result.write(ROW_BEGIN);
+        this.document.outputDebugLinebreak(result);
+        result.write(ROW_WIDTH_STYLE);
+        result.write(ROW_WIDTH);
+        result.write(intToByteArray(this.width));
+        if(this.parentTable.getCellsFitToPage()) {
+            result.write(ROW_KEEP_TOGETHER);
+        }
+        if(this.rowNumber <= this.parentTable.getHeaderRows()) {
+            result.write(ROW_HEADER_ROW);
+        }
+        switch (this.parentTable.getAlignment()) {
+            case Element.ALIGN_LEFT:
+            	result.write(ROW_ALIGN_LEFT);
+                break;
+            case Element.ALIGN_RIGHT:
+                result.write(ROW_ALIGN_RIGHT);
+                break;
+            case Element.ALIGN_CENTER:
+                result.write(ROW_ALIGN_CENTER);
+                break;
+            case Element.ALIGN_JUSTIFIED:
+            case Element.ALIGN_JUSTIFIED_ALL:
+                result.write(ROW_ALIGN_JUSTIFIED);
+                break;
+        }
+        result.write(ROW_GRAPH);
+        RtfBorderGroup borders =this.parentTable.getBorders();
+        if(borders != null) {
+        	borders.writeContent(result);
+        }
+        
+        if(this.parentTable.getCellSpacing() > 0) {
+            result.write(ROW_CELL_SPACING_LEFT);
+            result.write(intToByteArray((int) (this.parentTable.getCellSpacing() / 2)));
+            result.write(ROW_CELL_SPACING_LEFT_STYLE);
+            result.write(ROW_CELL_SPACING_TOP);
+            result.write(intToByteArray((int) (this.parentTable.getCellSpacing() / 2)));
+            result.write(ROW_CELL_SPACING_TOP_STYLE);
+            result.write(ROW_CELL_SPACING_RIGHT);
+            result.write(intToByteArray((int) (this.parentTable.getCellSpacing() / 2)));
+            result.write(ROW_CELL_SPACING_RIGHT_STYLE);
+            result.write(ROW_CELL_SPACING_BOTTOM);
+            result.write(intToByteArray((int) (this.parentTable.getCellSpacing() / 2)));
+            result.write(ROW_CELL_SPACING_BOTTOM_STYLE);
+        }
+        
+        result.write(ROW_CELL_PADDING_LEFT);
+        result.write(intToByteArray((int) (this.parentTable.getCellPadding() / 2)));
+        result.write(ROW_CELL_PADDING_RIGHT);
+        result.write(intToByteArray((int) (this.parentTable.getCellPadding() / 2)));
+        result.write(ROW_CELL_PADDING_LEFT_STYLE);
+        result.write(ROW_CELL_PADDING_RIGHT_STYLE);
+        
+        this.document.outputDebugLinebreak(result);
+        
+        for(int i = 0; i < this.cells.size(); i++) {
+            RtfCell rtfCell = (RtfCell) this.cells.get(i);
+            rtfCell.writeDefinition(result);
+        }    	
+    }
+    
+    /**
+     * Writes the content of this RtfRow
+     */    
+    public void writeContent(final OutputStream result) throws IOException
+    {
+    	writeRowDefinition(result);
+        
+        for(int i = 0; i < this.cells.size(); i++) {
+            RtfCell rtfCell = (RtfCell) this.cells.get(i);
+            rtfCell.writeContent(result);
+        }
+
+        result.write(DELIMITER);
+
+        if(this.document.getDocumentSettings().isOutputTableRowDefinitionAfter()) {
+        	writeRowDefinition(result);
+        }
+
+        result.write(ROW_END);
+        this.document.outputDebugLinebreak(result);
+    }        
+    
+    /**
+     * Gets the parent RtfTable of this RtfRow
+     * 
+     * @return The parent RtfTable of this RtfRow
+     */
+    protected RtfTable getParentTable() {
+        return this.parentTable;
+    }
+    
+    /**
+     * Gets the cells of this RtfRow
+     * 
+     * @return The cells of this RtfRow
+     */
+    protected ArrayList getCells() {
+        return this.cells;
+    }
+}
Index: src/core/com/lowagie/text/rtf/RtfExtendedElement.java
===================================================================
--- src/core/com/lowagie/text/rtf/RtfExtendedElement.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/RtfExtendedElement.java	(revision 0)
@@ -0,0 +1,71 @@
+/*
+ * $Id: RtfExtendedElement.java 3373 2008-05-12 16:21:24Z xlv $
+ *
+ * Copyright 2001, 2002, 2003, 2004 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.rtf;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * The RtfExtendedElement interface is to be used for elements that also
+ * write data into the definition part of the rtf document
+ * 
+ * @version $Id: RtfExtendedElement.java 3373 2008-05-12 16:21:24Z xlv $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Thomas Bickel (tmb99@inode.at)
+ */
+public interface RtfExtendedElement extends RtfBasicElement
+{
+    /**
+     * Write the definition part of the element
+     * 
+     * @param out The <code>OutputStream</code> to write the element definition to
+     */
+    public void writeDefinition(OutputStream out) throws IOException;
+}
Index: src/core/com/lowagie/text/xml/XmlToXXX.java
===================================================================
--- src/core/com/lowagie/text/xml/XmlToXXX.java	(revision 0)
+++ src/core/com/lowagie/text/xml/XmlToXXX.java	(revision 0)
@@ -0,0 +1,147 @@
+/*
+ * Copyright 2002 by Matt Benson.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.xml;
+
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import com.lowagie.text.Document;
+import com.lowagie.text.PageSize;
+import com.lowagie.text.Rectangle;
+import com.lowagie.text.DocumentException;
+
+
+/**
+ * Generates an specific file from an iText XML file.
+ *
+ * @version 1.0
+ * @author <a href="mailto:orangeherbert@users.sourceforge.net">Matt Benson</a>
+ */
+public abstract class XmlToXXX
+{
+	
+	protected Rectangle pageSize;
+	
+	
+/**
+ * Construct an <CODE>XmlToXXX</CODE> with the default page size.
+ */
+	public XmlToXXX()
+	{
+		this(PageSize.LETTER);
+	}//end default constructor
+	
+	
+/**
+ * Construct an <CODE>XmlToXXX</CODE> with the specified page size.
+ * @param pageSize   <CODE>String</CODE> page size name from
+ * <CODE>com.lowagie.text.PageSize</CODE>.
+ */
+	public XmlToXXX(String pageSize)
+	{
+		this(getPageSize(pageSize));
+	}//end constructor(String)
+	
+	
+	private XmlToXXX(Rectangle pageSize)
+	{
+		this.pageSize = pageSize;
+	}//end constructor(Rectangle)
+	
+	
+/**
+ * Parse the XML from the specified <CODE>InputStream</CODE>, writing to the
+ * specified <CODE>OutputStream</CODE>.
+ * @param in    the <CODE>InputStream</CODE> from which the XML is read.
+ * @param out   the <CODE>OutputStream</CODE> to which the result is written.
+ * @throws DocumentException if document errors occur.
+ */
+	public final void parse(InputStream in, OutputStream out)
+	 throws DocumentException
+	{
+		Document doc = new Document(pageSize);
+
+		addWriter(doc, out);
+		XmlParser.parse(doc, in);
+	}//end parse
+	
+	
+	private static Rectangle getPageSize(String pageSize)
+	{
+		Rectangle result = PageSize.LETTER;
+		Field fld = null;
+		try
+		{
+			fld = PageSize.class.getDeclaredField(pageSize.toUpperCase());
+			result = (fld != null
+			 && Modifier.isStatic(fld.getModifiers())
+			 && fld.getType().equals(Rectangle.class)) ? (Rectangle)(fld.get(null))
+			 : result;
+		}//end try to get field
+		catch (Exception ex)
+		{
+			System.err.println(ex.getMessage());
+		}//end catch Exception
+		return result;
+	}//end getPageSize
+	
+
+/**
+ * Add a <CODE>DocWriter</CODE> for the specified <CODE>Document</CODE> and
+ * <CODE>OutputStream</CODE>.
+ * @param doc The document to which content will be added
+ * @param out The outputstream to which the document will be sent
+ * @throws DocumentException if document errors occur.
+ */	
+	protected abstract void addWriter(Document doc, OutputStream out)
+	 throws DocumentException;
+	
+}//end class XmlToXXX
Index: src/core/com/lowagie/text/rtf/parser/destinations/RtfDestinationColorTable.java
===================================================================
--- src/core/com/lowagie/text/rtf/parser/destinations/RtfDestinationColorTable.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/parser/destinations/RtfDestinationColorTable.java	(revision 0)
@@ -0,0 +1,319 @@
+/*
+ * $Id: RtfDestinationColorTable.java 3373 2008-05-12 16:21:24Z xlv $
+ *
+ * Copyright 2007 by Howard Shank (hgshank@yahoo.com)
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+package com.lowagie.text.rtf.parser.destinations;
+
+import java.awt.Color;
+import java.util.HashMap;
+
+import com.lowagie.text.rtf.parser.RtfImportMgr;
+import com.lowagie.text.rtf.parser.RtfParser;
+import com.lowagie.text.rtf.parser.ctrlwords.RtfCtrlWordData;
+import com.lowagie.text.rtf.parser.enumerations.RtfColorThemes;
+
+/**
+ * <code>RtfDestinationColorTable</code> handles data destined for the color table destination
+ * 
+ * @author Howard Shank (hgshank@yahoo.com)
+ * 
+ * @since 2.0.8
+ */
+public class RtfDestinationColorTable extends RtfDestination  {
+
+	/**
+	 * The RtfImportHeader to add color mappings to.
+	 */
+	private RtfImportMgr importHeader = null;
+	/**
+	 * The number of the current color being parsed.
+	 */
+	private int colorNr = 0;
+	/**
+	 * The red component of the current color being parsed.
+	 */
+	private int red = -1;
+	/**
+	 * The green component of the current color being parsed.
+	 */
+	private int green = -1;
+	/**
+	 * The blue component of the current color being parsed.
+	 */
+	private int blue = -1;
+	/*
+	 * Color themes - Introduced Word 2007
+	 */
+	/**
+	 * Specifies the tint when specifying a theme color.
+	 * RTF control word ctint
+	 * 
+	 * 0 - 255: 0 = full tint(white), 255 = no tint. 
+	 * Default value: 255
+	 * 
+	 * If tint is specified and is less than 255, cshade must equal 255.
+	 * ctint/cshade are mutually exclusive
+	 * 
+	 * @see com.lowagie.text.rtf.parser.destinations.RtfDestinationColorTable#cshade
+	 * @see com.lowagie.text.rtf.parser.destinations.RtfDestinationColorTable#themeColor
+	 */
+	private int ctint = 255;
+	/**
+	 * Specifies the shade when specifying a theme color.
+	 * RTF control word cshade
+	 * 
+	 * 0 - 255: 0 = full shade(black), 255 = no shade. 
+	 * Default value: 255
+	 * 
+	 * If shade is specified and is less than 255, ctint must equal 255.
+	 * cshade/ctint are mutually exclusive
+	 * 
+	 * @see com.lowagie.text.rtf.parser.destinations.RtfDestinationColorTable#ctint
+	 * @see com.lowagie.text.rtf.parser.destinations.RtfDestinationColorTable#themeColor
+	 */
+	private int cshade = 255;
+	/**
+	 * Specifies the use of a theme color.
+	 * 
+	 * @see com.lowagie.text.rtf.parser.enumerations.RtfColorThemes
+	 * @see com.lowagie.text.rtf.parser.destinations.RtfDestinationColorTable#ctint
+	 * @see com.lowagie.text.rtf.parser.destinations.RtfDestinationColorTable#cshade
+	 */
+	private int themeColor = RtfColorThemes.THEME_UNDEFINED;
+	/**
+	 * Color map object for conversions
+	 */
+	private HashMap colorMap = null;
+	
+	/**
+	 * Constructor.
+	 */
+	public RtfDestinationColorTable() {
+		super(null);
+		colorMap = new HashMap();
+		this.colorNr = 0;
+	}
+	
+	/**
+	 * Constructs a new RtfColorTableParser.
+	 * 
+	 * @param parser an RtfParser
+	 */
+	public RtfDestinationColorTable(RtfParser parser) {
+		super(parser);
+		colorMap = new HashMap();
+		this.colorNr = 0;
+		this.importHeader = parser.getImportManager();
+		this.setToDefaults();
+	}
+	
+	public void setParser(RtfParser parser) {
+		this.rtfParser = parser;
+		colorMap = new HashMap();
+		this.colorNr = 0;
+		this.importHeader = parser.getImportManager();
+		this.setToDefaults();
+	}
+	/* (non-Javadoc)
+	 * @see com.lowagie.text.rtf.parser.destinations.RtfDestination#handleOpenNewGroup()
+	 */
+	public boolean handleOpeningSubGroup() {
+		return true;
+	}
+
+	public boolean closeDestination() {
+		return true;
+	}
+
+	public boolean handleCloseGroup() {
+		processColor();
+		return true;
+	}
+	public boolean handleOpenGroup() {
+		return true;
+	}
+	
+	public boolean handleCharacter(int ch) {
+		// color elements end with a semicolon (;)
+		if(ch == ';') {
+			this.processColor();
+		}
+		return true;
+	}
+	
+	public boolean handleControlWord(RtfCtrlWordData ctrlWordData) {
+		if(ctrlWordData.ctrlWord.equals("blue")) this.setBlue(ctrlWordData.intValue());
+		if(ctrlWordData.ctrlWord.equals("red")) this.setRed(ctrlWordData.intValue());
+		if(ctrlWordData.ctrlWord.equals("green")) this.setGreen(ctrlWordData.intValue());
+		if(ctrlWordData.ctrlWord.equals("cshade")) this.setShade(ctrlWordData.intValue());
+		if(ctrlWordData.ctrlWord.equals("ctint")) this.setTint(ctrlWordData.intValue());
+		//if(ctrlWordData.ctrlWord.equals("cmaindarkone")) this.setThemeColor(ctrlWordData.ctrlWord);
+		//if(ctrlWordData.ctrlWord.equals("cmainlightone")) this.setThemeColor(ctrlWordData.ctrlWord);
+		//if(ctrlWordData.ctrlWord.equals("cmaindarktwo")) this.setThemeColor(ctrlWordData.ctrlWord);
+		//if(ctrlWordData.ctrlWord.equals("cmainlighttwo")) this.setThemeColor(ctrlWordData.ctrlWord);
+		//if(ctrlWordData.ctrlWord.equals("caccentone")) this.setThemeColor(ctrlWordData.ctrlWord);
+		//if(ctrlWordData.ctrlWord.equals("caccenttwo")) this.setThemeColor(ctrlWordData.ctrlWord);
+		//if(ctrlWordData.ctrlWord.equals("caccentthree")) this.setThemeColor(ctrlWordData.ctrlWord);
+		//if(ctrlWordData.ctrlWord.equals("caccentfour")) this.setThemeColor(ctrlWordData.ctrlWord);
+		//if(ctrlWordData.ctrlWord.equals("caccentfive")) this.setThemeColor(ctrlWordData.ctrlWord);
+		//if(ctrlWordData.ctrlWord.equals("caccentsix")) this.setThemeColor(ctrlWordData.ctrlWord);
+		//if(ctrlWordData.ctrlWord.equals("chyperlink")) this.setThemeColor(ctrlWordData.ctrlWord);
+		//if(ctrlWordData.ctrlWord.equals("cfollowedhyperlink")) this.setThemeColor(ctrlWordData.ctrlWord);
+		//if(ctrlWordData.ctrlWord.equals("cbackgroundone")) this.setThemeColor(ctrlWordData.ctrlWord);
+		//if(ctrlWordData.ctrlWord.equals("ctextone")) this.setThemeColor(ctrlWordData.ctrlWord);
+		//if(ctrlWordData.ctrlWord.equals("cbacgroundtwo")) this.setThemeColor(ctrlWordData.ctrlWord);
+		//if(ctrlWordData.ctrlWord.equals("ctexttwo")) this.setThemeColor(ctrlWordData.ctrlWord);
+	return true;
+	}
+	
+	/**
+	 * Set default values.
+	 */
+	public void setToDefaults() {
+		this.red = -1;
+		this.green = -1;
+		this.blue = -1;
+		this.ctint = 255;
+		this.cshade = 255;
+		this.themeColor = RtfColorThemes.THEME_UNDEFINED;
+		// do not reset colorNr
+	}
+	/**
+	 * Processes the color triplet parsed from the document.
+	 * Add it to the import mapping so colors can be mapped when encountered
+	 * in the RTF import or conversion.
+	 */
+	private void processColor() {
+		if(red != -1 && green != -1 && blue != -1) {
+			if(this.rtfParser.isImport()) {
+				this.importHeader.importColor(Integer.toString(this.colorNr), new Color(this.red, this.green, this.blue));
+			}
+		
+			if(this.rtfParser.isConvert()) {
+				colorMap.put(Integer.toString(this.colorNr), new Color(this.red, this.green, this.blue));
+			}
+		}
+		this.setToDefaults();
+		this.colorNr++;
+	}
+	/**
+	 * Set the red color to value.
+	 * @param value Value to set red to.
+	 */
+	private void setRed(int value) {
+		if(value >= 0 && value <= 255) {
+			this.red = value;
+		}
+	}
+	/**
+	 * Set the green color value.
+	 * @param value Value to set green to.
+	 */
+	private void setGreen(int value) {
+		if(value >= 0 && value <= 255) {
+			this.green = value;
+		}
+	}
+	/**
+	 * Set the blue color value.
+	 * @param value Value to set blue to.
+	 */
+	private void setBlue(int value) {
+		if(value >= 0 && value <= 255) {
+			this.blue = value;
+		}
+	}
+	/**
+	 * Set the tint value
+	 * @param value Value to set the tint to
+	 * @see com.lowagie.text.rtf.parser.destinations.RtfDestinationColorTable#ctint
+	 */
+	private void setTint(int value) {
+		if(value >= 0 && value <= 255) {
+			this.ctint = value;
+			if(value >= 0 && value <255) {
+				this.cshade = 255;
+			}
+		}
+	}
+	/**
+	 * Set the shade value
+	 * @param value Value to set the shade to
+	 * @see com.lowagie.text.rtf.parser.destinations.RtfDestinationColorTable#cshade
+	 */
+	private void setShade(int value) {
+		if(value >= 0 && value <= 255) {
+			this.cshade = value;
+			if(value >= 0 && value <255) {
+				this.ctint = 255;
+			}
+		}
+	}
+	/**
+	 * Set the theme color value.
+	 * @param value Value to set the theme color to
+	 * @see com.lowagie.text.rtf.parser.enumerations.RtfColorThemes
+	 */
+	private void setThemeColor(int value) {
+		if(value >= RtfColorThemes.THEME_UNDEFINED && value <= RtfColorThemes.THEME_MAX) {
+			this.themeColor = value;
+		} else {
+			this.themeColor = RtfColorThemes.THEME_UNDEFINED;
+		}
+	}
+	
+	// conversion functions
+	/**
+	 * Get the <code>Color</code> object that is mapped to the key.
+	 * @param key The map number.
+	 * *@return <code>Color</code> object from the map. null if key does not exist.
+	 */
+	public Color getColor(String key) {
+		return (Color)colorMap.get(key);
+	}
+	
+}
Index: src/core/com/lowagie/text/rtf/RtfBasicElement.java
===================================================================
--- src/core/com/lowagie/text/rtf/RtfBasicElement.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/RtfBasicElement.java	(revision 0)
@@ -0,0 +1,116 @@
+/*
+ * $Id: RtfBasicElement.java 3580 2008-08-06 15:52:00Z howard_s $
+ *
+ * Copyright 2001, 2002, 2003, 2004 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.rtf;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import com.lowagie.text.DocWriter;
+import com.lowagie.text.RtfElementInterface;
+import com.lowagie.text.rtf.document.RtfDocument;
+
+/**
+ * The RtfBasicElement interface defines the interface for elements that can
+ * be added to the RtfWriter.
+ *
+ * @version $Id: RtfBasicElement.java 3580 2008-08-06 15:52:00Z howard_s $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Thomas Bickel (tmb99@inode.at)
+ */
+public interface RtfBasicElement extends RtfElementInterface {
+    /**
+     * Constant for the beginning of a rtf group
+     */
+    public static final byte[] OPEN_GROUP = DocWriter.getISOBytes("{");
+    /**
+     * Constant for the end of an rtf group
+     */
+    public static final byte[] CLOSE_GROUP = DocWriter.getISOBytes("}");
+    /**
+     * Constant for a delimiter in rtf
+     */
+    public static final byte[] DELIMITER = DocWriter.getISOBytes(" ");
+    /**
+     * Constant for a comma delimiter in rtf
+     */
+    public static final byte[] COMMA_DELIMITER = DocWriter.getISOBytes(";");
+    /**
+     * The factor to use for translating from iText to rtf measurements
+     */
+    public static final double TWIPS_FACTOR = 20;
+
+    /**
+     * Writes the element content to the given output stream.
+     * 
+     * @param out The <code>OutputStream</code> to write the content to
+     */
+    public void writeContent(OutputStream out) throws IOException;
+    
+    /**
+     * Sets the RtfDocument this RtfElement belongs to
+     * 
+     * @param doc The @link{com.lowagie.text.rtf.document.RtfDocument} this <code>RtfElement</code> belongs to
+     */
+    public void setRtfDocument(RtfDocument doc);
+    
+    /**
+     * Sets whether this RtfBasicElement is in a table
+     * 
+     * @param inTable Whether this RtfBasicElement is in a table
+     */
+    public void setInTable(boolean inTable);
+    
+    /**
+     * Sets whether this RtfBasicElement is in a header
+     * 
+     * @param inHeader Whether this RtfBasicElement is in a header
+     */
+    public void setInHeader(boolean inHeader);
+}
Index: src/core/com/lowagie/text/rtf/table/RtfCell.java
===================================================================
--- src/core/com/lowagie/text/rtf/table/RtfCell.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/table/RtfCell.java	(revision 0)
@@ -0,0 +1,708 @@
+/*
+ * $Id: RtfCell.java 3580 2008-08-06 15:52:00Z howard_s $
+ *
+ * Copyright 2001, 2002, 2003, 2004 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.rtf.table;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import com.lowagie.text.BadElementException;
+import com.lowagie.text.Cell;
+import com.lowagie.text.DocWriter;
+import com.lowagie.text.DocumentException;
+import com.lowagie.text.Element;
+import com.lowagie.text.Image;
+import com.lowagie.text.List;
+import com.lowagie.text.Paragraph;
+import com.lowagie.text.Phrase;
+import com.lowagie.text.pdf.PdfPCell;
+import com.lowagie.text.pdf.PdfPTable;
+import com.lowagie.text.rtf.RtfBasicElement;
+import com.lowagie.text.rtf.RtfExtendedElement;
+import com.lowagie.text.rtf.document.RtfDocument;
+import com.lowagie.text.rtf.style.RtfColor;
+import com.lowagie.text.rtf.style.RtfParagraphStyle;
+import com.lowagie.text.rtf.text.RtfParagraph;
+
+
+/**
+ * The RtfCell wraps a Cell, but can also be added directly to a Table.
+ * The RtfCell is an extension of Cell, that supports a multitude of different
+ * borderstyles.
+ * 
+ * @version $Id: RtfCell.java 3580 2008-08-06 15:52:00Z howard_s $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Steffen Stundzig
+ * @author Benoit Wiart
+ * @author Thomas Bickel (tmb99@inode.at)
+ * @see com.lowagie.text.rtf.table.RtfBorder
+ */
+public class RtfCell extends Cell implements RtfExtendedElement {
+
+    /**
+     * This cell is not merged
+     */
+    private static final int MERGE_NONE = 0;
+    /**
+     * This cell is the parent cell of a vertical merge operation
+     */
+    private static final int MERGE_VERT_PARENT = 1;
+    /**
+     * This cell is a child cell of a vertical merge operation
+     */
+    private static final int MERGE_VERT_CHILD = 2;
+
+    /**
+     * The parent RtfRow of this RtfCell
+     */
+    private RtfRow parentRow = null;
+    /**
+     * The content of this RtfCell
+     */
+    private ArrayList content = null;
+    /**
+     * The right margin of this RtfCell
+     */
+    private int cellRight = 0;
+    /**
+     * The width of this RtfCell
+     */
+    private int cellWidth = 0;
+    /**
+     * The borders of this RtfCell
+     */
+    private RtfBorderGroup borders = null;
+    
+    /**
+     * The background color of this RtfCell
+     */
+    private RtfColor backgroundColor = null;
+    /**
+     * The padding of this RtfCell
+     */
+    private int cellPadding = 0;
+    /**
+     * The merge type of this RtfCell
+     */
+    private int mergeType = MERGE_NONE;
+    /**
+     * The RtfDocument this RtfCell belongs to
+     */
+    private RtfDocument document = null;
+    /**
+     * Whether this RtfCell is in a header
+     */
+    private boolean inHeader = false;
+    /**
+     * Whether this RtfCell is a placeholder for a removed table cell.
+     */
+    private boolean deleted = false;
+
+    /**
+     * Whether to use generic padding or individual 
+     * padding values (cellPaddingLeft, cellPaddingTop, cellPaddingBottom, cellPaddingRight)
+     */
+    private boolean usePadding = false;
+    /*
+     * Cell padding left
+     */
+    private float cellPaddingLeft = 0;
+    /*
+     * Cell padding top
+     */
+    private float cellPaddingTop = 0;
+    /*
+     * Cell padding bottom
+     */
+    private float cellPaddingBottom = 0;
+    /*
+     * Cell padding right
+     */
+    private float cellPaddingRight = 0;
+
+    /**
+     * Constructs an empty RtfCell
+     */
+    public RtfCell() {
+        super();
+        this.borders = new RtfBorderGroup();
+        verticalAlignment = ALIGN_MIDDLE;
+    }
+    
+    /**
+     * Constructs a RtfCell based upon a String
+     * 
+     * @param content The String to base the RtfCell on
+     */
+    public RtfCell(String content) {
+        super(content);
+        this.borders = new RtfBorderGroup();
+        verticalAlignment = ALIGN_MIDDLE;
+    }
+    
+    /**
+     * Constructs a RtfCell based upon an Element
+     * 
+     * @param element The Element to base the RtfCell on
+     * @throws BadElementException If the Element is not valid
+     */
+    public RtfCell(Element element) throws BadElementException {
+        super(element);
+        this.borders = new RtfBorderGroup();
+        verticalAlignment = ALIGN_MIDDLE;
+    }
+    
+    /**
+     * Constructs a deleted RtfCell.
+     * 
+     * @param deleted Whether this RtfCell is actually deleted.
+     */
+    protected RtfCell(boolean deleted) {
+        super();
+        this.deleted = deleted;
+        verticalAlignment = ALIGN_MIDDLE;
+    }
+    
+    /**
+     * Constructs a RtfCell based on a Cell.
+     * 
+     * @param doc The RtfDocument this RtfCell belongs to
+     * @param row The RtfRow this RtfCell lies in
+     * @param cell The Cell to base this RtfCell on
+     */
+    protected RtfCell(RtfDocument doc, RtfRow row, Cell cell) {
+        this.document = doc;
+        this.parentRow = row;
+        importCell(cell);
+    }
+    
+    /**
+     * Constructs a RtfCell based on a Cell.
+     * 
+     * @param doc The RtfDocument this RtfCell belongs to
+     * @param row The RtfRow this RtfCell lies in
+     * @param cell The PdfPCell to base this RtfCell on
+     * @since 2.1.3
+     */
+    protected RtfCell(RtfDocument doc, RtfRow row, PdfPCell cell) {
+        this.document = doc;
+        this.parentRow = row;
+        importCell(cell);
+    }
+    /**
+     * Imports the Cell properties into the RtfCell
+     * 
+     * @param cell The Cell to import
+     */
+    private void importCell(Cell cell) {
+        this.content = new ArrayList();
+        
+        if(cell == null) {
+            this.borders = new RtfBorderGroup(this.document, RtfBorder.CELL_BORDER, this.parentRow.getParentTable().getBorders());
+            return;
+        }
+        
+        this.colspan = cell.getColspan();
+        this.rowspan = cell.getRowspan();
+        if(cell.getRowspan() > 1) {
+            this.mergeType = MERGE_VERT_PARENT;
+        }
+        if(cell instanceof RtfCell) {
+            this.borders = new RtfBorderGroup(this.document, RtfBorder.CELL_BORDER, ((RtfCell) cell).getBorders());
+        } else {
+            this.borders = new RtfBorderGroup(this.document, RtfBorder.CELL_BORDER, cell.getBorder(), cell.getBorderWidth(), cell.getBorderColor());
+        }
+        this.verticalAlignment = cell.getVerticalAlignment();
+        if(cell.getBackgroundColor() == null) {
+            this.backgroundColor = new RtfColor(this.document, 255, 255, 255);
+        } else {
+            this.backgroundColor = new RtfColor(this.document, cell.getBackgroundColor());
+        }
+        
+        this.cellPadding = (int) this.parentRow.getParentTable().getCellPadding();
+        
+        Iterator cellIterator = cell.getElements();
+        Paragraph container = null;
+        while(cellIterator.hasNext()) {
+            try {
+                Element element = (Element) cellIterator.next();
+                // should we wrap it in a paragraph
+                if(!(element instanceof Paragraph) && !(element instanceof List)) {
+                    if(container != null) {
+                        container.add(element);
+                    } else {
+                        container = new Paragraph();
+                        container.setAlignment(cell.getHorizontalAlignment());
+                        container.add(element);
+                    }
+                } else {
+                    if(container != null) {
+                        RtfBasicElement[] rtfElements = this.document.getMapper().mapElement(container);
+                        for(int i = 0; i < rtfElements.length; i++) {
+                            rtfElements[i].setInTable(true);
+                            this.content.add(rtfElements[i]);
+                        }
+                        container = null;
+                    }
+                    // if horizontal alignment is undefined overwrite
+                    // with that of enclosing cell
+                    if (element instanceof Paragraph && ((Paragraph) element).getAlignment() == Element.ALIGN_UNDEFINED) {
+                        ((Paragraph) element).setAlignment(cell.getHorizontalAlignment());
+                    }
+
+                    RtfBasicElement[] rtfElements = this.document.getMapper().mapElement(element);
+                    for(int i = 0; i < rtfElements.length; i++) {
+                        rtfElements[i].setInTable(true);
+                        this.content.add(rtfElements[i]);
+                    }
+                }
+            } catch(DocumentException de) {
+                de.printStackTrace();
+            }
+        }
+        if(container != null) {
+            try {
+                RtfBasicElement[] rtfElements = this.document.getMapper().mapElement(container);
+                for(int i = 0; i < rtfElements.length; i++) {
+                    rtfElements[i].setInTable(true);
+                    this.content.add(rtfElements[i]);
+                }
+            } catch(DocumentException de) {
+                de.printStackTrace();
+            }
+        }
+    }
+    /**
+     * Imports the Cell properties into the RtfCell
+     * 
+     * @param cell The PdfPCell to import
+     * @since 2.1.3
+     */
+    private void importCell(PdfPCell cell) {
+        this.content = new ArrayList();
+        
+        if(cell == null) {
+            this.borders = new RtfBorderGroup(this.document, RtfBorder.CELL_BORDER, this.parentRow.getParentTable().getBorders());
+            return;
+        }
+        
+        // padding
+        this.cellPadding = (int) this.parentRow.getParentTable().getCellPadding();
+        this.cellPaddingBottom = cell.getPaddingBottom();
+        this.cellPaddingTop = cell.getPaddingTop();
+        this.cellPaddingRight = cell.getPaddingRight();
+        this.cellPaddingLeft = cell.getPaddingLeft();
+        
+        // BORDERS
+        this.borders = new RtfBorderGroup(this.document, RtfBorder.CELL_BORDER, cell.getBorder(), cell.getBorderWidth(), cell.getBorderColor());
+
+        // border colors
+        this.border = cell.getBorder();
+        this.borderColor = cell.getBorderColor();
+        this.borderColorBottom = cell.getBorderColorBottom();
+        this.borderColorTop = cell.getBorderColorTop();
+        this.borderColorLeft = cell.getBorderColorLeft();
+        this.borderColorRight = cell.getBorderColorRight();
+        
+        // border widths
+        this.borderWidth = cell.getBorderWidth();
+        this.borderWidthBottom = cell.getBorderWidthBottom();
+        this.borderWidthTop = cell.getBorderWidthTop();
+        this.borderWidthLeft = cell.getBorderWidthLeft();
+        this.borderWidthRight = cell.getBorderWidthRight();
+        
+       
+        this.colspan = cell.getColspan();
+        this.rowspan = 1; //cell.getRowspan();
+//        if(cell.getRowspan() > 1) {
+//            this.mergeType = MERGE_VERT_PARENT;
+//        }
+
+        
+        this.verticalAlignment = cell.getVerticalAlignment();
+        
+        if(cell.getBackgroundColor() == null) {
+            this.backgroundColor = new RtfColor(this.document, 255, 255, 255);
+        } else {
+            this.backgroundColor = new RtfColor(this.document, cell.getBackgroundColor());
+        }
+        
+        
+        // does it have column composite info?
+        java.util.List compositeElements = cell.getCompositeElements();
+        if(compositeElements != null) {
+	        Iterator cellIterator = compositeElements.iterator();
+	        // does it have column info?
+	        Paragraph container = null;
+	        while(cellIterator.hasNext()) {
+	            try {
+	                Element element = (Element) cellIterator.next();
+	                // should we wrap it in a paragraph
+	                if(!(element instanceof Paragraph) && !(element instanceof List)) {
+	                    if(container != null) {
+	                        container.add(element);
+	                    } else {
+	                        container = new Paragraph();
+	                        container.setAlignment(cell.getHorizontalAlignment());
+	                        container.add(element);
+	                    }
+	                } else {
+	                    if(container != null) {
+	                        RtfBasicElement[] rtfElements = this.document.getMapper().mapElement(container);
+	                        for(int i = 0; i < rtfElements.length; i++) {
+	                            rtfElements[i].setInTable(true);
+	                            this.content.add(rtfElements[i]);
+	                        }
+	                        container = null;
+	                    }
+	                    // if horizontal alignment is undefined overwrite
+	                    // with that of enclosing cell
+	                    if (element instanceof Paragraph && ((Paragraph) element).getAlignment() == Element.ALIGN_UNDEFINED) {
+	                        ((Paragraph) element).setAlignment(cell.getHorizontalAlignment());
+	                    }
+	
+	                    RtfBasicElement[] rtfElements = this.document.getMapper().mapElement(element);
+	                    for(int i = 0; i < rtfElements.length; i++) {
+	                        rtfElements[i].setInTable(true);
+	                        this.content.add(rtfElements[i]);
+	                    }
+	                }
+	            } catch(DocumentException de) {
+	                de.printStackTrace();
+	            }
+	        }
+	        if(container != null) {
+	            try {
+	                RtfBasicElement[] rtfElements = this.document.getMapper().mapElement(container);
+	                for(int i = 0; i < rtfElements.length; i++) {
+	                    rtfElements[i].setInTable(true);
+	                    this.content.add(rtfElements[i]);
+	                }
+	            } catch(DocumentException de) {
+	                de.printStackTrace();
+	            }
+	        }
+        }
+
+        // does it have image info?
+
+        Image img = cell.getImage();
+        if(img != null) {
+            try {
+				RtfBasicElement[] rtfElements = this.document.getMapper().mapElement(img);
+				for (int i = 0; i < rtfElements.length; i++) {
+					rtfElements[i].setInTable(true);
+					this.content.add(rtfElements[i]);
+				}
+			} catch (DocumentException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+        }
+        // does it have phrase info?
+        Phrase phrase = cell.getPhrase();
+        if(phrase != null) {
+            try {
+				RtfBasicElement[] rtfElements = this.document.getMapper().mapElement(phrase);
+				for (int i = 0; i < rtfElements.length; i++) {
+					rtfElements[i].setInTable(true);
+					this.content.add(rtfElements[i]);
+				}
+			} catch (DocumentException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+        }
+        // does it have table info?
+        PdfPTable table = cell.getTable();
+        if(table != null) {
+        	this.add(table);
+//            try {
+//				RtfBasicElement[] rtfElements = this.document.getMapper().mapElement(table);
+//				for (int i = 0; i < rtfElements.length; i++) {
+//					rtfElements[i].setInTable(true);
+//					this.content.add(rtfElements[i]);
+//				}
+//			} catch (DocumentException e) {
+//				// TODO Auto-generated catch block
+//				e.printStackTrace();
+//			}
+        }
+
+    }
+    /**
+	 * Write the cell definition part of this RtfCell
+	 */
+    public void writeDefinition(final OutputStream result) throws IOException 
+    {
+        if(this.mergeType == MERGE_VERT_PARENT) {
+            result.write(DocWriter.getISOBytes("\\clvmgf"));
+        } else if(this.mergeType == MERGE_VERT_CHILD) {
+            result.write(DocWriter.getISOBytes("\\clvmrg"));
+        }
+        switch (verticalAlignment) {
+            case Element.ALIGN_BOTTOM:
+                result.write(DocWriter.getISOBytes("\\clvertalb"));
+                break;
+            case Element.ALIGN_CENTER:
+            case Element.ALIGN_MIDDLE:
+                result.write(DocWriter.getISOBytes("\\clvertalc"));
+                break;
+            case Element.ALIGN_TOP:
+                result.write(DocWriter.getISOBytes("\\clvertalt"));
+                break;
+        }
+        this.borders.writeContent(result);
+
+        if(this.backgroundColor != null) {
+            result.write(DocWriter.getISOBytes("\\clcbpat"));
+            result.write(intToByteArray(this.backgroundColor.getColorNumber()));
+        }
+        this.document.outputDebugLinebreak(result);
+        
+        result.write(DocWriter.getISOBytes("\\clftsWidth3"));
+        this.document.outputDebugLinebreak(result);
+        
+        result.write(DocWriter.getISOBytes("\\clwWidth"));
+        result.write(intToByteArray(this.cellWidth));
+        this.document.outputDebugLinebreak(result);
+        
+        if(this.cellPadding > 0) {
+            result.write(DocWriter.getISOBytes("\\clpadl"));
+            result.write(intToByteArray(this.cellPadding / 2));
+            result.write(DocWriter.getISOBytes("\\clpadt"));
+            result.write(intToByteArray(this.cellPadding / 2));
+            result.write(DocWriter.getISOBytes("\\clpadr"));
+            result.write(intToByteArray(this.cellPadding / 2));
+            result.write(DocWriter.getISOBytes("\\clpadb"));
+            result.write(intToByteArray(this.cellPadding / 2));
+            result.write(DocWriter.getISOBytes("\\clpadfl3"));
+            result.write(DocWriter.getISOBytes("\\clpadft3"));
+            result.write(DocWriter.getISOBytes("\\clpadfr3"));
+            result.write(DocWriter.getISOBytes("\\clpadfb3"));
+        }
+        result.write(DocWriter.getISOBytes("\\cellx"));
+        result.write(intToByteArray(this.cellRight));
+    }
+
+    
+    /**
+     * Write the content of this RtfCell
+     */    
+    public void writeContent(final OutputStream result) throws IOException
+    {
+        if(this.content.size() == 0) {
+            result.write(RtfParagraph.PARAGRAPH_DEFAULTS);
+            if(this.parentRow.getParentTable().getTableFitToPage()) {
+                result.write(RtfParagraphStyle.KEEP_TOGETHER_WITH_NEXT);
+            }
+            result.write(RtfParagraph.IN_TABLE);
+        } else {
+            for(int i = 0; i < this.content.size(); i++) {
+                RtfBasicElement rtfElement = (RtfBasicElement) this.content.get(i);
+                if(rtfElement instanceof RtfParagraph) {
+                    ((RtfParagraph) rtfElement).setKeepTogetherWithNext(this.parentRow.getParentTable().getTableFitToPage());
+                }
+                rtfElement.writeContent(result);
+                if(rtfElement instanceof RtfParagraph && i < (this.content.size() - 1)) {
+                    result.write(RtfParagraph.PARAGRAPH);
+                }
+            }
+        }
+        result.write(DocWriter.getISOBytes("\\cell"));
+    }        
+
+    /**
+     * Sets the right margin of this cell. Used in merge operations
+     * 
+     * @param cellRight The right margin to use
+     */
+    protected void setCellRight(int cellRight) {
+        this.cellRight = cellRight;
+    }
+    
+    /**
+     * Gets the right margin of this RtfCell
+     * 
+     * @return The right margin of this RtfCell.
+     */
+    protected int getCellRight() {
+        return this.cellRight;
+    }
+    
+    /**
+     * Sets the cell width of this RtfCell. Used in merge operations.
+     * 
+     * @param cellWidth The cell width to use
+     */
+    protected void setCellWidth(int cellWidth) {
+        this.cellWidth = cellWidth;
+    }
+    
+    /**
+     * Gets the cell width of this RtfCell
+     * 
+     * @return The cell width of this RtfCell
+     */
+    protected int getCellWidth() {
+        return this.cellWidth;
+    }
+    
+    /**
+     * Gets the cell padding of this RtfCell
+     * 
+     * @return The cell padding of this RtfCell
+     */
+    protected int getCellpadding() {
+        return this.cellPadding;
+    }
+
+    /**
+     * Gets the borders of this RtfCell
+     * 
+     * @return The borders of this RtfCell
+     */
+    protected RtfBorderGroup getBorders() {
+        return this.borders;
+    }
+    
+    /**
+     * Set the borders of this RtfCell
+     * 
+     * @param borderGroup The RtfBorderGroup to use as borders
+     */
+    public void setBorders(RtfBorderGroup borderGroup) {
+        this.borders = new RtfBorderGroup(this.document, RtfBorder.CELL_BORDER, borderGroup);
+    }
+
+	/**
+     * Get the background color of this RtfCell
+     * 
+     * @return The background color of this RtfCell
+     */
+    protected RtfColor getRtfBackgroundColor() {
+        return this.backgroundColor;
+    }
+
+    /**
+     * Merge this cell into the parent cell.
+     * 
+     * @param mergeParent The RtfCell to merge with
+     */
+    protected void setCellMergeChild(RtfCell mergeParent) {
+        this.mergeType = MERGE_VERT_CHILD;
+        this.cellWidth = mergeParent.getCellWidth();
+        this.cellRight = mergeParent.getCellRight();
+        this.cellPadding = mergeParent.getCellpadding();
+        this.borders = mergeParent.getBorders();
+        this.verticalAlignment = mergeParent.getVerticalAlignment();
+        this.backgroundColor = mergeParent.getRtfBackgroundColor();
+    }
+
+    /**
+     * Sets the RtfDocument this RtfCell belongs to
+     * 
+     * @param doc The RtfDocument to use
+     */
+    public void setRtfDocument(RtfDocument doc) {
+        this.document = doc;
+    }
+    
+    /**
+     * Unused
+     * @param inTable
+     */
+    public void setInTable(boolean inTable) {
+    }
+    
+    /**
+     * Sets whether this RtfCell is in a header
+     * 
+     * @param inHeader <code>True</code> if this RtfCell is in a header, <code>false</code> otherwise
+     */
+    public void setInHeader(boolean inHeader) {
+        this.inHeader = inHeader;
+        for(int i = 0; i < this.content.size(); i++) {
+            ((RtfBasicElement) this.content.get(i)).setInHeader(inHeader);
+        }
+    }
+    
+    /**
+     * Gets whether this <code>RtfCell</code> is in a header
+     * 
+     * @return <code>True</code> if this <code>RtfCell</code> is in a header, <code>false</code> otherwise
+     * @since 2.1.0
+     */
+    public boolean isInHeader() {
+        return this.inHeader;
+    }
+
+    /**
+     * Transforms an integer into its String representation and then returns the bytes
+     * of that string.
+     *
+     * @param i The integer to convert
+     * @return A byte array representing the integer
+     */
+    private byte[] intToByteArray(int i) {
+        return DocWriter.getISOBytes(Integer.toString(i));
+    }
+    
+    /**
+     * Checks whether this RtfCell is a placeholder for
+     * a table cell that has been removed due to col/row spanning.
+     * 
+     * @return <code>True</code> if this RtfCell is deleted, <code>false</code> otherwise.
+     */
+    public boolean isDeleted() {
+        return this.deleted;
+    }
+}
Index: src/core/com/lowagie/text/rtf/parser/destinations/RtfDestinationMgr.java
===================================================================
--- src/core/com/lowagie/text/rtf/parser/destinations/RtfDestinationMgr.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/parser/destinations/RtfDestinationMgr.java	(revision 0)
@@ -0,0 +1,231 @@
+/*
+ * $Id: RtfDestinationMgr.java 3373 2008-05-12 16:21:24Z xlv $
+ *
+ * Copyright 2007 by Howard Shank
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+package com.lowagie.text.rtf.parser.destinations;
+
+import java.util.HashMap;
+
+import com.lowagie.text.rtf.parser.RtfParser;
+
+/**
+ * <code>RtfDestinationMgr</code> manages destination objects for the parser
+ * 
+ * @author Howard Shank (hgshank@yahoo.com)
+ * @since 2.0.8
+ */
+public final class RtfDestinationMgr {
+	/*
+	 * Destinations
+	 */
+	private static RtfDestinationMgr instance = null;
+	private static Object lock = new Object();
+	
+	/**
+	 * CtrlWord <-> Destination map object.
+	 * 
+	 * Maps control words to their destinations objects.
+	 * Null destination is a special destination used for
+	 * discarding unwanted data. This is primarily used when
+	 * skipping groups, binary data or unwanted/unknown data.
+	 */
+	private static HashMap destinations = new HashMap(300, 0.95f);
+	/**
+	 * Destination objects.
+	 * There is only one of each destination.
+	 */
+	private static HashMap destinationObjects = new HashMap(10, 0.95f);
+	
+	private static boolean ignoreUnknownDestinations = false;
+	
+	private static RtfParser rtfParser = null;
+
+	/**
+	 * String representation of null destination.
+	 */
+	public static final String DESTINATION_NULL = "null";
+	/**
+	 * String representation of document destination.
+	 */
+	public static final String DESTINATION_DOCUMENT = "document";
+	
+	/**
+	 * Hidden default constructor becuase
+	 */
+	private RtfDestinationMgr() {
+	}
+	
+	public static void setParser(RtfParser parser) {
+		rtfParser = parser;
+	}
+	public static RtfDestinationMgr getInstance() {
+		synchronized(lock) {
+			if(instance == null) {
+				instance = new RtfDestinationMgr();
+				// 2 required destinations for all documents
+				RtfDestinationMgr.addDestination(RtfDestinationMgr.DESTINATION_DOCUMENT, new Object[] { "RtfDestinationDocument", "" } );
+				RtfDestinationMgr.addDestination(RtfDestinationMgr.DESTINATION_NULL, new Object[] { "RtfDestinationNull", "" } );
+			}
+			return instance;
+		}
+	}
+	public static RtfDestinationMgr getInstance(RtfParser parser) {
+		synchronized(lock) {
+			RtfDestinationMgr.setParser(parser);
+			if(instance == null) {
+				instance = new RtfDestinationMgr();
+				// 2 required destinations for all documents
+				RtfDestinationMgr.addDestination(RtfDestinationMgr.DESTINATION_DOCUMENT, new Object[] { "RtfDestinationDocument", "" } );
+				RtfDestinationMgr.addDestination(RtfDestinationMgr.DESTINATION_NULL, new Object[] { "RtfDestinationNull", "" } );
+			}
+			return instance;
+		}
+	}
+	
+	public static RtfDestination getDestination(String destination) {
+		RtfDestination dest = null;
+		if(destinations.containsKey(destination)) {
+			dest = (RtfDestination)destinations.get(destination);
+		} else {
+			if(ignoreUnknownDestinations) {
+				dest = (RtfDestination)destinations.get(DESTINATION_NULL);
+			} else {
+				dest = (RtfDestination)destinations.get(DESTINATION_DOCUMENT);
+			}
+		}
+		dest.setParser(RtfDestinationMgr.rtfParser);
+		return dest;
+	}
+	
+	public static boolean addDestination(String destination, Object[] args) {
+		if(destinations.containsKey(destination)) {
+			return true;
+		}
+		
+		String thisClass =  "com.lowagie.text.rtf.parser.destinations." + (String)args[0];
+
+		if(thisClass.indexOf("RtfDestinationNull") >= 0) {
+			destinations.put(destination, RtfDestinationNull.getInstance());
+			return true;
+		}
+		
+		Class value = null;
+	
+		try {
+			value = Class.forName(thisClass);
+		} catch (ClassNotFoundException e1) {
+			// TODO Auto-generated catch block
+			e1.printStackTrace();
+			return false;
+		}
+		
+		RtfDestination c = null;
+		
+		if(destinationObjects.containsKey(value.getName())) {
+			c = (RtfDestination)destinationObjects.get(value.getName());		
+		} else {
+			try {
+				c = (RtfDestination)value.newInstance();
+			} catch (InstantiationException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+				return false;
+			} catch (IllegalAccessException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+				return false;
+			}
+		}
+		
+		c.setParser(rtfParser);
+		
+		if(value.isInstance(RtfDestinationInfo.class)) {
+				((RtfDestinationInfo)c).setElementName(destination);
+		}
+		
+		if(value.isInstance(RtfDestinationStylesheetTable.class)) {
+				((RtfDestinationStylesheetTable)c).setElementName(destination);
+				((RtfDestinationStylesheetTable)c).setType((String)args[1]);
+		}
+
+		destinations.put(destination, c);
+		destinationObjects.put(value.getName(), c);
+		return true;
+	}
+	
+	// listener methods
+
+	/**
+	 * Adds a <CODE>RtfDestinationListener</CODE> to the appropriate <CODE>RtfDestination</CODE>.
+	 *
+	 * @param destination the destination string for the listener
+	 * @param listener
+	 *            the new RtfDestinationListener.
+	 */
+	public static boolean addListener(String destination, RtfDestinationListener listener) {
+		RtfDestination dest = getDestination(destination);
+		if(dest != null) {
+			return dest.addListener(listener);
+		}
+		return false;
+	}
+
+	/**
+	 * Removes a <CODE>RtfDestinationListener</CODE> from the appropriate <CODE>RtfDestination</CODE>.
+	 *
+	 * @param destination the destination string for the listener
+	 * @param listener
+	 *            the RtfCtrlWordListener that has to be removed.
+	 */
+	public static boolean removeListener(String destination, RtfDestinationListener listener) {
+		RtfDestination dest = getDestination(destination);
+		if(dest != null) {
+			return dest.removeListener(listener);
+		}
+		return false;
+	}
+}
Index: src/core/com/lowagie/text/rtf/document/RtfProtectionSetting.java
===================================================================
--- src/core/com/lowagie/text/rtf/document/RtfProtectionSetting.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/document/RtfProtectionSetting.java	(revision 0)
@@ -0,0 +1,175 @@
+/*
+ * $Id: RtfProtectionSetting.java 3580 2008-08-06 15:52:00Z howard_s $
+ *
+ * Copyright 2008 by Howard Shank
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.rtf.document;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import com.lowagie.text.DocWriter;
+import com.lowagie.text.rtf.RtfElement;
+
+
+/**
+ * The RtfProtectionSetting handles document protection elements 
+ * 
+ * @version $Id: RtfProtectionSetting.java 3580 2008-08-06 15:52:00Z howard_s $
+ * @author Howard Shank (hgshank@yahoo.com)
+ * @since 2.1.1 
+ */
+public class RtfProtectionSetting extends RtfElement {
+	/**
+	 * Constant for Form protection controlword
+	 * Mutually exclusive
+	 * @see com.lowagie.text.rtf.document.RtfProtectionSetting#REVPROT
+	 * @see com.lowagie.text.rtf.document.RtfProtectionSetting#ANNOTPROT
+	 * @see com.lowagie.text.rtf.document.RtfProtectionSetting#READPROT
+	 * @since 2.1.1 
+	 */
+    private static final byte[] FORMPROT = DocWriter.getISOBytes("\\formprot");
+	/**
+	 * Constant for Revision protection controlword
+	 * Mutually exclusive
+	 * @see com.lowagie.text.rtf.document.RtfProtectionSetting#FORMPROT
+	 * @see com.lowagie.text.rtf.document.RtfProtectionSetting#ANNOTPROT
+	 * @see com.lowagie.text.rtf.document.RtfProtectionSetting#READPROT
+	 * @since 2.1.1
+	 */
+    private static final byte[] REVPROT = DocWriter.getISOBytes("\\revprot");
+	/**
+	 * Constant for Annotation/Comment protection controlword
+	 * Mutually exclusive
+	 * @see com.lowagie.text.rtf.document.RtfProtectionSetting#FORMPROT
+	 * @see com.lowagie.text.rtf.document.RtfProtectionSetting#REVPROT
+	 * @see com.lowagie.text.rtf.document.RtfProtectionSetting#READPROT
+	 * @since 2.1.1
+	 */
+    private static final byte[] ANNOTPROT = DocWriter.getISOBytes("\\annotprot");
+	/**
+	 * Constant for read only rotection controlword
+	 * Mutually exclusive - exception, can be combined with ANNOTPROT
+	 * for backwards compatibility
+	 * @see com.lowagie.text.rtf.document.RtfProtectionSetting#FORMPROT
+	 * @see com.lowagie.text.rtf.document.RtfProtectionSetting#REVPROT
+	 * @see com.lowagie.text.rtf.document.RtfProtectionSetting#ANNOTPROT
+	 * @since 2.1.1
+	 */
+    private static final byte[] READPROT = DocWriter.getISOBytes("\\readprot");
+    
+	/**
+	 * Constant for protlevel controlword
+	 * @since 2.1.1
+	 */
+    private static final byte[] PROTLEVEL = DocWriter.getISOBytes("\\protlevel");
+	/**
+	 * Constant for enforceprot controlword
+	 * @since 2.1.1 
+	 */
+    private static final byte[] ENFORCEPROT = DocWriter.getISOBytes("\\enforceprot");
+    
+	/**
+	 * Constant for enforceprot controlword.
+	 * Implemented in Microsoft Word 2007.
+	 * 
+     * @since 2.1.1
+	 */
+    private static final byte[] READONLYRECOMMENDED = DocWriter.getISOBytes("\\readonlyrecommended");
+
+    /**
+     * Constructs a <code>RtfProtectionSetting</code> belonging to a RtfDocument
+     * 
+     * @param doc The <code>RtfDocument</code> this <code>RtfProtectionSetting</code> belongs to
+	 * @since 2.1.1
+     */
+    public RtfProtectionSetting(RtfDocument doc) {
+        super(doc);
+    }
+
+    /**
+     * Writes the RTF protection control words
+	 * @since 2.1.1
+     */    
+    public void writeContent(final OutputStream result) throws IOException
+    {
+    }
+    
+    /**
+     * Writes the RTF protection control words
+	 * @since 2.1.1
+    */    
+    public void writeDefinition(final OutputStream result) throws IOException
+    {
+    	if(document.getDocumentSettings().isDocumentProtected()) {
+	    	switch(document.getDocumentSettings().getProtectionLevelRaw()) {
+	    	case RtfProtection.LEVEL_FORMPROT:
+	    		result.write(FORMPROT);
+	    		break;
+	    	case RtfProtection.LEVEL_ANNOTPROT:
+	    		result.write(ANNOTPROT);
+	    		break;
+	    	case RtfProtection.LEVEL_REVPROT:
+	    		result.write(REVPROT);
+	    		break;
+	    	case RtfProtection.LEVEL_READPROT:
+	    		result.write(ANNOTPROT);
+	    		result.write(READPROT);
+	    		break;
+	    	}
+	    	result.write(ENFORCEPROT);	// assumes one of the above protection keywords was output.
+	    	result.write((byte)'1');
+	    	result.write(PROTLEVEL);
+	    	result.write(document.getDocumentSettings().getProtectionLevelBytes());
+    	}
+    	
+    	if(document.getDocumentSettings().getReadOnlyRecommended()) {
+	    	result.write(READONLYRECOMMENDED);
+	    	result.write(DELIMITER);
+    	}
+    }
+}
Index: src/core/com/lowagie/text/rtf/parser/RtfParserState.java
===================================================================
--- src/core/com/lowagie/text/rtf/parser/RtfParserState.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/parser/RtfParserState.java	(revision 0)
@@ -0,0 +1,137 @@
+/*
+ * $Id: RtfParserState.java 3373 2008-05-12 16:21:24Z xlv $
+ *
+ * Copyright 2007 by Howard Shank (hgshank@yahoo.com)
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+package com.lowagie.text.rtf.parser;
+
+import java.util.Stack;
+
+import com.lowagie.text.rtf.parser.destinations.RtfDestination;
+import com.lowagie.text.rtf.parser.destinations.RtfDestinationNull;
+import com.lowagie.text.rtf.parser.properties.RtfProperty;
+
+/**
+ * The <code>RtfParserState</code> contains the state information
+ * for the parser. The current state object is pushed/popped in a stack
+ * when a group change is made.
+ * 
+ * When an open group is encountered, the current state is copied and 
+ * then pushed on the top of the stack
+ * When a close group is encountered, the current state is overwritten with
+ * the popped value from the top of the stack 
+ * 
+ * @author Howard Shank (hgshank@yahoo.com)
+ * @since 2.0.8
+ */
+public class RtfParserState {
+	/**
+	 * The parser state.
+	 */
+	public int parserState = RtfParser.PARSER_IN_UNKNOWN;
+	/**
+	 * The tokeniser state.
+	 */
+	public int tokeniserState = RtfParser.TOKENISER_STATE_IN_UNKOWN;
+	/**
+	 * The control word set as the group handler. 
+	 */
+	public Object groupHandler = null;
+	/**
+	 * The parsed value for the current group/control word.
+	 */
+	public StringBuffer text = null;
+	/**
+	 * Stack containing control word handlers. There could be multiple
+	 * control words in a group.
+	 */
+	public Stack ctrlWordHandlers = null;
+	/**
+	 * The current control word handler.
+	 */
+	public Object ctrlWordHandler = null;
+	/**
+	 * The current destination.
+	 */
+	public RtfDestination destination = null;
+	/**
+	 * Flag indicating if this is an extended destination \* control word
+	 */
+	public boolean isExtendedDestination = false;
+	/**
+	 * Flag to indicate if last token was an open group token '{'
+	 */
+	public boolean newGroup = false;
+	
+	public RtfProperty properties = null;
+	/**
+	 * Default constructor
+	 *
+	 */
+	public RtfParserState() {
+		this.text = new StringBuffer();
+		this.ctrlWordHandlers = new Stack();
+		this.properties = new RtfProperty();
+		this.destination = RtfDestinationNull.getInstance();
+		this.newGroup = false;
+	}
+	/**
+	 * Copy constructor
+	 * @param orig The object to copy
+	 */
+	public RtfParserState(RtfParserState orig) {
+		this.properties = orig.properties;
+		this.parserState = orig.parserState;
+		this.tokeniserState = orig.tokeniserState;
+		this.groupHandler = null;
+		this.destination = orig.destination;
+		this.text = new StringBuffer();
+		this.ctrlWordHandlers = new Stack();
+		this.destination = orig.destination;
+		this.newGroup = false;
+	}
+	
+}
Index: src/core/com/lowagie/text/rtf/text/RtfNewPage.java
===================================================================
--- src/core/com/lowagie/text/rtf/text/RtfNewPage.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/text/RtfNewPage.java	(revision 0)
@@ -0,0 +1,92 @@
+/*
+ * $Id: RtfNewPage.java 3580 2008-08-06 15:52:00Z howard_s $
+ *
+ * Copyright 2001, 2002, 2003, 2004 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.rtf.text;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import com.lowagie.text.DocWriter;
+import com.lowagie.text.rtf.RtfElement;
+import com.lowagie.text.rtf.document.RtfDocument;
+
+
+/**
+ * The RtfNewPage creates a new page. INTERNAL CLASS
+ * 
+ * @version $Id: RtfNewPage.java 3580 2008-08-06 15:52:00Z howard_s $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Thomas Bickel (tmb99@inode.at)
+ */
+public class RtfNewPage extends RtfElement {
+
+    /**
+     * Constant for a new page
+     */
+    public static final byte[] NEW_PAGE = DocWriter.getISOBytes("\\page");
+    
+    /**
+     * Constructs a RtfNewPage
+     * 
+     * @param doc The RtfDocument this RtfNewPage belongs to
+     */
+    public RtfNewPage(RtfDocument doc) {
+        super(doc);
+    }
+    
+    /**
+     * Writes a new page
+     */ 
+    public void writeContent(final OutputStream result) throws IOException
+    {
+        result.write(NEW_PAGE);
+        result.write(RtfParagraph.PARAGRAPH_DEFAULTS);    	
+    }
+    
+}
Index: src/core/com/lowagie/text/rtf/document/RtfInfoElement.java
===================================================================
--- src/core/com/lowagie/text/rtf/document/RtfInfoElement.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/document/RtfInfoElement.java	(revision 0)
@@ -0,0 +1,175 @@
+/*
+ * $Id: RtfInfoElement.java 3580 2008-08-06 15:52:00Z howard_s $
+ *
+ * Copyright 2003, 2004 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.rtf.document;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import com.lowagie.text.DocWriter;
+import com.lowagie.text.Meta;
+import com.lowagie.text.rtf.RtfElement;
+
+
+/**
+ * Stores one information group element. Valid elements are
+ * author, title, subject, keywords, producer and creationdate.
+ * 
+ * @version $Id: RtfInfoElement.java 3580 2008-08-06 15:52:00Z howard_s $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Thomas Bickel (tmb99@inode.at)
+ */
+public class RtfInfoElement extends RtfElement {
+
+    /**
+     * Constant for the author element
+     */
+    private static final byte[] INFO_AUTHOR = DocWriter.getISOBytes("\\author");
+    /**
+     * Constant for the subject element
+     */
+    private static final byte[] INFO_SUBJECT = DocWriter.getISOBytes("\\subject");
+    /**
+     * Constant for the keywords element
+     */
+    private static final byte[] INFO_KEYWORDS = DocWriter.getISOBytes("\\keywords");
+    /**
+     * Constant for the title element
+     */
+    private static final byte[] INFO_TITLE = DocWriter.getISOBytes("\\title");
+    /**
+     * Constant for the producer element
+     */
+    private static final byte[] INFO_PRODUCER = DocWriter.getISOBytes("\\operator");
+    /**
+     * Constant for the creationdate element
+     */
+    private static final byte[] INFO_CREATION_DATE =DocWriter.getISOBytes( "\\creationdate");
+
+    /**
+     * The type of this RtfInfoElement. The values from Element.INFO_ELEMENT_NAME are used.
+     */
+    private int infoType = -1;
+    /**
+     * The content of this RtfInfoElement
+     */
+    private String content = "";
+    
+    /**
+     * Constructs a RtfInfoElement based on the given Meta object
+     * 
+     * @param doc The RtfDocument this RtfInfoElement belongs to
+     * @param meta The Meta object this RtfInfoElement is based on
+     */
+    public RtfInfoElement(RtfDocument doc, Meta meta) {
+        super(doc);
+        infoType = meta.type();
+        content = meta.getContent();
+    }
+    
+    /**
+     * Writes the content of one RTF information element.
+     */    
+    public void writeContent(final OutputStream result) throws IOException
+    {
+        result.write(OPEN_GROUP);
+        switch(infoType) {
+            case Meta.AUTHOR:
+                result.write(INFO_AUTHOR);
+            	break;
+            case Meta.SUBJECT:
+                result.write(INFO_SUBJECT);
+        		break;
+            case Meta.KEYWORDS:
+                result.write(INFO_KEYWORDS);
+        		break;
+            case Meta.TITLE:
+                result.write(INFO_TITLE);
+        		break;
+            case Meta.PRODUCER:
+                result.write(INFO_PRODUCER);
+        		break;
+            case Meta.CREATIONDATE:
+                result.write(INFO_CREATION_DATE);
+            	break;
+            default:
+                result.write(INFO_AUTHOR);
+            	break;
+        }
+        result.write(DELIMITER);
+        if(infoType == Meta.CREATIONDATE) {
+            result.write(DocWriter.getISOBytes(convertDate(content)));
+        } else {
+            document.filterSpecialChar(result, content, false, false);
+        }
+        result.write(CLOSE_GROUP);
+    }        
+    
+    /**
+     * Converts a date from the format used by iText to the format required by
+     * rtf.<br>iText: EEE MMM dd HH:mm:ss zzz yyyy - rtf: \\'yr'yyyy\\'mo'MM\\'dy'dd\\'hr'HH\\'min'mm\\'sec'ss
+     * 
+     * @param date The date formated by iText
+     * @return The date formated for rtf
+     */
+    private String convertDate(String date) {
+        SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy");
+        try {
+            Date creationDate = sdf.parse(date);
+            sdf = new SimpleDateFormat("\\'yr'yyyy\\'mo'MM\\'dy'dd\\'hr'HH\\'min'mm\\'sec'ss");
+            return sdf.format(creationDate);
+        } catch(ParseException pe) {
+            pe.printStackTrace();
+            return "";
+        }
+    }
+}
Index: src/core/com/lowagie/text/rtf/list/RtfListItem.java
===================================================================
--- src/core/com/lowagie/text/rtf/list/RtfListItem.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/list/RtfListItem.java	(revision 0)
@@ -0,0 +1,232 @@
+/*
+ * $Id: RtfListItem.java 3969 2009-06-16 08:03:23Z blowagie $
+ *
+ * Copyright 2008 by Howard Shank (hgshank@yahoo.com)
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.rtf.list;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import com.lowagie.text.DocWriter;
+import com.lowagie.text.ListItem;
+import com.lowagie.text.rtf.RtfBasicElement;
+import com.lowagie.text.rtf.document.RtfDocument;
+import com.lowagie.text.rtf.style.RtfParagraphStyle;
+import com.lowagie.text.rtf.text.RtfChunk;
+import com.lowagie.text.rtf.text.RtfParagraph;
+
+
+/**
+ * The RtfListItem acts as a wrapper for a ListItem.
+ * 
+ * @version $Id: RtfListItem.java 3969 2009-06-16 08:03:23Z blowagie $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Howard Shank (hgshank@yahoo.com)
+ * @since 2.1.3
+ */
+public class RtfListItem extends RtfParagraph {
+
+    /**
+     * The RtfList this RtfListItem belongs to.
+     */
+    private RtfListLevel parentList = null;
+    /**
+     * Whether this RtfListItem contains further RtfLists.
+     */
+    private boolean containsInnerList = false;
+    
+    /**
+     * Constructs a RtfListItem for a ListItem belonging to a RtfDocument.
+     * 
+     * @param doc The RtfDocument this RtfListItem belongs to.
+     * @param listItem The ListItem this RtfListItem is based on.
+     */
+    public RtfListItem(RtfDocument doc, ListItem listItem) {
+        super(doc, listItem);
+    }
+    
+    /**
+     * Writes the content of this RtfListItem.
+     */    
+    public void writeContent(final OutputStream result) throws IOException
+    {
+        if(this.paragraphStyle.getSpacingBefore() > 0) {
+            result.write(RtfParagraphStyle.SPACING_BEFORE);
+            result.write(intToByteArray(paragraphStyle.getSpacingBefore()));
+        }
+        if(this.paragraphStyle.getSpacingAfter() > 0) {
+            result.write(RtfParagraphStyle.SPACING_AFTER);
+            result.write(intToByteArray(this.paragraphStyle.getSpacingAfter()));
+        }
+        if(this.paragraphStyle.getLineLeading() > 0) {
+        	result.write(RtfParagraph.LINE_SPACING);
+        	result.write(intToByteArray(this.paragraphStyle.getLineLeading()));
+        }
+        for(int i = 0; i < chunks.size(); i++) {
+            RtfBasicElement rtfElement = (RtfBasicElement) chunks.get(i);
+            if(rtfElement instanceof RtfChunk) {
+                ((RtfChunk) rtfElement).setSoftLineBreaks(true);
+            } else if(rtfElement instanceof RtfList) {
+                result.write(RtfParagraph.PARAGRAPH);
+                this.containsInnerList = true;
+            }
+            rtfElement.writeContent(result);
+            if(rtfElement instanceof RtfList) {
+                switch(this.parentList.getLevelFollowValue()) {
+                case RtfListLevel.LIST_LEVEL_FOLLOW_NOTHING:
+                	break;
+                case RtfListLevel.LIST_LEVEL_FOLLOW_TAB:
+                    this.parentList.writeListBeginning(result);
+                    result.write(RtfList.TAB);
+                    break;
+                case RtfListLevel.LIST_LEVEL_FOLLOW_SPACE:
+                    this.parentList.writeListBeginning(result);
+                    result.write(DocWriter.getISOBytes(" "));
+                    break;
+                }
+            }
+        }
+    }        
+
+    /**
+     * Writes the definition of the first element in this RtfListItem that is
+     * an instanceof {@link RtfList} to the given stream.<br> 
+     * If this item does not contain a {@link RtfList} element nothing is written
+     * and the method returns <code>false</code>.
+     * 
+     * @param out destination stream
+     * @return <code>true</code> if a RtfList definition was written, <code>false</code> otherwise
+     * @throws IOException
+     */
+    public boolean writeDefinition(OutputStream out) throws IOException
+    {
+        for(int i = 0; i < chunks.size(); i++) {
+            RtfBasicElement rtfElement = (RtfBasicElement)chunks.get(i);
+            if(rtfElement instanceof RtfList) {
+            	RtfList rl = (RtfList)rtfElement;
+            	rl.writeDefinition(out);
+                return true;
+            }
+        }
+        return false;
+    }
+    
+    private int level=0;
+    /**
+     * Inherit the list settings from the parent list to RtfLists that
+     * are contained in this RtfListItem.
+     * 
+     * @param listNumber The list number to inherit.
+     * @param listLevel The list level to inherit.
+     */
+    public void inheritListSettings(int listNumber, int listLevel) {
+        for(int i = 0; i < chunks.size(); i++) {
+            RtfBasicElement rtfElement = (RtfBasicElement) chunks.get(i);
+            if(rtfElement instanceof RtfList) {
+                ((RtfList) rtfElement).setListNumber(listNumber);
+                setLevel(listLevel);
+//                ((RtfList) rtfElement).setParent(this.parentList);
+            }
+        }
+    }
+        
+    /**
+     * Correct the indentation of RtfLists in this RtfListItem by adding left/first line indentation
+     * from the parent RtfList. Also calls correctIndentation on all child RtfLists.
+     */
+    protected void correctIndentation() {
+        for(int i = 0; i < chunks.size(); i++) {
+            RtfBasicElement rtfElement = (RtfBasicElement) chunks.get(i);
+            if(rtfElement instanceof RtfList) {
+                ((RtfList) rtfElement).correctIndentation();
+            }
+        }
+    }
+    
+    /**
+     * Set the parent RtfList.
+     * 
+     * @param parentList The parent RtfList to use.
+     */
+    public void setParent(RtfListLevel parentList) {
+        this.parentList = parentList;
+    }
+    /**
+     * Set the parent RtfList.
+     * 
+     * @return  The parent RtfList to use.
+     * @since 2.1.3
+     */
+    public RtfListLevel getParent() {
+        return this.parentList;
+    }
+    /**
+     * Gets whether this RtfListItem contains further RtfLists.
+     * 
+     * @return Whether this RtfListItem contains further RtfLists.
+     */
+    public boolean isContainsInnerList() {
+        return this.containsInnerList;
+    }
+
+	/**
+	 * @return the level
+	 * @since 2.1.3
+	 */
+	public int getLevel() {
+		return level;
+	}
+
+	/**
+	 * @param level the level to set
+     * @since 2.1.3
+	 */
+	public void setLevel(int level) {
+		this.level = level;
+	}
+}
Index: src/core/com/lowagie/text/rtf/document/RtfDocument.java
===================================================================
--- src/core/com/lowagie/text/rtf/document/RtfDocument.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/document/RtfDocument.java	(revision 0)
@@ -0,0 +1,372 @@
+/*
+ * $Id: RtfDocument.java 3580 2008-08-06 15:52:00Z howard_s $
+ *
+ * Copyright 2003, 2004, 2005 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.rtf.document;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+
+import com.lowagie.text.DocWriter;
+import com.lowagie.text.rtf.RtfBasicElement;
+import com.lowagie.text.rtf.RtfElement;
+import com.lowagie.text.rtf.RtfMapper;
+import com.lowagie.text.rtf.document.output.RtfDataCache;
+import com.lowagie.text.rtf.document.output.RtfDiskCache;
+import com.lowagie.text.rtf.document.output.RtfEfficientMemoryCache;
+import com.lowagie.text.rtf.document.output.RtfMemoryCache;
+import com.lowagie.text.rtf.graphic.RtfImage;
+
+/**
+ * The RtfDocument stores all document related data and also the main data stream.
+ * INTERNAL CLASS - NOT TO BE USED DIRECTLY
+ *
+ * @version $Id: RtfDocument.java 3580 2008-08-06 15:52:00Z howard_s $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Todd Bush [Tab support]
+ * @author Thomas Bickel (tmb99@inode.at)
+ * @since 1.x
+ */
+public class RtfDocument extends RtfElement {
+    /**
+     * Stores the actual document data
+     */
+    private RtfDataCache data = null;
+    /**
+     * The RtfMapper to use in this RtfDocument
+     */
+    private RtfMapper mapper = null;
+    /**
+     * The RtfDocumentHeader that handles all document header methods
+     */
+    private RtfDocumentHeader documentHeader = null;
+    /**
+     * Stores integers that have been generated as unique random numbers
+     */
+    private ArrayList previousRandomInts = null;
+    /**
+     * Whether to automatically generate TOC entries for Chapters and Sections. Defaults to false
+     */
+    private boolean autogenerateTOCEntries = false;
+    /**
+     * The RtfDocumentSettings for this RtfDocument.
+     */
+    private RtfDocumentSettings documentSettings = null;
+    /**
+     * The last RtfBasicElement that was added directly to the RtfDocument.
+     */
+    private RtfBasicElement lastElementWritten = null;
+    
+    /**
+     * Constant for the Rtf document start
+     */
+    private static final byte[] RTF_DOCUMENT = DocWriter.getISOBytes("\\rtf1");
+
+    private final static byte[] FSC_LINE = DocWriter.getISOBytes("\\line ");
+    private final static byte[] FSC_PAR = DocWriter.getISOBytes("\\par ");
+    private final static byte[] FSC_TAB = DocWriter.getISOBytes("\\tab ");
+    private final static byte[] FSC_PAGE_PAR = DocWriter.getISOBytes("\\page\\par ");
+    private final static byte[] FSC_NEWPAGE = DocWriter.getISOBytes("$newpage$");
+    private final static byte[] FSC_BACKSLASH = DocWriter.getISOBytes("\\");
+    private final static byte[] FSC_HEX_PREFIX = DocWriter.getISOBytes("\\\'");
+    private final static byte[] FSC_UNI_PREFIX = DocWriter.getISOBytes("\\u");
+    
+    /**
+     * The default constructor for a RtfDocument
+     */
+    public RtfDocument() {
+        super(null);
+        this.data = new RtfMemoryCache();
+        this.mapper = new RtfMapper(this);
+        this.documentHeader = new RtfDocumentHeader(this);
+        this.documentHeader.init();
+        this.previousRandomInts = new ArrayList();
+        this.documentSettings = new RtfDocumentSettings(this);
+    }
+
+    /**
+     * unused
+     */
+    public void writeContent(final OutputStream out) throws IOException
+    {    	
+    }
+    
+    /**
+     * Writes the document
+     *
+     * @param out The <code>OutputStream</code> to write the RTF document to.
+     */
+    public void writeDocument(OutputStream out) {
+        try {
+            out.write(OPEN_GROUP);
+            out.write(RtfDocument.RTF_DOCUMENT);
+            this.documentHeader.writeContent(out);
+            this.data.writeTo(out);
+            out.write(CLOSE_GROUP);
+        } catch(IOException ioe) {
+            ioe.printStackTrace();
+        }
+    }
+    
+    /**
+     * Opens the RtfDocument and initializes the data cache. If the data cache is
+     * set to CACHE_DISK, but the cache cannot be initialized then the memory cache
+     * is used.
+     */
+    public void open() {
+        try {
+            switch(this.documentSettings.getDataCacheStyle()) {
+            	case RtfDataCache.CACHE_MEMORY_EFFICIENT:  
+            		this.data = new RtfEfficientMemoryCache(); 
+            		break;
+                case RtfDataCache.CACHE_MEMORY:
+                	this.data = new RtfMemoryCache();
+                	break;
+                case RtfDataCache.CACHE_DISK:
+                	this.data = new RtfDiskCache();
+                	break;
+                default:
+                	throw new RuntimeException("unknown");
+            }
+    		
+        } catch(IOException ioe) {
+            System.err.println("Could not initialize disk cache. Using memory cache.");
+            ioe.printStackTrace();
+            this.data = new RtfMemoryCache();
+        }
+    }
+    
+    /**
+     * Adds an element to the rtf document
+     * 
+     * @param element The element to add
+     */
+    public void add(RtfBasicElement element) {
+        try {
+            if(element instanceof RtfInfoElement) {
+                this.documentHeader.addInfoElement((RtfInfoElement) element);
+            } else {
+                if(element instanceof RtfImage) {
+                    ((RtfImage) element).setTopLevelElement(true);
+                }
+                element.writeContent( this.data.getOutputStream() );
+                this.lastElementWritten = element;
+            }
+        } catch(IOException ioe) {
+            ioe.printStackTrace();
+        }
+    }
+    
+    /**
+     * Gets the RtfMapper object of this RtfDocument
+     * 
+     * @return The RtfMapper
+     */
+    public RtfMapper getMapper() {
+        return this.mapper;
+    }
+    
+    /**
+     * Generates a random integer that is unique with respect to the document.
+     * Will not return a number between -1 and -5 because some values in that range are invalid.
+     * @return A random int
+     */
+    public int getRandomInt() {
+        Integer newInt = null;
+        do {
+//        	do {
+        		newInt = new Integer((int) (Math.random() * Integer.MAX_VALUE));
+//        	} while(newInt.intValue() <= -1 && newInt.intValue() >= -5);
+        } while(this.previousRandomInts.contains(newInt));
+        this.previousRandomInts.add(newInt);
+        return newInt.intValue();
+    }
+    
+    /**
+     * Gets the RtfDocumentHeader of this RtfDocument
+     * 
+     * @return The RtfDocumentHeader of this RtfDocument
+     */
+    public RtfDocumentHeader getDocumentHeader() {
+        return this.documentHeader;
+    }
+    
+    /**
+     * Writes the given string to the given {@link OutputStream} encoding the string characters.
+     * 
+     * @param out destination OutputStream
+     * @param str string to write
+     * @param useHex if <code>true</code> hex encoding characters is preferred to unicode encoding if possible
+     * @param softLineBreaks if <code>true</code> return characters are written as soft line breaks
+     * 
+     * @throws IOException
+     */
+    public void filterSpecialChar(final OutputStream out, final String str, final boolean useHex, final boolean softLineBreaks) throws IOException
+    {
+        if(out == null) {
+            throw new NullPointerException("null OutpuStream");
+        }
+
+        final boolean alwaysUseUniCode = this.documentSettings.isAlwaysUseUnicode();
+        if(str == null) {
+            return;
+        }
+        final int len = str.length();
+        if(len == 0) {
+            return;
+        }
+
+        for(int k = 0; k < len; k++) {
+            final char c = str.charAt(k);
+            if(c < 0x20) {
+                //allow return and tab only
+                if(c == '\n') {
+                    out.write(softLineBreaks ? FSC_LINE : FSC_PAR);
+                } else if(c == '\t') {
+                    out.write(FSC_TAB);                 
+                } else {
+                    out.write('?');
+                }
+            } else if((c == '\\') || (c == '{') || (c == '}')) {
+                //escape
+                out.write(FSC_BACKSLASH);
+                out.write(c);
+            } else if((c == '$') && (len-k >= FSC_NEWPAGE.length) && subMatch(str, k, FSC_NEWPAGE)) {
+                out.write(FSC_PAGE_PAR);
+                k += FSC_NEWPAGE.length-1;
+            } else {
+                if((c > 0xff) || ((c > 'z') && alwaysUseUniCode)) {
+                    if(useHex && (c <= 0xff)) {
+                        //encode as 2 char hex string 
+                        out.write(FSC_HEX_PREFIX);
+                        out.write(RtfImage.byte2charLUT, c*2, 2);
+                    } else {
+                        //encode as decimal, signed short value
+                        out.write(FSC_UNI_PREFIX);
+                        String s = Short.toString((short)c);
+                        for(int x = 0; x < s.length(); x++) {
+                            out.write(s.charAt(x));
+                        }
+                        out.write('?');
+                    }
+                } else {
+                    out.write(c);
+                }
+            }
+        }       
+    }
+    /**
+     * Returns <code>true</code> if <tt>m.length</tt> characters in <tt>str</tt>, starting at offset <tt>soff</tt>
+     * match the bytes in the given array <tt>m</tt>.
+     * 
+     * @param str the string to search for a match
+     * @param soff the starting offset in str
+     * @param m the array to match
+     * @return <code>true</code> if there is match
+     */
+    private static boolean subMatch(final String str, int soff, final byte[] m)
+    {
+        for(int k = 0; k < m.length; k++) {
+            if(str.charAt(soff++) != m[k]) {
+                return false;
+            }
+        }
+        return true;
+    }
+    
+    /**
+     * Whether to automagically generate table of contents entries when
+     * adding Chapters or Sections.
+     * 
+     * @param autogenerate Whether to automatically generate TOC entries
+     */
+    public void setAutogenerateTOCEntries(boolean autogenerate) {
+        this.autogenerateTOCEntries = autogenerate;
+    }
+    
+    /**
+     * Get whether to automatically generate table of contents entries
+     * 
+     * @return Whether to automatically generate TOC entries
+     */
+    public boolean getAutogenerateTOCEntries() {
+        return this.autogenerateTOCEntries;
+    }
+    
+    /**
+     * Gets the RtfDocumentSettings that specify how the rtf document is generated.
+     * 
+     * @return The current RtfDocumentSettings.
+     */
+    public RtfDocumentSettings getDocumentSettings() {
+        return this.documentSettings;
+    }
+    
+    /**
+     * Gets the last RtfBasicElement that was directly added to the RtfDocument.
+     *  
+     * @return The last RtfBasicElement that was directly added to the RtfDocument.
+     */
+    public RtfBasicElement getLastElementWritten() {
+        return this.lastElementWritten;
+    }
+    
+    /**
+     * Helper method outputs linebreak in document if debugging is turned on.
+     * @param result the OutputStream to write the linebreak to.
+     * @throws IOException
+     * @since 2.1.3
+     */
+    final public void outputDebugLinebreak(final OutputStream result) throws IOException {
+    	if(this.getDocumentSettings().isOutputDebugLineBreaks())
+        {
+        	result.write('\n');
+        }
+    }
+}
\ No newline at end of file
Index: src/core/com/lowagie/text/rtf/parser/RtfParser.java
===================================================================
--- src/core/com/lowagie/text/rtf/parser/RtfParser.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/parser/RtfParser.java	(revision 0)
@@ -0,0 +1,1604 @@
+/*
+ * $Id: RtfParser.java 3580 2008-08-06 15:52:00Z howard_s $
+ *
+ * Copyright 2007 by Howard Shank (hgshank@yahoo.com)
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+package com.lowagie.text.rtf.parser;
+
+import java.awt.Color;
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PushbackInputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.EventListener;
+import java.util.Iterator;
+import java.util.Stack;
+
+import com.lowagie.text.Document;
+import com.lowagie.text.DocumentException;
+import com.lowagie.text.Element;
+import com.lowagie.text.List;
+import com.lowagie.text.rtf.direct.RtfDirectContent;
+import com.lowagie.text.rtf.document.RtfDocument;
+import com.lowagie.text.rtf.parser.ctrlwords.RtfCtrlWordData;
+import com.lowagie.text.rtf.parser.ctrlwords.RtfCtrlWordListener;
+import com.lowagie.text.rtf.parser.ctrlwords.RtfCtrlWordMgr;
+import com.lowagie.text.rtf.parser.destinations.RtfDestination;
+import com.lowagie.text.rtf.parser.destinations.RtfDestinationMgr;
+
+/**
+ * The RtfParser allows the importing of RTF documents or
+ * RTF document fragments. The RTF document or fragment is tokenised,
+ * font and color definitions corrected and then added to
+ * the document being written.
+ * 
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Howard Shank (hgshank@yahoo.com)
+ * @since 2.0.8
+ */
+
+public class RtfParser {
+	/**
+	 * Debugging flag.
+	 */
+	private static final boolean debugParser = false;	// DEBUG Files are unlikely to be read by any reader!
+	private String logFile = null;
+	private boolean logging = false;
+	private boolean logAppend = false;
+	
+	/**
+	 * The iText element to add the RTF document to.
+	 * @since 2.1.3
+	 */
+	private Element elem = null;
+	/**
+	 * The iText document to add the RTF document to.
+	 */
+	private Document document = null;
+	/**
+	 * The RtfDocument to add the RTF document or fragment to.
+	 */
+	private RtfDocument rtfDoc = null;
+	/**
+	 * The RtfKeywords that creates and handles keywords that are implemented.
+	 */
+	private RtfCtrlWordMgr rtfKeywordMgr = null;
+	/**
+	 * The RtfImportHeader to store imported font and color mappings in.
+	 */
+	private RtfImportMgr importMgr = null;
+	/**
+	 * The RtfDestinationMgr object to manage destinations.
+	 */
+	private RtfDestinationMgr destinationMgr = null;
+	/**
+	 * Stack for saving states for groups
+	 */
+	private Stack stackState = null;
+	/**
+	 * The current parser state.
+	 */	
+	private RtfParserState currentState = null;
+	/**
+	 * The pushback reader to read the input stream.
+	 */
+	private PushbackInputStream pbReader = null;
+	/**
+	 * Conversion type. Identifies if we are doing in import or a convert.
+	 */
+	private int conversionType = TYPE_IMPORT_FULL;
+	
+
+	/*
+	 * Bitmapping:
+	 * 
+	 * 0111 1111 1111 1111 = Unkown state
+	 * 0xxx xxxx xxxx xxxx = In Header
+	 * 1xxx xxxx xxxx xxxx = In Document
+	 * 2xxx xxxx xxxx xxxx = Reserved
+	 * 4xxx xxxx xxxx xxxx = Other
+	 * 8xxx xxxx xxxx xxxx = Errors
+	 */
+	
+	/*
+	 * Header state values
+	 */
+
+	/**
+	 * Currently the RTF document header is being parsed.
+	 */
+	public static final int PARSER_IN_HEADER = (0x0 << 28) | 0x000000;
+	/**
+	 * Currently the RTF charset is being parsed.
+	 */
+	public static final int PARSER_IN_CHARSET = PARSER_IN_HEADER | 0x000001;
+	/**
+	 * Currently the RTF deffont is being parsed.
+	 */
+	public static final int PARSER_IN_DEFFONT = PARSER_IN_HEADER | 0x000002;
+	/**
+	 * Currently the RTF font table is being parsed.
+	 */
+	public static final int PARSER_IN_FONT_TABLE = PARSER_IN_HEADER | 0x000003;
+	/**
+	 * Currently a RTF font table info element is being parsed.
+	 */
+	public static final int PARSER_IN_FONT_TABLE_INFO = PARSER_IN_HEADER | 0x000004;
+	/**
+	 * Currently the RTF filetbl is being parsed.
+	 */
+	public static final int PARSER_IN_FILE_TABLE = PARSER_IN_HEADER | 0x000005;
+	/**
+	 * Currently the RTF color table is being parsed.
+	 */
+	public static final int PARSER_IN_COLOR_TABLE = PARSER_IN_HEADER | 0x000006;
+	/**
+	 * Currently the RTF  stylesheet is being parsed.
+	 */
+	public static final int PARSER_IN_STYLESHEET = PARSER_IN_HEADER | 0x000007;
+	/**
+	 * Currently the RTF listtables is being parsed.
+	 */
+	public static final int PARSER_IN_LIST_TABLE = PARSER_IN_HEADER | 0x000008;
+	/**
+	 * Currently the RTF listtable override is being parsed.
+	 */
+	public static final int PARSER_IN_LISTOVERRIDE_TABLE = PARSER_IN_HEADER | 0x000009;
+	/**
+	 * Currently the RTF revtbl is being parsed.
+	 */
+	public static final int PARSER_IN_REV_TABLE = PARSER_IN_HEADER | 0x00000A;
+	/**
+	 * Currently the RTF rsidtable is being parsed.
+	 */
+	public static final int PARSER_IN_RSID_TABLE = PARSER_IN_HEADER | 0x0000B;
+	/**
+	 * Currently the RTF generator is being parsed.
+	 */
+	public static final int PARSER_IN_GENERATOR = PARSER_IN_HEADER | 0x00000C;
+	/**
+	 * Currently the RTF Paragraph group properties Table (word 2002)
+	 */
+	public static final int PARSER_IN_PARAGRAPH_TABLE = PARSER_IN_HEADER | 0x00000E;
+	/**
+	 * Currently the RTF Old Properties.
+	 */
+	public static final int PARSER_IN_OLDCPROPS = PARSER_IN_HEADER | 0x00000F;
+	/**
+	 * Currently the RTF Old Properties.
+	 */
+	public static final int PARSER_IN_OLDPPROPS = PARSER_IN_HEADER | 0x000010;
+	/**
+	 * Currently the RTF Old Properties.
+	 */
+	public static final int PARSER_IN_OLDTPROPS = PARSER_IN_HEADER | 0x000012;
+	/**
+	 * Currently the RTF Old Properties.
+	 */
+	public static final int PARSER_IN_OLDSPROPS = PARSER_IN_HEADER | 0x000013;
+	/**
+	 * Currently the RTF User Protection Information.
+	 */
+	public static final int PARSER_IN_PROT_USER_TABLE = PARSER_IN_HEADER | 0x000014;
+	/**
+	 * Currently the Latent Style and Formatting usage restrictions
+	 */
+	public static final int PARSER_IN_LATENTSTYLES = PARSER_IN_HEADER | 0x000015;
+	
+	public static final int PARSER_IN_PARAGRAPH_GROUP_PROPERTIES =PARSER_IN_HEADER | 0x000016;
+	
+	/*
+	 * Document state values
+	 */
+	
+	/**
+	 * Currently the RTF document content is being parsed.
+	 */
+	public static final int PARSER_IN_DOCUMENT = (0x2 << 28 ) | 0x000000;
+
+	/**
+	 * Currently the RTF info group is being parsed.
+	 */
+	public static final int PARSER_IN_INFO_GROUP = PARSER_IN_DOCUMENT | 0x000001;
+
+	
+	public static final int PARSER_IN_UPR = PARSER_IN_DOCUMENT | 0x000002;
+	/**
+	 * Currently a shppict control word is being parsed.
+	 */
+	public static final int PARSER_IN_SHPPICT = PARSER_IN_DOCUMENT | 0x000010; //16
+	/**
+	 * Currently a pict control word is being parsed.
+	 */
+	public static final int PARSER_IN_PICT = PARSER_IN_DOCUMENT | 0x000011; //17
+	/**
+	 * Currently a picprop control word is being parsed.
+	 */
+	public static final int PARSER_IN_PICPROP = PARSER_IN_DOCUMENT | 0x000012; //18
+	/**
+	 * Currently a blipuid control word is being parsed.
+	 */
+	public static final int PARSER_IN_BLIPUID = PARSER_IN_DOCUMENT | 0x000013; //19
+
+	/* other states */
+	/**
+	 * The parser is at the beginning or the end of the file.
+	 */
+	public static final int PARSER_STARTSTOP = (0x4 << 28)| 0x0001;
+	/* ERRORS */
+	/**
+	 * Currently the parser is in an error state.
+	 */
+	public static final int PARSER_ERROR = (0x8 << 28) | 0x0000;
+	/**
+	 * The parser reached the end of the file.
+	 */
+	public static final int PARSER_ERROR_EOF = PARSER_ERROR | 0x0001;
+	/**
+	 * Currently the parser is in an unknown state.
+	 */
+	public static final int PARSER_IN_UNKNOWN = PARSER_ERROR | 0x0FFFFFFF;
+	
+	
+	/**
+	 * Conversion type is unknown
+	 */
+	public static final int TYPE_UNIDENTIFIED = -1;
+	/**
+	 * Conversion type is an import. Uses direct content to add everything.
+	 * This is what the original import does.
+	 */
+	public static final int TYPE_IMPORT_FULL = 0;
+	/**
+	 * Conversion type is an import of a partial file/fragment. Uses direct content to add everything.
+	 */
+	public static final int TYPE_IMPORT_FRAGMENT = 1;
+	/**
+	 * Conversion type is a conversion. This uses the document (not rtfDoc) to add
+	 * all the elements making it a different supported documents depending on the writer used.
+	 */
+	public static final int TYPE_CONVERT = 2;
+	/**
+	 * Conversion type to import a document into an element. i.e. Chapter, Section, Table Cell, etc.
+	 * @since 2.1.4
+	 */
+	public static final int TYPE_IMPORT_INTO_ELEMENT = 3;
+
+	
+	/**
+	 * Destination is normal. Text is processed.
+	 */
+	public static final int DESTINATION_NORMAL = 0;
+	/**
+	 * Destination is skipping. Text is ignored.
+	 */
+	public static final int DESTINATION_SKIP = 1;
+	
+	//////////////////////////////////// TOKENISE VARIABLES ///////////////////
+	/*
+	 * State flags use 4/28 bitmask.
+	 * First 4 bits (nibble) indicates major state. Used for unknown and error
+	 * Last 28 bits indicates the value;
+	 */
+	
+	/**
+	 * The RtfTokeniser is in its ground state. Any token may follow.
+	 */
+	public static final int TOKENISER_NORMAL = 0x00000000;
+	/**
+	 * The last token parsed was a slash.
+	 */
+	public static final int TOKENISER_SKIP_BYTES = 0x00000001;
+	/**
+	 * The RtfTokeniser is currently tokenising a control word.
+	 */
+	public static final int TOKENISER_SKIP_GROUP = 0x00000002;
+	/**
+	 * The RtfTokeniser is currently reading binary stream.
+	 */
+	public static final int TOKENISER_BINARY= 0x00000003;
+	/**
+	 * The RtfTokeniser is currently reading hex data.
+	 */
+	public static final int TOKENISER_HEX= 0x00000004;
+	/**
+	 * The RtfTokeniser ignore result
+	 */
+	public static final int TOKENISER_IGNORE_RESULT= 0x00000005;
+	/**
+	 * The RtfTokeniser is currently in error state
+	 */
+	public static final int TOKENISER_STATE_IN_ERROR =  0x80000000; // 1000 0000 0000 0000 0000 0000 0000 0000
+	/**
+	 * The RtfTokeniser is currently in an unkown state
+	 */
+	public static final int TOKENISER_STATE_IN_UNKOWN = 0xFF000000; // 1111 0000 0000 0000 0000 0000 0000 0000
+	
+	/**
+	 * The current group nesting level.
+	 */
+	private int groupLevel = 0;
+	/**
+	 * The current document group nesting level. Used for fragments.
+	 */
+	private int docGroupLevel = 0;
+	/**
+	 * When the tokeniser is Binary.
+	 */
+	private long binByteCount = 0;
+	/**
+	 * When the tokeniser is set to skip bytes, binSkipByteCount is the number of bytes to skip.
+	 */
+	private long binSkipByteCount = 0;
+	/**
+	 * When the tokeniser is set to skip to next group, this is the group indentifier to return to.
+	 */
+	private int skipGroupLevel = 0;
+
+	//RTF parser error codes
+	public static final int  errOK =0;                        // Everything's fine!
+	public static final int  errStackUnderflow   =  -1;       // Unmatched '}'
+	public static final int  errStackOverflow    =  -2;       // Too many '{' -- memory exhausted
+	public static final int  errUnmatchedBrace   =  -3;       // RTF ended during an open group.
+	public static final int  errInvalidHex       =  -4;       // invalid hex character found in data
+	public static final int  errBadTable         =  -5;       // RTF table (sym or prop) invalid
+	public static final int  errAssertion        =  -6;       // Assertion failure
+	public static final int  errEndOfFile        =  -7;       // End of file reached while reading RTF
+	public static final int  errCtrlWordNotFound =  -8;		  // control word was not found
+	//////////////////////////////////// TOKENISE VARIABLES ///////////////////
+	
+	
+	//////////////////////////////////// STATS VARIABLES ///////////////////
+	/**
+	 * Total bytes read.
+	 */
+	private long byteCount = 0;
+	/**
+	 * Total control words processed.
+	 * 
+	 * Contains both known and unknown.
+	 * 
+	 * <code>ctrlWordCount</code> should equal 
+	 * <code>ctrlWrodHandlecCount</code> + <code>ctrlWordNotHandledCount</code + <code>ctrlWordSkippedCount</code>
+	 */
+	private long ctrlWordCount = 0;
+	/**
+	 * Total { encountered as an open group token.
+	 */
+	private long openGroupCount = 0;
+	/**
+	 * Total } encountered as a close group token.
+	 */
+	private long closeGroupCount = 0;
+	/**
+	 * Total clear text characters processed.
+	 */
+	private long characterCount = 0;
+	/**
+	 * Total control words recognized.
+	 */
+	private long ctrlWordHandledCount = 0;
+	/**
+	 * Total control words not handled.
+	 */
+	private long ctrlWordNotHandledCount = 0;
+	/**
+	 * Total control words skipped.
+	 */
+	private long ctrlWordSkippedCount = 0;
+	/**
+	 * Total groups skipped. Includes { and } as a group.
+	 */
+	private long groupSkippedCount = 0;
+	/**
+	 * Start time as a long.
+	 */
+	private long startTime = 0;
+	/**
+	 * Stop time as a long.
+	 */
+	private long endTime = 0;
+	/**
+	 * Start date as a date.
+	 */
+	private Date startDate = null;
+	/**
+	 * End date as a date.
+	 */
+	private Date endDate = null;
+	//////////////////////////////////// STATS VARIABLES ///////////////////
+	/**
+	 * Last control word and parameter processed.
+	 */
+	private RtfCtrlWordData lastCtrlWordParam = null;
+	
+	/** The <code>RtfCtrlWordListener</code>. */
+    private ArrayList listeners = new ArrayList();
+    
+	/**
+	 * Constructor 
+	 * @param doc
+	 * @since 2.1.3
+	 */
+    public RtfParser(Document doc) {
+    	this.document = doc;
+    }
+	/* *********
+	 *  READER *
+	 ***********/
+	/**
+	 * Imports a complete RTF document.
+	 * 
+	 * @param readerIn 
+	 * 		The Reader to read the RTF document from.
+	 * @param rtfDoc 
+	 * 		The RtfDocument to add the imported document to.
+	 * @throws IOException On I/O errors.
+	 *  @since 2.1.3
+	 */
+	public void importRtfDocument(InputStream readerIn, RtfDocument rtfDoc) throws IOException {
+		if(readerIn == null || rtfDoc == null) return;
+		this.init(TYPE_IMPORT_FULL, rtfDoc, readerIn, this.document, null);
+		this.setCurrentDestination(RtfDestinationMgr.DESTINATION_NULL);
+		startDate = new Date();
+		startTime = System.currentTimeMillis();
+		this.groupLevel = 0;
+		try {
+			this.tokenise();
+		} catch (RuntimeException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		catch (Exception e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		endTime = System.currentTimeMillis();
+		endDate = new Date();
+	}
+	/**
+	 * Imports a complete RTF document into an Element, i.e. Chapter, section, Table Cell, etc.
+	 * 
+	 * @param elem The Element the document is to be imported into.
+	 * @param readerIn 
+	 * 		The Reader to read the RTF document from.
+	 * @param rtfDoc 
+	 * 		The RtfDocument to add the imported document to.
+	 * @throws IOException On I/O errors.
+	 * @since 2.1.4
+	 */
+	public void importRtfDocumentIntoElement(Element elem, InputStream readerIn, RtfDocument rtfDoc) throws IOException {
+		if(readerIn == null || rtfDoc == null || elem == null) return;
+		this.init(TYPE_IMPORT_INTO_ELEMENT, rtfDoc, readerIn, this.document, elem);
+		this.setCurrentDestination(RtfDestinationMgr.DESTINATION_NULL);
+		startDate = new Date();
+		startTime = System.currentTimeMillis();
+		this.groupLevel = 0;
+		try {
+			this.tokenise();
+		} catch (RuntimeException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		catch (Exception e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		endTime = System.currentTimeMillis();
+		endDate = new Date();
+	}
+	/**
+	 * Converts an RTF document to an iText document.
+	 * 
+	 * Usage: Create a parser object and call this method with the input stream and the iText Document object
+	 * 
+	 * @param readerIn 
+	 * 		The Reader to read the RTF file from.
+	 * @param doc 
+	 * 		The iText document that the RTF file is to be added to.
+	 * @throws IOException 
+	 * 		On I/O errors.
+	 *  @since 2.1.3
+	 */
+	public void convertRtfDocument(InputStream readerIn, Document doc) throws IOException {
+		if(readerIn == null || doc == null) return;
+		this.init(TYPE_CONVERT, null, readerIn, doc, null);
+		this.setCurrentDestination(RtfDestinationMgr.DESTINATION_DOCUMENT);
+		startDate = new Date();
+		startTime = System.currentTimeMillis();
+		this.groupLevel = 0;
+		this.tokenise();
+		endTime = System.currentTimeMillis();
+		endDate = new Date();
+	}
+
+	/**
+	 * Imports an RTF fragment.
+	 * 
+	 * @param readerIn 
+	 * 		The Reader to read the RTF fragment from.
+	 * @param rtfDoc 
+	 * 		The RTF document to add the RTF fragment to.
+	 * @param importMappings 
+	 * 		The RtfImportMappings defining font and color mappings for the fragment.
+	 * @throws IOException 
+	 * 		On I/O errors.
+	 *   @since 2.1.3
+	 */
+	public void importRtfFragment(InputStream readerIn, RtfDocument rtfDoc, RtfImportMappings importMappings) throws IOException {
+	//public void importRtfFragment2(Reader readerIn, RtfDocument rtfDoc, RtfImportMappings importMappings) throws IOException {
+		if(readerIn == null || rtfDoc == null || importMappings==null) return;
+		this.init(TYPE_IMPORT_FRAGMENT, rtfDoc, readerIn, null, null);
+		this.handleImportMappings(importMappings);
+		this.setCurrentDestination(RtfDestinationMgr.DESTINATION_DOCUMENT);
+		this.groupLevel = 1;
+		setParserState(RtfParser.PARSER_IN_DOCUMENT);
+		startDate = new Date();
+		startTime = System.currentTimeMillis();
+		this.tokenise();
+		endTime = System.currentTimeMillis();
+		endDate = new Date();
+	}
+	
+    // listener methods
+
+	/**
+	 * Adds a <CODE>EventListener</CODE> to the <CODE>RtfCtrlWordMgr</CODE>.
+	 *
+	 * @param listener
+	 *            the new EventListener.
+	 * @since 2.1.3
+	 */
+	public void addListener(EventListener listener) {
+		listeners.add(listener);
+	}
+
+	/**
+	 * Removes a <CODE>EventListener</CODE> from the <CODE>RtfCtrlWordMgr</CODE>.
+	 *
+	 * @param listener
+	 *            the EventListener that has to be removed.
+	 *  @since 2.1.3
+	 */
+	public void removeListener(EventListener listener) {
+		listeners.remove(listener);
+	}
+
+	/**
+	 * Initialize the parser object values. 
+	 * 
+	 * @param type Type of conversion or import
+	 * @param rtfDoc The <code>RtfDocument</code>
+	 * @param readerIn The input stream
+	 * @param doc The iText <code>Document</code>
+	 *   @since 2.1.3
+	 */
+	private void init(int type, RtfDocument rtfDoc, InputStream readerIn, Document doc, Element elem) {
+
+		init_stats();
+		// initialize reader to a PushbackReader
+		this.pbReader = init_Reader(readerIn);
+		
+		this.conversionType = type;
+		this.rtfDoc = rtfDoc;
+		this.document = doc;
+		this.elem = elem;
+		this.currentState = new RtfParserState();
+		this.stackState = new Stack();
+		this.setParserState(PARSER_STARTSTOP);
+		this.importMgr = new RtfImportMgr(this.rtfDoc, this.document);
+
+		// get destination Mgr
+		this.destinationMgr = RtfDestinationMgr.getInstance(this);
+		// set the parser
+		RtfDestinationMgr.setParser(this);
+
+
+		// DEBUG INFO for timing and memory usage of RtfCtrlWordMgr object
+		// create multiple new RtfCtrlWordMgr objects to check timing and memory usage
+//		System.gc();
+//		long endTime = 0;
+//		Date endDate = null;		
+//		long endFree = 0;
+//		DecimalFormat df = new DecimalFormat("#,##0");
+//		Date startDate = new Date();
+//		long startTime = System.currentTimeMillis();
+//		long startFree = Runtime.getRuntime().freeMemory();
+//		System.out.println("1:");
+		
+		this.rtfKeywordMgr = new RtfCtrlWordMgr(this, this.pbReader);/////////DO NOT COMMENT OUT THIS LINE ///////////
+		
+		Object listener;
+		for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
+            listener = iterator.next();
+            if(listener instanceof RtfCtrlWordListener) {
+                this.rtfKeywordMgr.addRtfCtrlWordListener((RtfCtrlWordListener)listener);    
+            }
+        }
+//		endFree = Runtime.getRuntime().freeMemory();
+//		endTime = System.currentTimeMillis();
+//		endDate = new Date();
+//		System.out.println("RtfCtrlWordMgr start date: " + startDate.toLocaleString());
+//		System.out.println("RtfCtrlWordMgr end date  : " + endDate.toLocaleString());
+//		System.out.println("  Elapsed time    : " + Long.toString(endTime - startTime) + " milliseconds.");
+//		System.out.println("Begin Constructor RtfCtrlWordMgr , free mem is " + df.format(startFree / 1024) + "k");
+//		System.out.println("End Constructor RtfCtrlWordMgr , free mem is " + df.format(endFree / 1024) + "k");
+//		System.out.println("RtfCtrlWordMgr used approximately " + df.format((startFree - endFree) / 1024) + "k");
+//		
+//		System.gc();
+//		System.out.println("2:");
+//		startDate = new Date();
+//		startTime = System.currentTimeMillis();
+//		startFree = Runtime.getRuntime().freeMemory();
+//		RtfCtrlWordMgr rtfKeywordMgr2 = new RtfCtrlWordMgr(this, this.pbReader);		
+//		endFree = Runtime.getRuntime().freeMemory();
+//		endTime = System.currentTimeMillis();
+//		endDate = new Date();
+//		System.out.println("RtfCtrlWordMgr start date: " + startDate.toLocaleString());
+//		System.out.println("RtfCtrlWordMgr end date  : " + endDate.toLocaleString());
+//		System.out.println("  Elapsed time    : " + Long.toString(endTime - startTime) + " milliseconds.");
+//		System.out.println("Begin Constructor RtfCtrlWordMgr , free mem is " + df.format(startFree / 1024) + "k");
+//		System.out.println("End Constructor RtfCtrlWordMgr , free mem is " + df.format(endFree / 1024) + "k");
+//		System.out.println("RtfCtrlWordMgr used approximately " + df.format((startFree - endFree) / 1024) + "k");
+//		
+//		System.gc();
+//		System.out.println("3:");
+//		startDate = new Date();
+//		startTime = System.currentTimeMillis();
+//		startFree = Runtime.getRuntime().freeMemory();
+//		RtfCtrlWordMgr rtfKeywordMgr3 = new RtfCtrlWordMgr(this, this.pbReader);	
+//		endFree = Runtime.getRuntime().freeMemory();
+//		endTime = System.currentTimeMillis();
+//		endDate = new Date();
+//		System.out.println("RtfCtrlWordMgr start date: " + startDate.toLocaleString());
+//		System.out.println("RtfCtrlWordMgr end date  : " + endDate.toLocaleString());
+//		System.out.println("  Elapsed time    : " + Long.toString(endTime - startTime) + " milliseconds.");
+//		System.out.println("Begin Constructor RtfCtrlWordMgr , free mem is " + df.format(startFree / 1024) + "k");
+//		System.out.println("End Constructor RtfCtrlWordMgr , free mem is " + df.format(endFree / 1024) + "k");
+//		System.out.println("RtfCtrlWordMgr used approximately " + df.format((startFree - endFree) / 1024) + "k");
+//
+//		System.gc();
+//		System.out.println("4:");
+//		startDate = new Date();
+//		startTime = System.currentTimeMillis();
+//		startFree = Runtime.getRuntime().freeMemory();
+//		RtfCtrlWordMgr rtfKeywordMgr4 = new RtfCtrlWordMgr(this, this.pbReader);	
+//		endFree = Runtime.getRuntime().freeMemory();
+//		endTime = System.currentTimeMillis();
+//		endDate = new Date();
+//		System.out.println("RtfCtrlWordMgr start date: " + startDate.toLocaleString());
+//		System.out.println("RtfCtrlWordMgr end date  : " + endDate.toLocaleString());
+//		System.out.println("  Elapsed time    : " + Long.toString(endTime - startTime) + " milliseconds.");
+//		System.out.println("Begin Constructor RtfCtrlWordMgr , free mem is " + df.format(startFree / 1024) + "k");
+//		System.out.println("End Constructor RtfCtrlWordMgr , free mem is " + df.format(endFree / 1024) + "k");
+//		System.out.println("RtfCtrlWordMgr used approximately " + df.format((startFree - endFree) / 1024) + "k");
+//
+//		System.gc();
+//		System.out.println("5:");
+//		startDate = new Date();
+//		startTime = System.currentTimeMillis();
+//		startFree = Runtime.getRuntime().freeMemory();
+//		RtfCtrlWordMgr rtfKeywordMgr5 = new RtfCtrlWordMgr(this, this.pbReader);	
+//		endFree = Runtime.getRuntime().freeMemory();
+//		endTime = System.currentTimeMillis();
+//		endDate = new Date();
+//		System.out.println("RtfCtrlWordMgr start date: " + startDate.toLocaleString());
+//		System.out.println("RtfCtrlWordMgr end date  : " + endDate.toLocaleString());
+//		System.out.println("  Elapsed time    : " + Long.toString(endTime - startTime) + " milliseconds.");
+//		System.out.println("Begin Constructor RtfCtrlWordMgr , free mem is " + df.format(startFree / 1024) + "k");
+//		System.out.println("End Constructor RtfCtrlWordMgr , free mem is " + df.format(endFree / 1024) + "k");
+//		System.out.println("RtfCtrlWordMgr used approximately " + df.format((startFree - endFree) / 1024) + "k");
+//		System.gc();
+//		System.out.println("At ed:");
+//		startDate = new Date();
+//		startTime = System.currentTimeMillis();
+//		startFree = Runtime.getRuntime().freeMemory();
+//		//RtfCtrlWordMgr rtfKeywordMgr6 = new RtfCtrlWordMgr(this, this.pbReader);	
+//		endFree = Runtime.getRuntime().freeMemory();
+//		endTime = System.currentTimeMillis();
+//		endDate = new Date();
+//		System.out.println("RtfCtrlWordMgr start date: " + startDate.toLocaleString());
+//		System.out.println("RtfCtrlWordMgr end date  : " + endDate.toLocaleString());
+//		System.out.println("  Elapsed time    : " + Long.toString(endTime - startTime) + " milliseconds.");
+//		System.out.println("Begin Constructor RtfCtrlWordMgr , free mem is " + df.format(startFree / 1024) + "k");
+//		System.out.println("End Constructor RtfCtrlWordMgr , free mem is " + df.format(endFree / 1024) + "k");
+//		System.out.println("RtfCtrlWordMgr used approximately " + df.format((startFree - endFree) / 1024) + "k");
+	}
+	/**
+	 * Initialize the statistics values.
+	 * @since 2.1.3
+	 */
+	protected void init_stats() {
+		byteCount = 0;
+		ctrlWordCount = 0;
+		openGroupCount = 0;
+		closeGroupCount = 0;
+		characterCount = 0;
+		ctrlWordHandledCount = 0;
+		ctrlWordNotHandledCount = 0;
+		ctrlWordSkippedCount = 0;
+		groupSkippedCount = 0;
+		startTime = 0;
+		endTime = 0;
+		startDate = null;
+		endDate = null;
+	}
+	
+	/**
+	 * Casts the input reader to a PushbackReader or 
+	 * creates a new PushbackReader from the Reader passed in.
+	 * The reader is also transformed into a BufferedReader if necessary.
+	 * 
+	 * @param readerIn
+	 * 		The Reader object for the input file.
+	 * @return
+	 * 		PushbackReader object
+	 * @since 2.1.3
+	 */
+	private PushbackInputStream init_Reader(InputStream readerIn) {
+//		Reader newReader = readerIn;
+//		// Initializing the reader as a BufferedReader 
+//		// cut test processing time by approximately 50%
+//		// default uses 8192 character buffer
+//		if(!(newReader instanceof BufferedReader)) {
+//			newReader = new BufferedReader(newReader);	// Since JDK1.1
+//		}
+//		// Initializing the reader as a PushbackReader is
+//		// a requirement of the parser to be able to put back
+//		// read ahead characters.
+//		if(!(newReader instanceof PushbackReader)) {
+//			newReader = new PushbackReader(newReader);	// Since JDK1.1
+//		}
+		
+		if(!(readerIn instanceof BufferedInputStream)) {
+			readerIn = new BufferedInputStream(readerIn);
+		}
+		if(!(readerIn instanceof PushbackInputStream)) {
+			readerIn = new PushbackInputStream(readerIn);
+		}
+		// return the proper reader object to the parser setup
+		return  (PushbackInputStream)readerIn;
+	}
+	
+	/**
+	 * Imports the mappings defined in the RtfImportMappings into the
+	 * RtfImportHeader of this RtfParser2.
+	 * 
+	 * @param importMappings 
+	 * 		The RtfImportMappings to import.
+	 * @since 2.1.3
+	 */
+	private void handleImportMappings(RtfImportMappings importMappings) {
+		Iterator it = importMappings.getFontMappings().keySet().iterator();
+		while(it.hasNext()) {
+			String fontNr = (String) it.next();
+			this.importMgr.importFont(fontNr, (String) importMappings.getFontMappings().get(fontNr));
+		}
+		it = importMappings.getColorMappings().keySet().iterator();
+		while(it.hasNext()) {
+			String colorNr = (String) it.next();
+			this.importMgr.importColor(colorNr, (Color) importMappings.getColorMappings().get(colorNr));
+		}
+		it = importMappings.getListMappings().keySet().iterator();
+		while(it.hasNext()) {
+			String listNr = (String) it.next();
+			this.importMgr.importList(listNr, (String)importMappings.getListMappings().get(listNr));
+		}
+		it = importMappings.getStylesheetListMappings().keySet().iterator();
+		while(it.hasNext()) {
+			String stylesheetListNr = (String) it.next();
+			this.importMgr.importStylesheetList(stylesheetListNr, (List) importMappings.getStylesheetListMappings().get(stylesheetListNr));
+		}
+		
+	}
+	
+	
+	/* *****************************************
+	 *   DOCUMENT CONTROL METHODS
+	 *   
+	 *   Handles -
+	 *   handleOpenGroup: 	Open groups		- '{'
+	 *   handleCloseGroup: 	Close groups	- '}'
+	 *   handleCtrlWord: 	Ctrl Words		- '\...'
+	 *   handleCharacter: 	Characters		- Plain Text, etc.
+	 * 
+	 */
+	
+	/**
+	 * Handles open group tokens. ({)
+	 * 
+	 * @return errOK if ok, other if an error occurred.
+	 * @since 2.1.3
+	 */
+	public int handleOpenGroup() {
+		int result = errOK;
+		this.openGroupCount++;	// stats
+		this.groupLevel++;		// current group level in tokeniser
+		this.docGroupLevel++;	// current group level in document
+		if (this.getTokeniserState() == TOKENISER_SKIP_GROUP) { 
+			this.groupSkippedCount++;
+		}
+	
+		RtfDestination dest = this.getCurrentDestination();
+		boolean handled = false;
+		
+		if(dest != null) {
+			if(debugParser) {
+				RtfParser.outputDebug(this.rtfDoc, groupLevel, "DEBUG: before dest.handleOpeningSubGroup()");
+				RtfParser.outputDebug(this.rtfDoc, groupLevel, "DEBUG: destination=" + dest.toString());
+			}
+			handled = dest.handleOpeningSubGroup();
+			if(debugParser) {
+				RtfParser.outputDebug(this.rtfDoc, groupLevel, "DEBUG: after dest.handleOpeningSubGroup()");
+			}
+		}
+
+		this.stackState.push(this.currentState);
+		this.currentState = new RtfParserState(this.currentState);
+		// do not set this true until after the state is pushed
+		// otherwise it inserts a { where one does not belong.
+		this.currentState.newGroup = true;
+		dest = this.getCurrentDestination();
+		
+		if(debugParser) {
+			RtfParser.outputDebug(this.rtfDoc, groupLevel, "DEBUG: handleOpenGroup()");
+			if(this.lastCtrlWordParam != null)
+				RtfParser.outputDebug(this.rtfDoc, groupLevel, "DEBUG: LastCtrlWord=" + this.lastCtrlWordParam.ctrlWord);
+			RtfParser.outputDebug(this.rtfDoc, groupLevel, "DEBUG: grouplevel=" + Integer.toString(groupLevel));
+			RtfParser.outputDebug(this.rtfDoc, groupLevel, "DEBUG: destination=" + dest.toString());
+		}
+
+		if(dest != null) {
+			handled = dest.handleOpenGroup();
+		}
+		
+		if(debugParser) {
+			RtfParser.outputDebug(this.rtfDoc, groupLevel, "DEBUG: after dest.handleOpenGroup(); handled=" + Boolean.toString(handled));
+		}
+		
+		return result;
+	}
+	public static void outputDebug(Object doc, int groupLevel, String str) {
+		System.out.println(str);
+		if(doc == null) return;
+		if(groupLevel<0) groupLevel = 0;
+		char[] a; Arrays.fill(a= new char[groupLevel*2], ' ');
+		String spaces= new String(a);
+		if(doc instanceof RtfDocument) {
+			((RtfDocument)doc).add(new RtfDirectContent("\n" + spaces + str));
+		}
+		else
+			if(doc instanceof Document) {
+				try {
+					((Document)doc).add(new RtfDirectContent("\n" + spaces + str));
+				} catch (DocumentException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				}
+			}
+	}
+	/**
+	 * Handles close group tokens. (})
+	 * 
+	 * @return errOK if ok, other if an error occurred.
+	 * @since 2.1.3
+	 */
+	public int handleCloseGroup() {
+		int result = errOK;
+		this.closeGroupCount++;	// stats
+
+		if (this.getTokeniserState() != TOKENISER_SKIP_GROUP) {
+			if(debugParser) {
+				RtfParser.outputDebug(this.rtfDoc, groupLevel, "DEBUG: handleCloseGroup()");
+				if(this.lastCtrlWordParam != null)
+					RtfParser.outputDebug(this.rtfDoc, groupLevel, "DEBUG: LastCtrlWord=" + this.lastCtrlWordParam.ctrlWord);
+				RtfParser.outputDebug(this.rtfDoc, groupLevel, "DEBUG: grouplevel=" + Integer.toString(groupLevel));
+				RtfParser.outputDebug(this.rtfDoc, groupLevel, "DEBUG: destination=" + this.getCurrentDestination().toString());
+				RtfParser.outputDebug(this.rtfDoc, groupLevel, "");
+			}
+			RtfDestination dest = this.getCurrentDestination();
+			boolean handled = false;
+			
+			if(dest != null) {
+				handled = dest.handleCloseGroup();
+			}
+			if(debugParser) {
+				RtfParser.outputDebug(this.rtfDoc, groupLevel, "DEBUG: After dest.handleCloseGroup(); handled = " + Boolean.toString(handled));
+				RtfParser.outputDebug(this.rtfDoc, groupLevel, "");
+			}
+		}
+		
+		if(this.stackState.size() >0 ) {
+			this.currentState = (RtfParserState)this.stackState.pop();
+		} else {
+			result = errStackUnderflow;
+		}
+		
+		this.docGroupLevel--;
+		this.groupLevel--;
+		
+		if (this.getTokeniserState() == TOKENISER_SKIP_GROUP && this.groupLevel < this.skipGroupLevel) {
+			this.setTokeniserState(TOKENISER_NORMAL);
+		}
+
+		return result;	
+	}
+	
+
+	/**
+	 * Handles control word tokens. Depending on the current
+	 * state a control word can lead to a state change. When
+	 * parsing the actual document contents, certain tabled
+	 * values are remapped. i.e. colors, fonts, styles, etc.
+	 * 
+	 * @param ctrlWordData The control word to handle.
+	 * @return errOK if ok, other if an error occurred.
+	 * @since 2.1.3
+	 */
+	public int handleCtrlWord(RtfCtrlWordData ctrlWordData) {
+		int result = errOK;
+		this.ctrlWordCount++; // stats
+
+		if(debugParser) {
+			RtfParser.outputDebug(this.rtfDoc, groupLevel, "DEBUG: handleCtrlWord=" + ctrlWordData.ctrlWord + " param=[" + ctrlWordData.param + "]");
+		}
+
+		if (this.getTokeniserState() == TOKENISER_SKIP_GROUP) { 
+			this.ctrlWordSkippedCount++;
+			if(debugParser) {
+				RtfParser.outputDebug(this.rtfDoc, groupLevel, "DEBUG: SKIPPED");
+			}
+			return result;
+		}
+
+		//		RtfDestination dest = (RtfDestination)this.getCurrentDestination();
+//		boolean handled = false;
+//		if(dest != null) {
+//			handled = dest.handleControlWord(ctrlWordData);
+//		}
+		
+		result = this.rtfKeywordMgr.handleKeyword(ctrlWordData, this.groupLevel);
+
+		if( result == errOK){
+			this.ctrlWordHandledCount++;
+		} else {
+			this.ctrlWordNotHandledCount++;
+			result = errOK;	// hack for now.
+		}
+		
+		return result;
+	}
+
+	/**
+	 * Handles text tokens. These are either handed on to the
+	 * appropriate destination handler.
+	 * 
+	 * @param nextChar
+	 * 		The text token to handle.
+	 * @return errOK if ok, other if an error occurred. 
+	 * @since 2.1.3
+	 */
+//	public int handleCharacter(char[] nextChar) {		
+	public int handleCharacter(int nextChar) {		
+		this.characterCount++;	// stats
+
+		if (this.getTokeniserState() == TOKENISER_SKIP_GROUP) { 
+			return errOK;
+		}
+
+		boolean handled = false;
+
+		RtfDestination dest = this.getCurrentDestination();
+		if(dest != null) {
+			handled = dest.handleCharacter(nextChar);
+		}
+
+		return errOK;
+	}
+
+	/**
+	 * Get the state of the parser.
+	 *
+	 * @return
+	 * 		The current RtfParserState state object.
+	 * @since 2.1.3
+	 */
+	public RtfParserState getState(){
+		return this.currentState;
+	}	
+
+	/**
+	 * Get the current state of the parser.
+	 * 
+	 * @return 
+	 * 		The current state of the parser.
+	 * @since 2.1.3
+	 */
+	public int getParserState(){
+		return this.currentState.parserState;
+	}
+	
+	/**
+	 * Set the state value of the parser.
+	 *
+	 * @param newState
+	 * 		The new state for the parser
+	 * @return
+	 * 		The state of the parser.
+	 * @since 2.1.3
+	 */
+	public int setParserState(int newState){
+		this.currentState.parserState = newState;
+		return this.currentState.parserState;
+	}
+
+	/**
+	 * Get the conversion type.
+	 * 
+	 * @return
+	 * 		The type of the conversion. Import or Convert.
+	 * @since 2.1.3
+	 */
+	public int getConversionType() {
+		return this.conversionType;
+	}
+	
+	/**
+	 * Get the RTF Document object.
+	 * @return
+	 * 		Returns the object rtfDoc.
+	 * @since 2.1.3
+	 */
+	public RtfDocument getRtfDocument() {
+		return this.rtfDoc;
+	}
+	
+	/**
+	 * Get the Document object.
+	 * @return
+	 * 		Returns the object rtfDoc.
+	 * @since 2.1.3
+	 */
+	public Document getDocument() {
+		return this.document;
+	}
+
+	/**
+	 * Get the RtfImportHeader object.
+	 * @return
+	 * 		Returns the object importHeader.
+	 * @since 2.1.3
+	 */
+	public RtfImportMgr getImportManager() {
+		return importMgr;
+	}
+	
+	
+	/////////////////////////////////////////////////////////////
+	// accessors for destinations
+	/**
+	 * Set the current destination object for the current state.
+	 * @param destination The destination value to set.
+	 * @since 2.1.3
+	 */
+	public boolean setCurrentDestination(String destination) {
+			RtfDestination dest = RtfDestinationMgr.getDestination(destination);
+			if(dest != null) {
+				this.currentState.destination = dest;
+				return false;
+			} else {
+				this.setTokeniserStateSkipGroup();
+				return false;
+			}
+	}
+	/**
+	 * Get the current destination object.
+	 * 
+	 * @return The current state destination
+	 * @since 2.1.3
+	 */
+	public RtfDestination getCurrentDestination() {
+		return this.currentState.destination;
+	}
+	/**
+	 * Get a destination from the map
+	 * 
+	 * @param destination The string destination.
+	 * @return The destination object from the map
+	 * @since 2.1.3
+	 */
+	public RtfDestination getDestination(String destination) {
+		return RtfDestinationMgr.getDestination(destination);
+	}
+	
+	/**
+	 * Helper method to determine if this is a new group.
+	 * 
+	 * @return true if this is a new group, otherwise it returns false.
+	 * @since 2.1.3
+	 */
+	public boolean isNewGroup() {
+		return this.currentState.newGroup;
+	}
+	/**
+	 * Helper method to set the new group flag
+	 * @param value The boolean value to set the flag
+	 * @return The value of newGroup
+	 * @since 2.1.3
+	 */
+	public boolean setNewGroup(boolean value) {
+		this.currentState.newGroup = value;
+		return this.currentState.newGroup;
+	}
+	
+	/* ************
+	 *  TOKENISER *
+	 **************/
+	
+	/**
+	 * Read through the input file and parse the data stream into tokens.
+	 * 
+	 * @throws IOException on IO error.
+	 * @since 2.1.3
+	 */	
+	public void tokenise() throws IOException {
+		int errorCode = errOK;	// error code
+		int nextChar = 0;
+//		char[] nextChar = new char[1]; // input variable
+//		nextChar[0]=0;	// set to 0
+		this.setTokeniserState(TOKENISER_NORMAL);	// set initial tokeniser state
+		
+		
+//		while(this.pbReader.read(nextChar) != -1) {
+		while((nextChar = this.pbReader.read()) != -1) {
+			this.byteCount++;
+			
+	        if (this.getTokeniserState() == TOKENISER_BINARY)                      // if we're parsing binary data, handle it directly
+	        {
+	            if ((errorCode = parseChar(nextChar)) != errOK)
+	                return; 
+	        }  else {
+//				switch(nextChar[0]) {
+				switch(nextChar) {
+					case '{':	// scope delimiter - Open
+						this.handleOpenGroup();
+						break;
+					case '}':  // scope delimiter - Close
+						this.handleCloseGroup();
+						break;
+					case 0x0a:	// noise character
+					case 0x0d:	// noise character
+//						if(this.isImport()) {
+//							this.rtfDoc.add(new RtfDirectContent(new String(nextChar)));
+//						}
+						break;
+					case '\\':	// Control word start delimiter
+							if(parseCtrlWord(pbReader) != errOK) {
+							// TODO: Indicate some type of error
+							return;
+						}
+						break;
+					default:
+						if(groupLevel == 0) { // BOMs
+							break;
+						}
+						if(this.getTokeniserState() == TOKENISER_HEX) {
+							StringBuffer hexChars = new StringBuffer();
+							hexChars.append(nextChar);
+//							if(pbReader.read(nextChar) == -1) {
+							if((nextChar = pbReader.read()) == -1) {
+								return;
+							}
+							this.byteCount++;
+							hexChars.append(nextChar);
+	                    	try {
+//								nextChar[0]=(char)Integer.parseInt(hexChars.toString(), 16);
+								nextChar=Integer.parseInt(hexChars.toString(), 16);
+							} catch (NumberFormatException e) {
+								return;
+							}
+		                    this.setTokeniserState(TOKENISER_NORMAL);
+						}
+						if ((errorCode = parseChar(nextChar)) != errOK) {
+                        	return; // some error occurred. we should send a
+									// real error
+						}
+						break;
+				}	// switch(nextChar[0])
+			}	// end if (this.getTokeniserState() == TOKENISER_BINARY)
+	        
+//	        if(groupLevel < 1 && this.isImportFragment()) return; //return errOK;
+//	        if(groupLevel < 0 && this.isImportFull()) return; //return errStackUnderflow;
+//	        if(groupLevel < 0 && this.isConvert()) return; //return errStackUnderflow;
+	        
+		}// end while(reader.read(nextChar) != -1)
+		RtfDestination dest = this.getCurrentDestination();
+		if(dest != null) {
+			dest.closeDestination();
+		}
+	}
+	
+	/**
+	 * Process the character and send it to the current destination.
+	 * @param nextChar
+	 * 		The character to process
+	 * @return
+	 * 		Returns an error code or errOK if no error.
+	 * @since 2.1.3
+	 */
+	private int parseChar(int nextChar) {
+		// figure out where to put the character
+		// needs to handle group levels for parsing
+		// examples
+		/*
+		 * {\f3\froman\fcharset2\fprq2{\*\panose 05050102010706020507}Symbol;}
+		 * {\f7\fswiss\fcharset0\fprq2{\*\panose 020b0604020202030204}Helv{\*\falt Arial};} <- special case!!!!
+		 * {\f5\froman\fcharset0 Tahoma;}
+		 * {\f6\froman\fcharset0 Arial Black;}
+		 * {\info(\author name}{\company company name}}
+		 * ... document text ...
+		 */
+	    if (this.getTokeniserState() == TOKENISER_BINARY && --binByteCount <= 0)
+	    	this.setTokeniserStateNormal();
+	    if (this.getTokeniserState() == TOKENISER_SKIP_BYTES && --binSkipByteCount <= 0)
+	    	this.setTokeniserStateNormal();
+	    return this.handleCharacter(nextChar);
+	}
+	
+	/**
+	 * Parses a keyword and it's parameter if one exists
+	 * @param reader
+	 * 		This is a pushback reader for file input.
+	 * @return
+	 * 		Returns an error code or errOK if no error.
+	 * @throws IOException
+	 * 		Catch any file read problem.
+	 * @since 2.1.3
+	 */
+	private int parseCtrlWord(PushbackInputStream reader) throws IOException {
+		int nextChar = 0;
+		int result = errOK;
+		
+		if((nextChar = reader.read()) == -1) {
+			return errEndOfFile;
+		}
+		this.byteCount++;
+
+		StringBuffer parsedCtrlWord = new StringBuffer();
+		StringBuffer parsedParam= new StringBuffer();
+		RtfCtrlWordData ctrlWordParam = new RtfCtrlWordData();
+		
+		if(!Character.isLetterOrDigit((char)nextChar)) {
+			parsedCtrlWord.append((char)nextChar);
+			ctrlWordParam.ctrlWord = parsedCtrlWord.toString();
+			result =  this.handleCtrlWord(ctrlWordParam);
+			lastCtrlWordParam = ctrlWordParam;
+			return result;
+		}
+		
+		do {
+			parsedCtrlWord.append((char)nextChar);
+			//TODO: catch EOF
+			nextChar = reader.read();
+			this.byteCount++;
+		} while  (Character.isLetter((char)nextChar));
+		
+		ctrlWordParam.ctrlWord = parsedCtrlWord.toString();
+
+		if(nextChar == '-') {
+			ctrlWordParam.isNeg = true;
+			if((nextChar = reader.read()) == -1) {
+					return errEndOfFile;
+			}
+			this.byteCount++;
+		}
+		
+
+		if(Character.isDigit((char)nextChar)) {
+			ctrlWordParam.hasParam = true;
+			do {
+				parsedParam.append((char)nextChar);
+				//TODO: catch EOF
+				nextChar = reader.read();
+				this.byteCount++;
+				} while  (Character.isDigit((char)nextChar));
+						
+			ctrlWordParam.param = parsedParam.toString();
+		}
+		
+		// push this character back into the stream
+		if(nextChar != ' ') { 
+			reader.unread(nextChar);
+		}
+		
+	    if(debugParser) {
+	//	    // debug: insrsid6254399
+	//	    if(ctrlWordParam.ctrlWord.equals("proptype") && ctrlWordParam.param.equals("30")) {
+	//	    	System.out.print("Debug value found\n");
+	//	    }
+//		    if(ctrlWordParam.ctrlWord.equals("cf") ) {
+//		    	System.out.print("Debug value found\n");
+//		    }
+	    }
+	    
+		result = this.handleCtrlWord(ctrlWordParam);
+		lastCtrlWordParam = ctrlWordParam;
+		return result;
+
+	}
+	
+	/**
+	 * Set the current state of the tokeniser.
+	 * @param value The new state of the tokeniser.
+	 * @return The state of the tokeniser.
+	 * @since 2.1.3
+	 */
+	public int setTokeniserState(int value) {
+		this.currentState.tokeniserState = value;
+		return this.currentState.tokeniserState;
+	}
+	
+	/**
+	 * Get the current state of the tokeniser.
+	 * @return The current state of the tokeniser.
+	 * @since 2.1.3
+	 */
+	public int getTokeniserState() {
+		return this.currentState.tokeniserState;
+	}
+
+	/**
+	 * Gets the current group level
+	 * 
+	 * @return
+	 * 		The current group level value.
+	 * @since 2.1.3
+	 */
+	public int getLevel() {
+		return this.groupLevel;
+	}
+	
+
+	/**
+	 * Set the tokeniser state to skip to the end of the group.
+	 * Sets the state to TOKENISER_SKIP_GROUP and skipGroupLevel to the current group level.
+	 * @since 2.1.3
+	 */
+	public void setTokeniserStateNormal() {
+		this.setTokeniserState(TOKENISER_NORMAL);
+	}
+
+	/**
+	 * Set the tokeniser state to skip to the end of the group.
+	 * Sets the state to TOKENISER_SKIP_GROUP and skipGroupLevel to the current group level.
+	 * @since 2.1.3
+	 */
+	public void setTokeniserStateSkipGroup() {
+		this.setTokeniserState(TOKENISER_SKIP_GROUP);
+		this.skipGroupLevel = this.groupLevel;
+	}
+	
+	/**
+	 * Sets the number of bytes to skip and the state of the tokeniser.
+	 * 
+	 * @param numberOfBytesToSkip
+	 * 			The numbere of bytes to skip in the file.
+	 * @since 2.1.3
+	 */
+	public void setTokeniserSkipBytes(long numberOfBytesToSkip) {
+		this.setTokeniserState(TOKENISER_SKIP_BYTES);
+		this.binSkipByteCount = numberOfBytesToSkip;
+	}
+	
+	/**
+	 * Sets the number of binary bytes.
+	 * 
+	 * @param binaryCount
+	 * 			The number of binary bytes.
+	 * @since 2.1.3
+	 */
+	public void setTokeniserStateBinary(int binaryCount) {
+		this.setTokeniserState(TOKENISER_BINARY);
+		this.binByteCount = binaryCount;
+	}
+	/**
+	 * Sets the number of binary bytes.
+	 * 
+	 * @param binaryCount
+	 * 			The number of binary bytes.
+	 * @since 2.1.3
+	 */
+	public void setTokeniserStateBinary(long binaryCount) {
+		this.setTokeniserState(TOKENISER_BINARY);
+		this.binByteCount = binaryCount;
+	}
+	/**
+	 * Helper method to determin if conversion is TYPE_CONVERT
+	 * @return true if TYPE_CONVERT, otherwise false
+	 * @see com.lowagie.text.rtf.parser.RtfParser#TYPE_CONVERT
+	 * @since 2.1.3
+	 */
+	public boolean isConvert() {
+		return (this.getConversionType() == RtfParser.TYPE_CONVERT);
+	}
+	
+	/**
+	 * Helper method to determin if conversion is TYPE_IMPORT_FULL or TYPE_IMPORT_FRAGMENT
+	 * @return true if TYPE_CONVERT, otherwise false
+	 * @see com.lowagie.text.rtf.parser.RtfParser#TYPE_IMPORT_FULL
+	 * @see com.lowagie.text.rtf.parser.RtfParser#TYPE_IMPORT_FRAGMENT
+	 * @since 2.1.3
+	 */
+	public boolean isImport() {
+		return (isImportFull() || this.isImportFragment());
+	}
+	/**
+	 * Helper method to determin if conversion is TYPE_IMPORT_FULL
+	 * @return true if TYPE_CONVERT, otherwise false
+	 * @see com.lowagie.text.rtf.parser.RtfParser#TYPE_IMPORT_FULL
+	 * @since 2.1.3
+	 */
+	public boolean isImportFull() {
+		return (this.getConversionType() == RtfParser.TYPE_IMPORT_FULL);
+	}
+	/**
+	 * Helper method to determin if conversion is TYPE_IMPORT_FRAGMENT
+	 * @return true if TYPE_CONVERT, otherwise false
+	 * @see com.lowagie.text.rtf.parser.RtfParser#TYPE_IMPORT_FRAGMENT
+	 * @since 2.1.3
+	 */
+	public boolean isImportFragment() {
+		return (this.getConversionType() == RtfParser.TYPE_IMPORT_FRAGMENT);
+	}
+	/**
+	 * Helper method to indicate if this control word was a \* control word.
+	 * @return true if it was a \* control word, otherwise false
+	 * @since 2.1.3
+	 */
+	public boolean getExtendedDestination() {
+		return this.currentState.isExtendedDestination;
+	}
+	/**
+	 * Helper method to set the extended control word flag.
+	 * @param value Boolean to set the value to.
+	 * @return isExtendedDestination.
+	 * @since 2.1.3
+	 */
+	public boolean setExtendedDestination(boolean value) {
+		this.currentState.isExtendedDestination = value;
+		return this.currentState.isExtendedDestination;
+	}
+
+	/**
+	 * Get the logfile name.
+	 * 
+	 * @return the logFile
+	 * @since 2.1.3
+	 */
+	public String getLogFile() {
+		return logFile;
+	}
+
+	/**
+	 * Set the logFile name
+	 * 
+	 * @param logFile the logFile to set
+	 * @since 2.1.3
+	 */
+	public void setLogFile(String logFile) {
+		this.logFile = logFile;
+	}
+	/**
+	 * Set the logFile name
+	 * 
+	 * @param logFile the logFile to set
+	 * @since 2.1.3
+	 */
+	public void setLogFile(String logFile, boolean logAppend) {
+		this.logFile = logFile;
+		this.setLogAppend(logAppend);
+	}
+
+	/**
+	 * Get flag indicating if logging is on or off.
+	 * 
+	 * @return the logging
+	 * @since 2.1.3
+	 */
+	public boolean isLogging() {
+		return logging;
+	}
+
+	/**
+	 * Set flag indicating if logging is on or off
+	 * @param logging <code>true</code> to turn on logging, <code>false</code> to turn off logging.
+	 * @since 2.1.3
+	 */
+	public void setLogging(boolean logging) {
+		this.logging = logging;
+	}
+
+	/**
+	 * @return the logAppend
+	 * @since 2.1.3
+	 */
+	public boolean isLogAppend() {
+		return logAppend;
+	}
+
+	/**
+	 * @param logAppend the logAppend to set
+	 * @since 2.1.3
+	 */
+	public void setLogAppend(boolean logAppend) {
+		this.logAppend = logAppend;
+	}
+
+/*	
+ *	Statistics
+ *
+ 	public void printStats(PrintStream out) {
+		if(out == null) return;
+		
+		out.println("");
+		out.println("Parser statistics:");
+		out.println("Process start date: " + startDate.toLocaleString());
+		out.println("Process end date  : " + endDate.toLocaleString());
+		out.println("  Elapsed time    : " + Long.toString(endTime - startTime) + " milliseconds.");
+		out.println("Total bytes read  : " + Long.toString(byteCount));
+		out.println("Open group count  : " + Long.toString(openGroupCount));
+		out.print("Close group count : " + Long.toString(closeGroupCount));
+		out.println(" (Groups Skipped): " + Long.toString(groupSkippedCount));
+		out.print("Control word count: " + Long.toString(ctrlWordCount));
+		out.print(" - Handled: " + Long.toString(ctrlWordHandledCount));
+		out.print(" Not Handled: " + Long.toString(ctrlWordNotHandledCount));
+		out.println(" Skipped: " + Long.toString(ctrlWordSkippedCount));
+		out.println("Plain text char count: " + Long.toString(characterCount));		
+	}*/
+}
Index: src/core/com/lowagie/text/rtf/list/RtfPictureList.java
===================================================================
--- src/core/com/lowagie/text/rtf/list/RtfPictureList.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/list/RtfPictureList.java	(revision 0)
@@ -0,0 +1,96 @@
+/*
+ * $Id: RtfPictureList.java 3580 2008-08-06 15:52:00Z howard_s $
+ *
+ * Copyright 2008 Howard Shank (hgshank@yahoo.com)
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.rtf.list;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import com.lowagie.text.DocWriter;
+import com.lowagie.text.rtf.RtfElement;
+import com.lowagie.text.rtf.RtfExtendedElement;
+import com.lowagie.text.rtf.document.RtfDocument;
+
+
+/**
+ * The RtfPictureList2 manages the pictures for lists.
+ * 
+ * @version $Id: RtfPictureList.java 3580 2008-08-06 15:52:00Z howard_s $
+ * @author Howard Shank (hgshank@yahoo.com)
+ * @since 2.1.3
+ */
+public class RtfPictureList  extends RtfElement implements RtfExtendedElement {
+    /**
+     * Constant for determining which picture bullet from the \listpicture destination that should be applied.
+     */
+    private static final byte[] LIST_LEVEL_PICTURE = DocWriter.getISOBytes("\\*\\listpicture");
+
+	public RtfPictureList(RtfDocument doc) {
+		super(doc);
+	}
+	/* (non-Javadoc)
+	 * @see com.lowagie.text.rtf.RtfElement#writeContent(java.io.OutputStream)
+	 */
+	public void writeContent(OutputStream out) throws IOException {
+		// TODO Auto-generated method stub
+		
+	}
+
+	/* (non-Javadoc)
+	 * @see com.lowagie.text.rtf.RtfExtendedElement#writeDefinition(java.io.OutputStream)
+	 */
+	public void writeDefinition(final OutputStream result) throws IOException {
+		// TODO Auto-generated method stub
+		result.write(OPEN_GROUP);
+		result.write(LIST_LEVEL_PICTURE);
+		// if there are elements, write the \shppictlist here
+		result.write(CLOSE_GROUP);
+	}
+
+}
Index: src/core/com/lowagie/text/rtf/text/RtfTab.java
===================================================================
--- src/core/com/lowagie/text/rtf/text/RtfTab.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/text/RtfTab.java	(revision 0)
@@ -0,0 +1,137 @@
+/*
+ * $Id: RtfTab.java 3580 2008-08-06 15:52:00Z howard_s $
+ *
+ * Copyright 2001, 2002, 2003, 2004 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ * Co-Developer of the code is Mark Hall. Portions created by the Co-Developer are
+ * Copyright (C) 2006 by Mark Hall. All Rights Reserved
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.rtf.text;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import com.lowagie.text.DocWriter;
+import com.lowagie.text.rtf.RtfAddableElement;
+
+/**
+ * The RtfTab encapsulates a tab position and tab type in a paragraph.
+ * To add tabs to a paragraph construct new RtfTab objects with the desired
+ * tab position and alignment and then add them to the paragraph. In the actual
+ * text the tabs are then defined as standard \t characters.<br /><br />
+ * 
+ * <code>RtfTab tab = new RtfTab(300, RtfTab.TAB_LEFT_ALIGN);<br />
+ * Paragraph para = new Paragraph();<br />
+ * para.add(tab);<br />
+ * para.add("This paragraph has a\ttab defined.");</code>
+ * 
+ * @version $Id: RtfTab.java 3580 2008-08-06 15:52:00Z howard_s $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Thomas Bickel (tmb99@inode.at)
+ */
+public class RtfTab extends RtfAddableElement {
+
+	/**
+	 * A tab where the text is left aligned.
+	 */
+	public static final int TAB_LEFT_ALIGN = 0;
+	/**
+	 * A tab where the text is center aligned.
+	 */
+	public static final int TAB_CENTER_ALIGN = 1;
+	/**
+	 * A tab where the text is right aligned.
+	 */
+	public static final int TAB_RIGHT_ALIGN = 2;
+	/**
+	 * A tab where the text is aligned on the decimal character. Which
+	 * character that is depends on the language settings of the viewer.
+	 */
+	public static final int TAB_DECIMAL_ALIGN = 3;
+	
+	/**
+	 * The tab position in twips.
+	 */
+	private int position = 0;
+	/**
+	 * The tab alignment.
+	 */
+	private int type = TAB_LEFT_ALIGN;
+	
+	/**
+	 * Constructs a new RtfTab with the given position and type. The position
+	 * is in standard iText points. The type is one of the tab alignment
+	 * constants defined in the RtfTab.
+	 * 
+	 * @param position The position of the tab in points.
+	 * @param type The tab type constant.
+	 */
+	public RtfTab(float position, int type) {
+		this.position = (int) Math.round(position * TWIPS_FACTOR);
+		switch(type) {
+		case TAB_LEFT_ALIGN: this.type = TAB_LEFT_ALIGN; break;
+		case TAB_CENTER_ALIGN: this.type = TAB_CENTER_ALIGN; break;
+		case TAB_RIGHT_ALIGN: this.type = TAB_RIGHT_ALIGN; break;
+		case TAB_DECIMAL_ALIGN: this.type = TAB_DECIMAL_ALIGN; break;
+		default: this.type = TAB_LEFT_ALIGN; break;
+		}
+	}
+	
+	/**
+	 * Writes the tab settings.
+	 */
+    public void writeContent(final OutputStream result) throws IOException
+    {
+    	switch(this.type) {
+    		case TAB_CENTER_ALIGN: result.write(DocWriter.getISOBytes("\\tqc")); break;
+    		case TAB_RIGHT_ALIGN: result.write(DocWriter.getISOBytes("\\tqr")); break;
+    		case TAB_DECIMAL_ALIGN: result.write(DocWriter.getISOBytes("\\tqdec")); break;
+        }
+        result.write(DocWriter.getISOBytes("\\tx"));
+        result.write(intToByteArray(this.position));    	
+    }
+	
+}
Index: src/core/com/lowagie/text/rtf/parser/exceptions/RtfUnknownCtrlWordException.java
===================================================================
--- src/core/com/lowagie/text/rtf/parser/exceptions/RtfUnknownCtrlWordException.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/parser/exceptions/RtfUnknownCtrlWordException.java	(revision 0)
@@ -0,0 +1,22 @@
+package com.lowagie.text.rtf.parser.exceptions;
+
+/**
+ * @since 2.1.0
+ */
+public class RtfUnknownCtrlWordException extends RtfParserException {
+
+	/**
+	 * Generated serial version UID.
+	 */
+	private static final long serialVersionUID = 7243046509505727849L;
+    
+    // constructors
+    
+    /**
+     * Constructs a <CODE>RtfParserException</CODE> whithout a message.
+     */
+    public RtfUnknownCtrlWordException() {
+        super("Unknown control word.");
+    }
+    
+}
Index: src/core/com/lowagie/text/rtf/field/RtfPageNumber.java
===================================================================
--- src/core/com/lowagie/text/rtf/field/RtfPageNumber.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/field/RtfPageNumber.java	(revision 0)
@@ -0,0 +1,129 @@
+/*
+ * $Id: RtfPageNumber.java 3580 2008-08-06 15:52:00Z howard_s $
+ *
+ * Copyright 2001, 2002, 2003, 2004 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.rtf.field;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import com.lowagie.text.DocWriter;
+import com.lowagie.text.Font;
+import com.lowagie.text.rtf.document.RtfDocument;
+
+
+/**
+ * The RtfPageNumber provides the page number field in rtf documents.
+ * 
+ * @version $Id: RtfPageNumber.java 3580 2008-08-06 15:52:00Z howard_s $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Steffen.Stundzig (Steffen.Stundzig@smb-tec.com)
+ * @author Thomas Bickel (tmb99@inode.at)
+ */
+public class RtfPageNumber extends RtfField {
+
+    /**
+     * Constant for the page number
+     */
+    private static final byte[] PAGE_NUMBER = DocWriter.getISOBytes("PAGE");
+    
+    /**
+     * Constructs a RtfPageNumber. This can be added anywhere to add a page number field.
+     */
+    public RtfPageNumber() {
+        super(null);
+    }
+    
+    /**
+     * Constructs a RtfPageNumber with a specified Font. This can be added anywhere to
+     * add a page number field.
+     * @param font
+     */
+    public RtfPageNumber(Font font) {
+        super(null, font);
+    }
+    
+    /**
+     * Constructs a RtfPageNumber object.
+     * 
+     * @param doc The RtfDocument this RtfPageNumber belongs to
+     */
+    public RtfPageNumber(RtfDocument doc) {
+        super(doc);
+    }
+    
+    /**
+     * Constructs a RtfPageNumber object with a specific font.
+     * 
+     * @param doc The RtfDocument this RtfPageNumber belongs to
+     * @param font The Font to use
+     */
+    public RtfPageNumber(RtfDocument doc, Font font) {
+        super(doc, font);
+    }
+    
+    /**
+     * Writes the field instruction content
+     *
+     * @param result The <code>OutputStream</code> to write to.
+     * @throws IOException on i/o errors.
+     */
+    protected void writeFieldInstContent(final OutputStream result) throws IOException 
+    {
+    	result.write(PAGE_NUMBER);
+    }
+    
+    /**
+     * Writes the field result content
+     * 
+     * @param result The <code>OutputStream</code> to write to.
+     * @throws IOException on i/o errors.
+     */
+    protected void writeFieldResultContent(final OutputStream result) throws IOException {        
+    }
+}
Index: src/core/com/lowagie/text/rtf/parser/ctrlwords/RtfCtrlWordType.java
===================================================================
--- src/core/com/lowagie/text/rtf/parser/ctrlwords/RtfCtrlWordType.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/parser/ctrlwords/RtfCtrlWordType.java	(revision 0)
@@ -0,0 +1,93 @@
+/* $Id: RtfCtrlWordType.java 3373 2008-05-12 16:21:24Z xlv $
+ *
+ * Copyright 2007 by Howard Shank (hgshank@yahoo.com)
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+package com.lowagie.text.rtf.parser.ctrlwords;
+/**
+ * <code>RtfCtrlWordType</code> indicates the type of control word.
+ * 
+ * RTF control words are divided up into:
+ * 	Destination, Flag, Value, Toggle, Symbol.
+ *
+ * Destination: The current destination for values and text to be sent.
+ * Flag: 0/1 value types. Represents true/false, on/off value types.
+ * Toggle: Flips a Flag value on/off.
+ * Value: an Integer value data type. (Exception: Some control words this is a long data value type)
+ * Symbol: Special RTF characters such as \{, \} and others.
+ * 
+ * @author Howard Shank (hgshank@yahoo.com)
+ * @since 2.0.8
+ */
+public final class RtfCtrlWordType {
+	/**
+	 * Control word is unidentified.
+	 */
+	public static final int UNIDENTIFIED = -1;
+	/**
+	 * Control word is a destination.
+	 */
+	public static final int DESTINATION = 0;
+	/**
+	 * Control word is a newer destination.
+	 */
+	public static final int DESTINATION_EX = 1;
+	/**
+	 * Control word is a flag.
+	 */
+	public static final int FLAG = 2;
+	/**
+	 * Control word is a value.
+	 */
+	public static final int VALUE = 3;
+	/**
+	 * Control word is a flag toggle.
+	 */
+	public static final int TOGGLE = 4;
+	/**
+	 * Control word is a special symbol.
+	 */
+	public static final int SYMBOL = 5;
+}
Index: src/core/com/lowagie/text/rtf/field/RtfField.java
===================================================================
--- src/core/com/lowagie/text/rtf/field/RtfField.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/field/RtfField.java	(revision 0)
@@ -0,0 +1,440 @@
+/*
+ * $Id: RtfField.java 3580 2008-08-06 15:52:00Z howard_s $
+ *
+ * Copyright 2004 by Mark Hall
+ * Uses code Copyright 2002
+ *   <a href="http://www.smb-tec.com">SMB</a> 
+ *   Dirk Weigenand (Dirk.Weigenand@smb-tec.com)
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.rtf.field;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import com.lowagie.text.Chunk;
+import com.lowagie.text.DocWriter;
+import com.lowagie.text.Font;
+import com.lowagie.text.rtf.RtfBasicElement;
+import com.lowagie.text.rtf.document.RtfDocument;
+import com.lowagie.text.rtf.style.RtfFont;
+
+
+/**
+ * The RtfField class is an abstract base class for all rtf field functionality.
+ * Subclasses only need to implement the two abstract methods writeFieldInstContent
+ * and writeFieldResultContent. All other field functionality is handled by the
+ * RtfField class.
+ * 
+ * @version $Id: RtfField.java 3580 2008-08-06 15:52:00Z howard_s $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Dirk Weigenand (Dirk.Weigenand@smb-tec.com)
+ * @author Thomas Bickel (tmb99@inode.at)
+ */
+public abstract class RtfField extends Chunk implements RtfBasicElement {
+
+    /**
+     * Constant for a rtf field
+     */
+    private static final byte[] FIELD = DocWriter.getISOBytes("\\field");
+    /**
+     * Constant for a dirty field
+     */
+    private static final byte[] FIELD_DIRTY = DocWriter.getISOBytes("\\flddirty");
+    /**
+     * Constant for a private field
+     */
+    private static final byte[] FIELD_PRIVATE = DocWriter.getISOBytes("\\fldpriv");
+    /**
+     * Constant for a locked field
+     */
+    private static final byte[] FIELD_LOCKED = DocWriter.getISOBytes("\\fldlock");
+    /**
+     * Constant for a edited field
+     */
+    private static final byte[] FIELD_EDIT = DocWriter.getISOBytes("\\fldedit");
+    /**
+     * Constant for an alt field
+     */
+    private static final byte[] FIELD_ALT = DocWriter.getISOBytes("\\fldalt");
+    /**
+     * Constant for the field instructions
+     */
+    private static final byte[] FIELD_INSTRUCTIONS = DocWriter.getISOBytes("\\*\\fldinst");
+    /**
+     * Constant for the field result
+     */
+    private static final byte[] FIELD_RESULT = DocWriter.getISOBytes("\\fldrslt");
+
+    /**
+     * Is the field dirty
+     */
+    private boolean fieldDirty = false;
+    /**
+     * Is the field edited
+     */
+    private boolean fieldEdit = false;
+    /**
+     * Is the field locked
+     */
+    private boolean fieldLocked = false;
+    /**
+     * Is the field private
+     */
+    private boolean fieldPrivate = false;
+    /**
+     * Is it an alt field
+     */
+    private boolean fieldAlt = false;
+    /**
+     * Whether this RtfField is in a table
+     */
+    private boolean inTable = false;
+    /**
+     * Whether this RtfElement is in a header
+     */
+    private boolean inHeader = false;
+    /**
+     * The RtfDocument this RtfField belongs to 
+     */
+    protected RtfDocument document = null;
+    /**
+     * The RtfFont of this RtfField
+     */
+    private RtfFont font = null;
+
+    /**
+     * Constructs a RtfField for a RtfDocument. This is not very useful,
+     * since the RtfField by itself does not do anything. Use one of the
+     * subclasses instead.
+     * 
+     * @param doc The RtfDocument this RtfField belongs to.
+     */
+    protected RtfField(RtfDocument doc) {
+        this(doc, new Font());
+    }
+    
+    /**
+     * Constructs a RtfField for a RtfDocument. This is not very useful,
+     * since the RtfField by itself does not do anything. Use one of the
+     * subclasses instead.
+     * 
+     * @param doc The RtfDocument this RtfField belongs to.
+     * @param font The Font this RtfField should use
+     */
+    protected RtfField(RtfDocument doc, Font font) {
+        super("", font);
+        this.document = doc;
+        this.font = new RtfFont(this.document, font);
+    }
+    
+    /**
+     * Sets the RtfDocument this RtfElement belongs to
+     * 
+     * @param doc The RtfDocument to use
+     */
+    public void setRtfDocument(RtfDocument doc) {
+        this.document = doc;
+        this.font.setRtfDocument(this.document);
+    }
+    
+    /**
+     * Writes the field beginning. Also writes field properties.
+     * 
+     * @param result The <code>OutputStream</code> to write to.
+     * @throws IOException
+     */
+    private void writeFieldBegin(OutputStream result) throws IOException 
+    {
+        result.write(OPEN_GROUP);
+        result.write(FIELD);
+        if(fieldDirty) result.write(FIELD_DIRTY);
+        if(fieldEdit) result.write(FIELD_EDIT);
+        if(fieldLocked) result.write(FIELD_LOCKED);
+        if(fieldPrivate) result.write(FIELD_PRIVATE);
+    }
+    
+    /**
+     * Writes the beginning of the field instruction area.
+     * 
+     * @param result The <code>OutputStream</code> to write to.
+     * @throws IOException
+     */
+    private void writeFieldInstBegin(OutputStream result) throws IOException 
+    {
+        result.write(OPEN_GROUP);        
+        result.write(FIELD_INSTRUCTIONS);
+        result.write(DELIMITER);
+    }
+    
+    /**
+     * Writes the content of the field instruction area. Override this
+     * method in your subclasses.
+     * 
+     * @param result The <code>OutputStream</code> to write to.
+     */
+    protected abstract void writeFieldInstContent(OutputStream result) throws IOException;
+    
+    /**
+     * Writes the end of the field instruction area.
+     * 
+     * @param result The <code>OutputStream</code> to write to.
+     */
+    private void writeFieldInstEnd(OutputStream result) throws IOException 
+    {
+        if(fieldAlt) {
+            result.write(DELIMITER);
+            result.write(FIELD_ALT);
+        }
+        result.write(CLOSE_GROUP);
+    }
+    
+    /**
+     * Writes the beginning of the field result area
+     * 
+     * @param result The <code>OutputStream</code> to write to.
+     */
+    private void writeFieldResultBegin(final OutputStream result) throws IOException 
+    {
+        result.write(OPEN_GROUP);
+        result.write(FIELD_RESULT);
+        result.write(DELIMITER);
+    }
+    
+    /**
+     * Writes the content of the pre-calculated field result. Override this
+     * method in your subclasses.
+     * 
+     * @param result The <code>OutputStream</code> to write to.
+     * @throws IOException on i/o errors.
+     */ 
+    protected abstract void writeFieldResultContent(OutputStream result) throws IOException;
+    
+    /**
+     * Writes the end of the field result area
+     * 
+     * @param result The <code>OutputStream</code> to write to.
+     * @throws IOException on i/o errors.
+     */ 
+    private void writeFieldResultEnd(final OutputStream result) throws IOException 
+    {
+        result.write(DELIMITER);
+        result.write(CLOSE_GROUP);
+    }
+    
+    /**
+     * Writes the end of the field
+     * 
+     * @param result The <code>OutputStream</code> to write to.
+     * @throws IOException on i/o errors.
+     */
+    private void writeFieldEnd(OutputStream result) throws IOException
+    {
+        result.write(CLOSE_GROUP);
+    }
+    
+    /**
+     * Writes the field to the <code>OutputStream</code>.
+     * 
+     * @param result The <code>OutputStream</code> to write to.
+     * @throws IOException on i/o errors.
+     */    
+    public void writeContent(final OutputStream result) throws IOException
+    {
+        this.font.writeBegin(result);
+        writeFieldBegin(result);
+        writeFieldInstBegin(result);
+        writeFieldInstContent(result);
+        writeFieldInstEnd(result);
+        writeFieldResultBegin(result);
+        writeFieldResultContent(result);
+        writeFieldResultEnd(result);
+        writeFieldEnd(result);
+        this.font.writeEnd(result);
+    }        
+        
+    /**
+     * Get whether this field is an alt field
+     * 
+     * @return Returns whether this field is an alt field
+     */
+    public boolean isFieldAlt() {
+        return fieldAlt;
+    }
+    
+    /**
+     * Set whether this field is an alt field
+     * 
+     * @param fieldAlt The value to use
+     */
+    public void setFieldAlt(boolean fieldAlt) {
+        this.fieldAlt = fieldAlt;
+    }
+    
+    /**
+     * Get whether this field is dirty
+     * 
+     * @return Returns whether this field is dirty
+     */
+    public boolean isFieldDirty() {
+        return fieldDirty;
+    }
+    
+    /**
+     * Set whether this field is dirty
+     * 
+     * @param fieldDirty The value to use
+     */
+    public void setFieldDirty(boolean fieldDirty) {
+        this.fieldDirty = fieldDirty;
+    }
+    
+    /**
+     * Get whether this field is edited
+     * 
+     * @return Returns whether this field is edited
+     */
+    public boolean isFieldEdit() {
+        return fieldEdit;
+    }
+    
+    /**
+     * Set whether this field is edited.
+     * 
+     * @param fieldEdit The value to use
+     */
+    public void setFieldEdit(boolean fieldEdit) {
+        this.fieldEdit = fieldEdit;
+    }
+    
+    /**
+     * Get whether this field is locked
+     * 
+     * @return Returns the fieldLocked.
+     */
+    public boolean isFieldLocked() {
+        return fieldLocked;
+    }
+    
+    /**
+     * Set whether this field is locked
+     * @param fieldLocked The value to use
+     */
+    public void setFieldLocked(boolean fieldLocked) {
+        this.fieldLocked = fieldLocked;
+    }
+    
+    /**
+     * Get whether this field is private
+     * 
+     * @return Returns the fieldPrivate.
+     */
+    public boolean isFieldPrivate() {
+        return fieldPrivate;
+    }
+    
+    /**
+     * Set whether this field is private
+     * 
+     * @param fieldPrivate The value to use
+     */
+    public void setFieldPrivate(boolean fieldPrivate) {
+        this.fieldPrivate = fieldPrivate;
+    }
+
+    /**
+     * Sets whether this RtfField is in a table
+     * 
+     * @param inTable <code>True</code> if this RtfField is in a table, <code>false</code> otherwise
+     */
+    public void setInTable(boolean inTable) {
+        this.inTable = inTable;
+    }
+    
+    /**
+     * Gets whether this <code>RtfField</code> is in a table.
+     * 
+     * @return <code>True</code> if this <code>RtfField</code> is in a table, <code>false</code> otherwise
+     * @since 2.1.0
+     */
+    public boolean isInTable() {
+        return this.inTable;
+    }
+    
+    /**
+     * Sets whether this RtfField is in a header
+     * 
+     * @param inHeader <code>True</code> if this RtfField is in a header, <code>false</code> otherwise
+     */
+    public void setInHeader(boolean inHeader) {
+        this.inHeader = inHeader;
+    }
+    
+    /**
+     * Gets whether this <code>RtfField</code> is in a header.
+     * 
+     * @return <code>True</code> if this <code>RtfField</code> is in a header, <code>false</code> otherwise
+     * @since 2.1.0
+     */
+    public boolean isInHeader() {
+        return this.inHeader;
+    }
+    
+    /**
+     * An RtfField is never empty.
+     */
+    public boolean isEmpty() {
+        return false;
+    }
+    
+    /**
+     * Override setFont to perform the correct font handling.
+     */
+    public void setFont(Font font) {
+        super.setFont(font);
+        this.font = new RtfFont(this.document, font);
+    }
+}
Index: src/core/com/lowagie/text/rtf/text/RtfAnnotation.java
===================================================================
--- src/core/com/lowagie/text/rtf/text/RtfAnnotation.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/text/RtfAnnotation.java	(revision 0)
@@ -0,0 +1,127 @@
+/*
+ * $Id: RtfAnnotation.java 3580 2008-08-06 15:52:00Z howard_s $
+ *
+ * Copyright 2001, 2002, 2003, 2004 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.rtf.text;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import com.lowagie.text.Annotation;
+import com.lowagie.text.DocWriter;
+import com.lowagie.text.rtf.RtfElement;
+import com.lowagie.text.rtf.document.RtfDocument;
+
+
+/**
+ * The RtfAnnotation provides support for adding Annotations to the rtf document.
+ * Only simple Annotations with Title / Content are supported.
+ * 
+ * @version $Id: RtfAnnotation.java 3580 2008-08-06 15:52:00Z howard_s $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Thomas Bickel (tmb99@inode.at)
+ */
+public class RtfAnnotation extends RtfElement {
+
+    /**
+     * Constant for the id of the annotation
+     */
+    private static final byte[] ANNOTATION_ID = DocWriter.getISOBytes("\\*\\atnid");
+    /**
+     * Constant for the author of the annotation
+     */
+    private static final byte[] ANNOTATION_AUTHOR = DocWriter.getISOBytes("\\*\\atnauthor");
+    /**
+     * Constant for the actual annotation
+     */
+    private static final byte[] ANNOTATION = DocWriter.getISOBytes("\\*\\annotation");
+    
+    /**
+     * The title of this RtfAnnotation
+     */
+    private String title = "";
+    /**
+     * The content of this RtfAnnotation
+     */
+    private String content = "";
+    
+    /**
+     * Constructs a RtfAnnotation based on an Annotation.
+     * 
+     * @param doc The RtfDocument this RtfAnnotation belongs to
+     * @param annotation The Annotation this RtfAnnotation is based off
+     */
+    public RtfAnnotation(RtfDocument doc, Annotation annotation) {
+        super(doc);
+        title = annotation.title();
+        content = annotation.content();
+    }
+    
+    /**
+     * Writes the content of the RtfAnnotation
+     */
+    public void writeContent(final OutputStream result) throws IOException
+    {
+        result.write(OPEN_GROUP);
+        result.write(ANNOTATION_ID);
+        result.write(DELIMITER);
+        result.write(intToByteArray(document.getRandomInt()));
+        result.write(CLOSE_GROUP);
+        result.write(OPEN_GROUP);
+        result.write(ANNOTATION_AUTHOR);
+        result.write(DELIMITER);
+        result.write(DocWriter.getISOBytes(title));
+        result.write(CLOSE_GROUP);
+        result.write(OPEN_GROUP);
+        result.write(ANNOTATION);
+        result.write(RtfParagraph.PARAGRAPH_DEFAULTS);
+        result.write(DELIMITER);
+        result.write(DocWriter.getISOBytes(content));
+        result.write(CLOSE_GROUP);    	
+    }
+}
Index: src/core/com/lowagie/text/rtf/parser/destinations/RtfDestinationFontTable.java
===================================================================
--- src/core/com/lowagie/text/rtf/parser/destinations/RtfDestinationFontTable.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/parser/destinations/RtfDestinationFontTable.java	(revision 0)
@@ -0,0 +1,614 @@
+/*
+ * $Id: RtfDestinationFontTable.java 3832 2009-04-04 13:18:12Z blowagie $
+ *
+ * Copyright 2007 by Howard Shank (hgshank@yahoo.com)
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+ 
+package com.lowagie.text.rtf.parser.destinations;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.util.HashMap;
+import java.util.Properties;
+
+import com.lowagie.text.Font;
+import com.lowagie.text.FontFactory;
+import com.lowagie.text.rtf.parser.RtfImportMgr;
+import com.lowagie.text.rtf.parser.RtfParser;
+import com.lowagie.text.rtf.parser.ctrlwords.RtfCtrlWordData;
+
+/**
+ * <code>RtfDestinationFontTable</code> handles data destined for the font table destination
+ * 
+ * @author Howard Shank (hgshank@yahoo.com)
+ *
+ * @since 2.0.8
+ */
+public final class RtfDestinationFontTable extends RtfDestination {
+	/**
+	 * The RtfImportHeader to add font mappings to.
+	 */
+	private RtfImportMgr importHeader = null;
+	/**
+	 * The theme (Office 2007)
+	 */
+	private String themeFont = "";
+	/**
+	 * The number of the font being parsed.
+	 */
+	private String fontNr = "";
+	/**
+	 * The family of the font being parsed.
+	 */
+	private String fontFamily = "";
+	/**
+	 * The \charset value
+	 */
+	private String charset = "";
+	private static final String CHARSET_DEFAULT = "0";
+	/**
+	 * The \fprq
+	 */
+	private int fprq = 0;
+	/**
+	 * The \*\panose font matching value if primary font is not available.
+	 */
+	private String panose = "";
+	/**
+	 * The \*\fname
+	 */
+	private String nontaggedname = "";
+	/**
+	 * The name of the font being parsed.
+	 */
+	private String fontName = "";
+	/**
+	 * The \falt alternate font if primary font is not available.
+	 */
+	private String falt = "";
+	/**
+	 * The \falt alternate font if primary font is not available.
+	 */
+	private String fontemb = "";
+	/**
+	 * The \falt alternate font if primary font is not available.
+	 */
+	private String fontType = "";
+	/**
+	 * The \falt alternate font if primary font is not available.
+	 */
+	private String fontFile = "";
+	/**
+	 * The \falt alternate font if primary font is not available.
+	 */
+	private String fontFileCpg = "";
+	/**
+	 * The \fbias value
+	 */
+	private int fbias = 0;
+	/**
+	 * The \cpg value
+	 */
+	private String cpg = "";
+	/**
+	 * The \fnil, \fttruetype value
+	 */
+	private String trueType = "";
+
+	/**
+	 * state flag to handle different parsing of a font element
+	 */
+	private int state = 0;
+	/* state values */
+	/** Normal 	 */
+	private static final int SETTING_NORMAL = 0;
+	/** \falt 	 */
+	private static final int SETTING_ALTERNATE = 1;
+	/** \fname 	 */
+	private static final int SETTING_FONTNAME = 2;
+	/** \panose 	 */
+	private static final int SETTING_PANOSE = 3;
+	/** \fontemb	*/
+	private static final int SETTING_FONT_EMBED = 4;
+	/** \ffile  */
+	private static final int SETTING_FONT_FILE = 5;
+	
+	/**
+	 * Convert font mapping to <code>FontFactory</code> font objects.
+	 */
+	private HashMap fontMap = null;
+	
+	/**
+	 * Constructor
+	 */
+	public RtfDestinationFontTable() {
+		super(null);
+	}
+	/**
+	 * Constructs a new RtfFontTableParser.
+	 * 
+	 * @param parser an RtfParser.
+	 * 
+	 * @since 2.0.8
+	 */
+	public RtfDestinationFontTable(RtfParser parser) {
+		super(parser);
+		this.init(true);
+	}
+	
+	/* (non-Javadoc)
+	 * @see com.lowagie.text.rtf.parser.destinations.RtfDestination#setParser(com.lowagie.text.rtf.parser.RtfParser)
+	 * 
+	 * @since 2.0.8
+	 */
+	public void setParser(RtfParser parser) {
+		if(this.rtfParser != null && this.rtfParser.equals(parser)) return;
+		this.rtfParser = parser;
+		this.init(true);
+	}
+	/**
+	 * Initialize the object.
+	 * 
+	 * @param importFonts true to import the fonts into the FontFactory, false do not load fonts
+	 * 
+	 * @since 2.0.8
+	 */
+	private void init(boolean importFonts) {
+		fontMap = new HashMap();
+		if(this.rtfParser != null) {
+			this.importHeader = this.rtfParser.getImportManager();
+		}
+		this.setToDefaults();
+		if(importFonts) {
+			importSystemFonts();
+		}
+	}
+	/* (non-Javadoc)
+	 * @see com.lowagie.text.rtf.parser.destinations.RtfDestination#handleOpenNewGroup()
+	 * 
+	 * @since 2.0.8
+	 */
+	public boolean handleOpeningSubGroup() {
+		return true;
+	}
+	/* (non-Javadoc)
+	 * @see com.lowagie.text.rtf.direct.RtfDestination#closeDestination()
+	 * 
+	 * @since 2.0.8
+	 */
+	public boolean closeDestination() {
+		return true;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.lowagie.text.rtf.direct.RtfDestination#handleGroupEnd()
+	 * 
+	 * @since 2.0.8
+	 */
+	public boolean handleCloseGroup() {
+		if(this.state == SETTING_NORMAL) {
+			processFont();
+		}
+		this.state = SETTING_NORMAL;
+		return true;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.lowagie.text.rtf.direct.RtfDestination#handleGroupStart()
+	 * 
+	 * @since 2.0.8
+	 */
+	public boolean handleOpenGroup() {
+
+		return true;
+	}
+	
+	/* (non-Javadoc)
+	 * @see com.lowagie.text.rtf.direct.RtfDestination#handleCharacter(char[])
+	 * 
+	 * @since 2.0.8
+	 */
+	public boolean handleCharacter(int ch) {
+		switch(this.state) {
+		case SETTING_NORMAL:
+			this.fontName += (char)ch;
+			break;
+		case SETTING_ALTERNATE:
+			this.falt += (char)ch;
+			break;
+		case SETTING_PANOSE:
+			this.panose += (char)ch;
+			break;
+		case SETTING_FONT_EMBED:
+			break;
+		case SETTING_FONT_FILE:
+			break;
+		case SETTING_FONTNAME:
+			break;
+			
+		}
+		return true;
+	}
+	/* (non-Javadoc)
+	 * @see com.lowagie.text.rtf.parser.destinations.RtfDestination#handleControlWord(com.lowagie.text.rtf.parser.ctrlwords.RtfCtrlWordData)
+	 * 
+	 * @since 2.0.8
+	 */
+	public boolean handleControlWord(RtfCtrlWordData ctrlWordData) {
+		boolean result = true;
+		// just let fonttbl fall through and set last ctrl word object.
+		
+		if(ctrlWordData.ctrlWord.equals("f")) { this.setFontNumber(ctrlWordData.param); result=true;}
+		if(ctrlWordData.ctrlWord.equals("fcharset")) { this.setCharset(ctrlWordData.param); result=true; }
+
+		// font families
+		if(ctrlWordData.ctrlWord.equals("fnil")) { this.setFontFamily("roman"); result=true; }
+		if(ctrlWordData.ctrlWord.equals("froman")) { this.setFontFamily("roman"); result=true; }
+		if(ctrlWordData.ctrlWord.equals("fswiss")) { this.setFontFamily("swiss"); result=true; }
+		if(ctrlWordData.ctrlWord.equals("fmodern")) { this.setFontFamily("modern"); result=true; }
+		if(ctrlWordData.ctrlWord.equals("fscript")) { this.setFontFamily("script"); result=true; }
+		if(ctrlWordData.ctrlWord.equals("fdecor")) { this.setFontFamily("decor"); result=true; }
+		if(ctrlWordData.ctrlWord.equals("ftech")) { this.setFontFamily("tech"); result=true; }
+		if(ctrlWordData.ctrlWord.equals("fbidi")) { this.setFontFamily("bidi"); result=true; }
+		// pitch
+		if(ctrlWordData.ctrlWord.equals("fprq")) { this.setPitch(ctrlWordData.param); result=true; }
+		// bias
+		if(ctrlWordData.ctrlWord.equals("fbias")) { this.setBias(ctrlWordData.param); result=true; }
+		// theme font information
+		if(ctrlWordData.ctrlWord.equals("flomajor")) { this.setThemeFont("flomajor"); result= true; }
+		if(ctrlWordData.ctrlWord.equals("fhimajor")) { this.setThemeFont("fhimajor"); result= true; }
+		if(ctrlWordData.ctrlWord.equals("fdbmajor")) { this.setThemeFont("fdbmajor"); result= true; }
+		if(ctrlWordData.ctrlWord.equals("fbimajor")) { this.setThemeFont("fbimajor"); result= true; }
+		if(ctrlWordData.ctrlWord.equals("flominor")) { this.setThemeFont("flominor"); result= true; }
+		if(ctrlWordData.ctrlWord.equals("fhiminor")) { this.setThemeFont("fhiminor"); result= true; }
+		if(ctrlWordData.ctrlWord.equals("fdbminor")) { this.setThemeFont("fdbminor"); result= true; }
+		if(ctrlWordData.ctrlWord.equals("fbiminor")) { this.setThemeFont("fbiminor"); result= true; }
+
+		// panose
+		if(ctrlWordData.ctrlWord.equals("panose")) {state = SETTING_PANOSE; result = true; }
+		
+		// \*\fname
+		// <font name> #PCDATA
+		if(ctrlWordData.ctrlWord.equals("fname")) {state = SETTING_FONTNAME; result = true; }
+
+		// \*\falt
+		if(ctrlWordData.ctrlWord.equals("falt")) { state = SETTING_ALTERNATE; result = true; }
+		
+		// \*\fontemb
+		if(ctrlWordData.ctrlWord.equals("fontemb")) { state = SETTING_FONT_EMBED; result = true; }
+
+		// font type
+		if(ctrlWordData.ctrlWord.equals("ftnil")) { this.setTrueType("ftnil"); result= true; }
+		if(ctrlWordData.ctrlWord.equals("fttruetype")) { this.setTrueType("fttruetype"); result= true; }
+		
+		// \*\fontfile
+		if(ctrlWordData.ctrlWord.equals("fontemb")) { state = SETTING_FONT_FILE; result = true; }
+
+		// codepage
+		if(ctrlWordData.ctrlWord.equals("cpg")) { this.setCodePage(ctrlWordData.param); result= true; }
+		
+		this.lastCtrlWord = ctrlWordData;
+		return result;
+	}
+	/**
+	 * Set the code page
+	 * @param value The code page value
+	 * 
+	 * @since 2.0.8
+	 */
+	public void setCodePage(String value) {
+		this.cpg = value;
+	}
+	/**
+	 * Set the TrueTtype type
+	 * @param value The type
+	 * 
+	 * @since 2.0.8
+	 */
+	public void setTrueType(String value) {
+		this.trueType = value;
+	}
+	/**
+	 * Set the font pitch
+	 * @param value Pitch value
+	 * 
+	 * @since 2.0.8
+	 */
+	public void setPitch(String value) {
+		this.fprq = Integer.parseInt(value);
+	}
+	/**
+	 * Set the font bias
+	 * @param value Bias value
+	 * 
+	 * @since 2.0.8
+	 */
+	public void setBias(String value) {
+		this.fbias = Integer.parseInt(value);
+	}
+	/**
+	 * Set the font theme
+	 * 
+	 * @param themeFont Theme value
+	 * 
+	 * @since 2.0.8
+	 */
+	public void setThemeFont(String themeFont) {
+		this.themeFont = themeFont;
+	}
+	/**
+	 * Set the font name to the parsed value.
+	 * 
+	 * @param fontName The font name.
+	 * 
+	 * @since 2.0.8
+	 */
+	public void setFontName(String fontName) {
+		this.fontName = fontName;
+	}
+	/**
+	 * Set the font family to the parsed value.
+	 * 
+	 * @param fontFamily The font family.
+	 * 
+	 * @since 2.0.8
+	 */
+	public void setFontFamily(String fontFamily) {
+		this.fontFamily = fontFamily;
+	}
+	/**
+	 * Set the font number to the parsed value.
+	 * This is used for mapping fonts to the new font numbers
+	 * 
+	 * @param fontNr The font number.
+	 * 
+	 * @since 2.0.8
+	 */
+	public void setFontNumber(String fontNr) {
+		this.fontNr = fontNr;
+	}
+	/**
+	 * Set the alternate font name.
+	 * 
+	 * @param fontAlternate The falt font value
+	 * 
+	 * @since 2.0.8
+	 */
+	public void setFontAlternate(String fontAlternate) {
+		this.falt = fontAlternate;
+	}
+	/**
+	 * Set the character-set to the parsed value.
+	 * 
+	 * @param charset The charset value
+	 * 
+	 * @since 2.0.8
+	 */
+	public void setCharset(String charset) {
+		if(charset.length() == 0) {
+			charset = CHARSET_DEFAULT;
+		}
+		this.charset = charset;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.lowagie.text.rtf.direct.RtfDestination#setDefaults()
+	 * 
+	 * @since 2.0.8
+	 */
+	public void setToDefaults() {
+		this.themeFont = "";
+		this.fontNr = "";
+		this.fontName = "";
+		this.fontFamily = "";
+		
+		this.charset = "";
+		this.fprq = 0;
+		this.panose = "";
+		this.nontaggedname = "";
+		this.falt = "";
+		this.fontemb = "";
+		this.fontType = "";
+		this.fontFile = "";
+		this.fontFileCpg = "";
+		this.fbias = 0;
+		this.cpg = "";
+		this.trueType = "";
+		this.state = SETTING_NORMAL;
+	}
+	/**
+	 * Process the font information that was parsed from the input.
+	 * 
+	 * @since 2.0.8
+	 */
+	private void processFont() {
+		this.fontName = this.fontName.trim();
+		if(fontName.length() == 0) return;
+		if(fontNr.length() == 0) return;
+		
+		if(fontName.length()>0 && fontName.indexOf(';') >= 0) {
+			fontName = fontName.substring(0,fontName.indexOf(';'));
+		}
+
+		if(this.rtfParser.isImport()) {
+			//TODO: If primary font fails, use the alternate
+				//TODO: Problem: RtfFont defaults family to \froman and doesn't allow any other family.
+				// if you set the family, it changes the font name and not the family in the Font.java class.
+				
+	//			if(this.fontFamily.length() > 0) {
+	//				if(this.importHeader.importFont(this.fontNr, this.fontName, this.fontFamily, Integer.parseInt(this.charset)) == false) {
+	//					if(this.falt.length() > 0) {
+	//						this.importHeader.importFont(this.fontNr, this.falt, this.fontFamily, Integer.parseInt(this.charset));
+	//					}
+	//				}
+	//			} else {
+					if(!this.importHeader.importFont(this.fontNr, this.fontName, Integer.parseInt("".equals(this.charset)?CHARSET_DEFAULT:this.charset))) {
+						if(this.falt.length() > 0) {
+							this.importHeader.importFont(this.fontNr, this.falt, Integer.parseInt("".equals(this.charset)?CHARSET_DEFAULT:this.charset));
+						}
+					}
+	//			}
+			}
+		if(this.rtfParser.isConvert()) {
+			// This could probably be written as a better font matching function
+			
+			String fName = this.fontName;	// work variable for trimming name if needed.
+			Font f1 = createfont(fName);
+			if(f1.getBaseFont() == null && this.falt.length()>0)
+				f1 = createfont(this.falt);
+			
+			if(f1.getBaseFont() == null) {
+				// Did not find a font, let's try a substring of the first name.
+				if(FontFactory.COURIER.indexOf(fName) > -1 ) {
+					f1 = FontFactory.getFont(FontFactory.COURIER);
+				} else if(FontFactory.HELVETICA.indexOf(fName) > -1 ) {
+					f1 = FontFactory.getFont(FontFactory.HELVETICA);
+				} else if(FontFactory.TIMES.indexOf(fName) > -1 ) {
+					f1 = FontFactory.getFont(FontFactory.TIMES);
+				} else if(FontFactory.SYMBOL.indexOf(fName) > -1 ) {
+					f1 = FontFactory.getFont(FontFactory.SYMBOL);
+				} else if(FontFactory.ZAPFDINGBATS.indexOf(fName) > -1 ) {
+					f1 = FontFactory.getFont(FontFactory.ZAPFDINGBATS);
+				} else {
+					// we did not find a matching font in any form.
+					// default to HELVETICA for now.
+					f1 = FontFactory.getFont(FontFactory.HELVETICA);
+				}
+			}
+			fontMap.put(this.fontNr, f1);
+			//System.out.println(f1.getFamilyname());
+		}
+		this.setToDefaults();
+	}
+	/**
+	 * Create a font via the <code>FontFactory</code>
+	 * 
+	 * @param fontName The font name to create
+	 * @return The created <code>Font</code> object
+	 * 
+	 * @since 2.0.8
+	 */
+	private Font createfont(String fontName) {
+		Font f1 = null;
+		int pos=-1;
+		do {
+			f1 = FontFactory.getFont(fontName);
+			
+			if(f1.getBaseFont() != null) break;	// found a font, exit the do/while
+			
+			pos = fontName.lastIndexOf(' ');	// find the last space
+			if(pos>0) {
+				fontName = fontName.substring(0, pos );	// truncate it to the last space
+			}
+		} while(pos>0);
+		return f1;
+	}
+	/**
+	 * Get a <code>Font</code> object from the font map object
+	 * 
+	 * @param key The font number to get
+	 * @return The mapped <code>Font</code> object.
+	 * 
+	 * @since 2.0.8
+	 */
+	public Font getFont(String key) {
+		return (Font) fontMap.get(key);
+	}
+	/**
+	 * Load system fonts into the static <code>FontFactory</code> object
+	 * 
+	 * @since 2.0.8
+	 */
+	private void importSystemFonts() {
+		Properties pr = null;
+		try {
+			pr = getEnvironmentVariables();
+		} catch (Throwable e) {
+		}
+		String systemRoot = pr.getProperty("SystemRoot");
+		Runtime runtime = Runtime.getRuntime();
+		String fileSeperator = System.getProperty("file.separator");
+		int r = FontFactory.registerDirectory(systemRoot + fileSeperator + "fonts");
+	}
+	
+	/**
+	 * Utility method to load the environment variables.
+	 * 
+	 * @return Properties object with environment variable information
+	 * @throws Throwable
+	 * 
+	 * @since 2.0.8
+	 */
+	 private Properties getEnvironmentVariables() throws Throwable {
+		Properties environmentVariables = new Properties();
+		String operatingSystem = System.getProperty("os.name").toLowerCase();
+		Runtime runtime = Runtime.getRuntime();
+		Process process = null;
+		if (operatingSystem.indexOf("windows 95") > -1
+				|| operatingSystem.indexOf("windows 98") > -1
+				|| operatingSystem.indexOf("me") > -1) {
+			process = runtime.exec("command.com /c set");
+		} else if ((operatingSystem.indexOf("nt") > -1)
+				|| (operatingSystem.indexOf("windows 2000") > -1)
+				|| (operatingSystem.indexOf("windows xp") > -1)
+				|| (operatingSystem.indexOf("windows 2003") > -1)
+				|| (operatingSystem.indexOf("windows vista") > -1)) {
+			process = runtime.exec("cmd.exe /c set");
+		} else {
+			process = runtime.exec("env");
+		}
+		BufferedReader environmentStream = new BufferedReader(new InputStreamReader(process.getInputStream()));
+		String inputLine = "";
+		int idx = -1;
+		while ((inputLine = environmentStream.readLine()) != null) {
+			idx = inputLine.indexOf('=');
+			environmentVariables.setProperty(inputLine.substring(0, idx),
+					inputLine.substring(idx + 1));
+		}
+		return environmentVariables;
+	}
+
+}
Index: src/core/com/lowagie/text/rtf/document/RtfCodePage.java
===================================================================
--- src/core/com/lowagie/text/rtf/document/RtfCodePage.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/document/RtfCodePage.java	(revision 0)
@@ -0,0 +1,103 @@
+/*
+ * $Id:RtfCodePage.java 3126 2008-02-07 20:30:46Z hallm $
+ *
+ * Copyright 2003, 2004 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.rtf.document;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import com.lowagie.text.DocWriter;
+import com.lowagie.text.rtf.RtfElement;
+import com.lowagie.text.rtf.RtfExtendedElement;
+
+/**
+ * The RtfCodePage class allows different code pages to be used in the rtf document.
+ * Currently always ansi / ansicpg1252
+ *
+ * @version $Id:RtfCodePage.java 3126 2008-02-07 20:30:46Z hallm $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Thomas Bickel (tmb99@inode.at)
+ */
+public class RtfCodePage extends RtfElement implements RtfExtendedElement {
+    /**
+     * Constant for ansi encoded rtf documents
+     */
+    private static final byte[] ANSI = DocWriter.getISOBytes("\\ansi");
+    /**
+     * Constant for the ansi codepage
+     */
+    private static final byte[] ANSI_CODEPAGE = DocWriter.getISOBytes("\\ansicpg");
+
+    /**
+     * Construct an RtfCodePage
+     * 
+     * @param doc The RtfDocument this RtfCodePage belongs to
+     */
+    public RtfCodePage(RtfDocument doc) {
+        super(doc);
+    }
+
+    /**
+     * unused
+     */
+    public void writeContent(final OutputStream out) throws IOException
+    {    	
+    }
+    
+    /**
+     * Writes the selected codepage
+     */
+    public void writeDefinition(final OutputStream result) throws IOException
+    {
+        result.write(ANSI);
+        result.write(ANSI_CODEPAGE);
+        result.write(intToByteArray(1252));
+        this.document.outputDebugLinebreak(result);    	
+    }
+
+}
Index: src/core/com/lowagie/text/rtf/list/RtfListTable.java
===================================================================
--- src/core/com/lowagie/text/rtf/list/RtfListTable.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/list/RtfListTable.java	(revision 0)
@@ -0,0 +1,192 @@
+/*
+ * $Id: RtfListTable.java 3580 2008-08-06 15:52:00Z howard_s $
+ *
+ * Copyright 2008 Howard Shank (hgshank@yahoo.com)
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.rtf.list;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+
+import com.lowagie.text.DocWriter;
+import com.lowagie.text.rtf.RtfElement;
+import com.lowagie.text.rtf.RtfExtendedElement;
+import com.lowagie.text.rtf.document.RtfDocument;
+
+
+/**
+ * The RtfListTable manages all RtfList objects and list override table in one RtfDocument.
+ * 
+ * @version $Id: RtfListTable.java 3580 2008-08-06 15:52:00Z howard_s $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Howard Shank (hgshank@yahoo.com)
+ */
+public class RtfListTable extends RtfElement implements RtfExtendedElement {
+    /**
+     * Constant for the list table
+     */
+    private static final byte[] LIST_TABLE = DocWriter.getISOBytes("\\*\\listtable");
+
+    /**
+     * Constant for the list override table
+     */
+    private static final byte[] LIST_OVERRIDE_TABLE = DocWriter.getISOBytes("\\*\\listoverridetable");
+    /**
+     * Constant for the list override
+     */
+    private static final byte[] LIST_OVERRIDE = DocWriter.getISOBytes("\\listoverride");
+    /**
+     * Constant for the list override count
+     */
+    private static final byte[] LIST_OVERRIDE_COUNT = DocWriter.getISOBytes("\\listoverridecount");
+    
+
+    /**
+     * The RtfList lists managed by this RtfListTable
+     */
+    private ArrayList lists;
+    /**
+     * The RtfPictureList lists managed by this RtfListTable
+     */
+    private ArrayList picturelists;
+    
+    /**
+     * Constructs a RtfListTable for a RtfDocument
+     * 
+     * @param doc The RtfDocument this RtfListTable belongs to
+     */
+    public RtfListTable(RtfDocument doc) {
+        super(doc);
+        
+        this.lists = new ArrayList();
+        this.picturelists = new ArrayList();
+    }
+
+    /**
+     * unused
+     */
+    public void writeContent(final OutputStream out) throws IOException
+    {    	
+    }
+    
+    /**
+     * Writes the list and list override tables.
+     */
+    public void writeDefinition(final OutputStream result) throws IOException
+    {
+        result.write(OPEN_GROUP);
+        result.write(LIST_TABLE);
+        this.document.outputDebugLinebreak(result);
+        
+        for(int i = 0; i < picturelists.size(); i++) {
+        	RtfPictureList l = (RtfPictureList)picturelists.get(i);
+//        	l.setID(document.getRandomInt());
+        	l.writeDefinition(result);
+        	this.document.outputDebugLinebreak(result);
+        }
+
+        for(int i = 0; i < lists.size(); i++) {
+        	RtfList l = (RtfList)lists.get(i);
+        	l.setID(document.getRandomInt());
+        	l.writeDefinition(result);
+        	this.document.outputDebugLinebreak(result);
+        }
+        result.write(CLOSE_GROUP);
+        this.document.outputDebugLinebreak(result);
+        
+        result.write(OPEN_GROUP);
+        result.write(LIST_OVERRIDE_TABLE);
+        this.document.outputDebugLinebreak(result);
+        
+        // list override index values are 1-based, not 0.
+        // valid list override index values \ls are 1 to 2000.
+        // if there are more then 2000 lists, the result is undefined.
+        for(int i = 0; i < lists.size(); i++) {
+            result.write(OPEN_GROUP);
+            result.write(LIST_OVERRIDE);
+            result.write(RtfList.LIST_ID);
+            result.write(intToByteArray( ((RtfList) lists.get(i)).getID() ));
+            result.write(LIST_OVERRIDE_COUNT);
+            result.write(intToByteArray(0));	// is this correct? Spec says valid values are 1 or 9.
+            result.write(RtfList.LIST_NUMBER);
+            result.write(intToByteArray( ((RtfList) lists.get(i)).getListNumber()) );
+            result.write(CLOSE_GROUP);
+            this.document.outputDebugLinebreak(result);
+        }
+        result.write(CLOSE_GROUP);
+        this.document.outputDebugLinebreak(result);
+    }
+
+    /**
+     * Gets the id of the specified RtfList. If the RtfList is not yet in the
+     * list of RtfList, then it is added.
+     * 
+     * @param list The RtfList for which to get the id.
+     * @return The id of the RtfList.
+     */
+    public int getListNumber(RtfList list) {
+        if(lists.contains(list)) {
+            return lists.indexOf(list);
+        } else {
+            lists.add(list);
+            return lists.size();
+        }
+    }
+    
+    /**
+     * Remove a RtfList from the list of RtfList
+     * 
+     * @param list The RtfList to remove.
+     */
+    public void freeListNumber(RtfList list) {
+        int i = lists.indexOf(list);
+        if(i >= 0) {
+            lists.remove(i);
+        }
+    }
+}
Index: src/core/com/lowagie/text/rtf/headerfooter/RtfHeaderFooterGroup.java
===================================================================
--- src/core/com/lowagie/text/rtf/headerfooter/RtfHeaderFooterGroup.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/headerfooter/RtfHeaderFooterGroup.java	(revision 0)
@@ -0,0 +1,430 @@
+/*
+ * $Id: RtfHeaderFooterGroup.java 3373 2008-05-12 16:21:24Z xlv $
+ *
+ * Copyright 2001, 2002, 2003, 2004 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.rtf.headerfooter;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import com.lowagie.text.HeaderFooter;
+import com.lowagie.text.Phrase;
+import com.lowagie.text.rtf.RtfBasicElement;
+import com.lowagie.text.rtf.document.RtfDocument;
+
+
+/**
+ * The RtfHeaderFooterGroup holds 0 - 3 RtfHeaderFooters that create a group
+ * of headers or footers.
+ * 
+ * @version $Id: RtfHeaderFooterGroup.java 3373 2008-05-12 16:21:24Z xlv $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Thomas Bickel (tmb99@inode.at)
+ */
+public class RtfHeaderFooterGroup extends HeaderFooter implements RtfBasicElement {
+    
+    /**
+     * This RtfHeaderFooterGroup contains no RtfHeaderFooter objects
+     */
+    private static final int MODE_NONE = 0;
+    /**
+     * This RtfHeaderFooterGroup contains one RtfHeaderFooter object
+     */
+    private static final int MODE_SINGLE = 1;
+    /**
+     * This RtfHeaderFooterGroup contains two or three RtfHeaderFooter objects
+     */
+    private static final int MODE_MULTIPLE = 2;
+    
+    /**
+     * The current mode of this RtfHeaderFooterGroup. Defaults to MODE_NONE
+     */
+    private int mode = MODE_NONE;
+    /**
+     * The current type of this RtfHeaderFooterGroup. Defaults to RtfHeaderFooter.TYPE_HEADER
+     */
+    private int type = RtfHeaderFooter.TYPE_HEADER;
+    
+    /**
+     * The RtfHeaderFooter for all pages
+     */
+    private RtfHeaderFooter headerAll = null;
+    /**
+     * The RtfHeaderFooter for the first page
+     */
+    private RtfHeaderFooter headerFirst = null;
+    /**
+     * The RtfHeaderFooter for the left hand pages
+     */
+    private RtfHeaderFooter headerLeft = null;
+    /**
+     * The RtfHeaderFooter for the right hand pages
+     */
+    private RtfHeaderFooter headerRight = null;
+    /**
+     * The RtfDocument this RtfHeaderFooterGroup belongs to
+     */
+    private RtfDocument document = null;
+
+    /**
+     * Constructs a RtfHeaderGroup to which you add headers/footers using 
+     * via the setHeaderFooter method.
+     *
+     */
+    public RtfHeaderFooterGroup() {
+        super(new Phrase(""), false);
+        this.mode = MODE_NONE;
+    }
+    
+    /**
+     * Constructs a certain type of RtfHeaderFooterGroup. RtfHeaderFooter.TYPE_HEADER
+     * and RtfHeaderFooter.TYPE_FOOTER are valid values for type.
+     * 
+     * @param doc The RtfDocument this RtfHeaderFooter belongs to
+     * @param type The type of RtfHeaderFooterGroup to create
+     */
+    public RtfHeaderFooterGroup(RtfDocument doc, int type) {
+        super(new Phrase(""), false);
+        this.document = doc;
+        this.type = type;
+    }
+    
+    /**
+     * Constructs a RtfHeaderFooterGroup by copying the content of the original
+     * RtfHeaderFooterGroup
+     * 
+     * @param doc The RtfDocument this RtfHeaderFooter belongs to
+     * @param headerFooter The RtfHeaderFooterGroup to copy
+     * @param type The type of RtfHeaderFooterGroup to create
+     */
+    public RtfHeaderFooterGroup(RtfDocument doc, RtfHeaderFooterGroup headerFooter, int type) {
+        super(new Phrase(""), false);
+        this.document = doc;
+        this.mode = headerFooter.getMode();
+        this.type = type;
+        if(headerFooter.getHeaderAll() != null) {
+            this.headerAll = new RtfHeaderFooter(this.document, headerFooter.getHeaderAll(), RtfHeaderFooter.DISPLAY_ALL_PAGES);
+        }
+        if(headerFooter.getHeaderFirst() != null) {
+            this.headerFirst = new RtfHeaderFooter(this.document, headerFooter.getHeaderFirst(), RtfHeaderFooter.DISPLAY_FIRST_PAGE);
+        }
+        if(headerFooter.getHeaderLeft() != null) {
+            this.headerLeft = new RtfHeaderFooter(this.document, headerFooter.getHeaderLeft(), RtfHeaderFooter.DISPLAY_LEFT_PAGES);
+        }
+        if(headerFooter.getHeaderRight() != null) {
+            this.headerRight = new RtfHeaderFooter(this.document, headerFooter.getHeaderRight(), RtfHeaderFooter.DISPLAY_RIGHT_PAGES);
+        }
+        setType(this.type);
+    }
+    
+    /**
+     * Constructs a RtfHeaderFooterGroup for a certain RtfHeaderFooter.
+     * 
+     * @param doc The RtfDocument this RtfHeaderFooter belongs to
+     * @param headerFooter The RtfHeaderFooter to display
+     * @param type The type of RtfHeaderFooterGroup to create
+     */
+    public RtfHeaderFooterGroup(RtfDocument doc, RtfHeaderFooter headerFooter, int type) {
+        super(new Phrase(""), false);
+        this.document = doc;
+        this.type = type;
+        this.mode = MODE_SINGLE;
+        headerAll = new RtfHeaderFooter(doc, headerFooter, RtfHeaderFooter.DISPLAY_ALL_PAGES);
+        headerAll.setType(this.type);
+    }
+    
+    /**
+     * Constructs a RtfHeaderGroup for a certain HeaderFooter
+     * 
+     * @param doc The RtfDocument this RtfHeaderFooter belongs to
+     * @param headerFooter The HeaderFooter to display
+     * @param type The type of RtfHeaderFooterGroup to create
+     */
+    public RtfHeaderFooterGroup(RtfDocument doc, HeaderFooter headerFooter, int type) {
+        super(new Phrase(""), false);
+        this.document = doc;
+        this.type = type;
+        this.mode = MODE_SINGLE;
+        headerAll = new RtfHeaderFooter(doc, headerFooter, type, RtfHeaderFooter.DISPLAY_ALL_PAGES);
+        headerAll.setType(this.type);
+    }
+    
+    /**
+     * Sets the RtfDocument this RtfElement belongs to
+     * 
+     * @param doc The RtfDocument to use
+     */
+    public void setRtfDocument(RtfDocument doc) {
+        this.document = doc;
+        if(headerAll != null) {
+            headerAll.setRtfDocument(this.document);
+        }
+        if(headerFirst != null) {
+            headerFirst.setRtfDocument(this.document);
+        }
+        if(headerLeft != null) {
+            headerLeft.setRtfDocument(this.document);
+        }
+        if(headerRight != null) {
+            headerRight.setRtfDocument(this.document);
+        }
+    }
+    
+    /**
+     * Write the content of this RtfHeaderFooterGroup.
+     */    
+    public void writeContent(final OutputStream result) throws IOException
+    {
+        if(this.mode == MODE_SINGLE) {
+        	headerAll.writeContent(result);
+        } else if(this.mode == MODE_MULTIPLE) {
+            if(headerFirst != null) {
+            	headerFirst.writeContent(result);
+            }
+            if(headerLeft != null) {
+                headerLeft.writeContent(result);
+            }
+            if(headerRight != null) {
+                headerRight.writeContent(result);
+            }
+            if(headerAll != null) {
+                headerAll.writeContent(result);
+            }
+        }
+    }        
+    
+    /**
+     * Set a RtfHeaderFooter to be displayed at a certain position
+     * 
+     * @param headerFooter The RtfHeaderFooter to display
+     * @param displayAt The display location to use
+     */
+    public void setHeaderFooter(RtfHeaderFooter headerFooter, int displayAt) {
+        this.mode = MODE_MULTIPLE;
+        headerFooter.setRtfDocument(this.document);
+        headerFooter.setType(this.type);
+        headerFooter.setDisplayAt(displayAt);
+        switch(displayAt) {
+            case RtfHeaderFooter.DISPLAY_ALL_PAGES:
+                headerAll = headerFooter;
+            	break;
+            case RtfHeaderFooter.DISPLAY_FIRST_PAGE:
+                headerFirst = headerFooter;
+                break;
+            case RtfHeaderFooter.DISPLAY_LEFT_PAGES:
+                headerLeft = headerFooter;
+                break;
+            case RtfHeaderFooter.DISPLAY_RIGHT_PAGES:
+                headerRight = headerFooter;
+                break;
+        }
+    }
+    
+    /**
+     * Set a HeaderFooter to be displayed at a certain position
+     * 
+     * @param headerFooter The HeaderFooter to set
+     * @param displayAt The display location to use
+     */
+    public void setHeaderFooter(HeaderFooter headerFooter, int displayAt) {
+        this.mode = MODE_MULTIPLE;
+        switch(displayAt) {
+            case RtfHeaderFooter.DISPLAY_ALL_PAGES:
+                headerAll = new RtfHeaderFooter(this.document, headerFooter, this.type, displayAt);
+            	break;
+            case RtfHeaderFooter.DISPLAY_FIRST_PAGE:
+                headerFirst = new RtfHeaderFooter(this.document, headerFooter, this.type, displayAt);
+                break;
+            case RtfHeaderFooter.DISPLAY_LEFT_PAGES:
+                headerLeft = new RtfHeaderFooter(this.document, headerFooter, this.type, displayAt);
+                break;
+            case RtfHeaderFooter.DISPLAY_RIGHT_PAGES:
+                headerRight = new RtfHeaderFooter(this.document, headerFooter, this.type, displayAt);
+                break;
+        }
+    }
+    
+    /**
+     * Set that this RtfHeaderFooterGroup should have a title page. If only
+     * a header / footer for all pages exists, then it will be copied to the
+     * first page as well.
+     */
+    public void setHasTitlePage() {
+        if(this.mode == MODE_SINGLE) {
+            this.mode = MODE_MULTIPLE;
+            headerFirst = new RtfHeaderFooter(this.document, headerAll, RtfHeaderFooter.DISPLAY_FIRST_PAGE);
+            headerFirst.setType(this.type);
+        }
+    }
+    
+    /**
+     * Set that this RtfHeaderFooterGroup should have facing pages. If only
+     * a header / footer for all pages exists, then it will be copied to the left
+     * and right pages as well.
+     */
+    public void setHasFacingPages() {
+        if(this.mode == MODE_SINGLE) {
+            this.mode = MODE_MULTIPLE;
+            this.headerLeft = new RtfHeaderFooter(this.document, this.headerAll, RtfHeaderFooter.DISPLAY_LEFT_PAGES);
+            this.headerLeft.setType(this.type);
+            this.headerRight = new RtfHeaderFooter(this.document, this.headerAll, RtfHeaderFooter.DISPLAY_RIGHT_PAGES);
+            this.headerRight.setType(this.type);
+            this.headerAll = null;
+        } else if(this.mode == MODE_MULTIPLE) {
+            if(this.headerLeft == null && this.headerAll != null) {
+                this.headerLeft = new RtfHeaderFooter(this.document, this.headerAll, RtfHeaderFooter.DISPLAY_LEFT_PAGES);
+                this.headerLeft.setType(this.type);
+            }
+            if(this.headerRight == null && this.headerAll != null) {
+                this.headerRight = new RtfHeaderFooter(this.document, this.headerAll, RtfHeaderFooter.DISPLAY_RIGHT_PAGES);
+                this.headerRight.setType(this.type);
+            }
+            this.headerAll = null;
+        }
+    }
+    
+    /**
+     * Get whether this RtfHeaderFooterGroup has a titlepage
+     * 
+     * @return Whether this RtfHeaderFooterGroup has a titlepage
+     */
+    public boolean hasTitlePage() {
+        return (headerFirst != null);
+    }
+    
+    /**
+     * Get whether this RtfHeaderFooterGroup has facing pages
+     * 
+     * @return Whether this RtfHeaderFooterGroup has facing pages
+     */
+    public boolean hasFacingPages() {
+        return (headerLeft != null || headerRight != null);
+    }
+
+    /**
+     * Unused
+     * @param inTable
+     */
+    public void setInTable(boolean inTable) {
+    }
+    
+    /**
+     * Unused
+     * @param inHeader
+     */
+    public void setInHeader(boolean inHeader) {
+    }
+    
+    /**
+     * Set the type of this RtfHeaderFooterGroup. RtfHeaderFooter.TYPE_HEADER
+     * or RtfHeaderFooter.TYPE_FOOTER. Also sets the type for all RtfHeaderFooters
+     * of this RtfHeaderFooterGroup.
+     * 
+     * @param type The type to use
+     */
+    public void setType(int type) {
+        this.type = type;
+        if(headerAll != null) {
+            headerAll.setType(this.type);
+        }
+        if(headerFirst != null) {
+            headerFirst.setType(this.type);
+        }
+        if(headerLeft != null) {
+            headerLeft.setType(this.type);
+        }
+        if(headerRight != null) {
+            headerRight.setType(this.type);
+        }
+    }
+    
+    /**
+     * Gets the mode of this RtfHeaderFooterGroup
+     * 
+     * @return The mode of this RtfHeaderFooterGroup
+     */
+    protected int getMode() {
+        return this.mode;
+    }
+    
+    /**
+     * Gets the RtfHeaderFooter for all pages
+     * 
+     * @return The RtfHeaderFooter for all pages 
+     */
+    protected RtfHeaderFooter getHeaderAll() {
+        return headerAll;
+    }
+
+    /**
+     * Gets the RtfHeaderFooter for the title page
+     * 
+     * @return The RtfHeaderFooter for the title page 
+     */
+    protected RtfHeaderFooter getHeaderFirst() {
+        return headerFirst;
+    }
+
+    /**
+     * Gets the RtfHeaderFooter for all left hand pages
+     * 
+     * @return The RtfHeaderFooter for all left hand pages 
+     */
+    protected RtfHeaderFooter getHeaderLeft() {
+        return headerLeft;
+    }
+
+    /**
+     * Gets the RtfHeaderFooter for all right hand pages
+     * 
+     * @return The RtfHeaderFooter for all right hand pages 
+     */
+    protected RtfHeaderFooter getHeaderRight() {
+        return headerRight;
+    }
+}
Index: src/core/com/lowagie/text/rtf/parser/ctrlwords/RtfCtrlWordMap.java
===================================================================
--- src/core/com/lowagie/text/rtf/parser/ctrlwords/RtfCtrlWordMap.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/parser/ctrlwords/RtfCtrlWordMap.java	(revision 0)
@@ -0,0 +1,1915 @@
+/*
+ * $Id: RtfCtrlWordMap.java 3580 2008-08-06 15:52:00Z howard_s $
+ *
+ * Copyright 2007 by Howard Shank
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+package com.lowagie.text.rtf.parser.ctrlwords;
+
+import java.util.HashMap;
+
+import com.lowagie.text.rtf.parser.RtfParser;
+import com.lowagie.text.rtf.parser.properties.RtfProperty;
+
+/**
+ * <code>RtfCtrlWords</code> handles the creation of the control word wiring.
+ * It is a class containing the hash map of the control words (key)
+ * and their associated class (value).
+ *
+ * @author Howard Shank (hgshank@yahoo.com)
+ * @since 2.0.8
+ */
+final class RtfCtrlWordMap {
+
+    // 1810 control words in Spec v1.9. might be a few more for other apps that implement
+    // additional control words such as exchange, outlook, etc.
+    // 1810/.9(loadfactor) = 2011.111111...
+    // set approximate initial size to initial count / load factor.
+    // HashMap default size is 16. Load Factor .75
+    /**
+     * Control Word HashMap mapping object.
+     */
+    private HashMap ctrlWords = new HashMap(2012, .9f);
+
+    /**
+     * Get the HashMap object containing the control words.
+     * Initializes the instance if this is the first instantiation
+     * of RtfCtrlWords class.
+     * @since 2.0.8
+     */
+    public RtfCtrlWordHandler getCtrlWordHandler(String ctrlWord) {
+    	try {
+        	RtfCtrlWordHandler handler = null;
+        	if(ctrlWord == "cf") {
+        	 handler = null;
+        	}
+        	if(ctrlWords.containsKey(ctrlWord)) {
+        		// add 1 to known control words
+        		return (RtfCtrlWordHandler)ctrlWords.get(ctrlWord);
+        	} else {
+        		// add 1 to unknown control words
+        		return (RtfCtrlWordHandler)ctrlWords.get("unknown");
+        	}
+		} catch (SecurityException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (IllegalArgumentException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		return null;
+    }
+    
+    /**
+     * Constructor
+     * @param rtfParser The parser object.
+     * @since 2.0.8
+     */
+    public RtfCtrlWordMap(RtfParser rtfParser) {
+/* 
+ * Parameters:
+ * RtfParser rtfParser
+ * String ctrlWord
+ * int defaultParameterValue
+ * boolean passDefaultParameterValue 
+ * RtfCtrlWordType ctrlWordType
+ * String prefix
+ * String suffix
+ * String specialHandler =
+ * 	If TOGGLE then the property name as String
+ * 	If FLAG then the property name as String
+ * 	If VALUE then the property name as String
+ * 	If SYMBOL then the character to use for substitution as String
+ * 	If DESTINATION|DESTINATION_EX then the RtfDestination class name as String 
+  */
+		//starwriter
+    	ctrlWords.put("aftnnrlc", new RtfCtrlWordHandler(rtfParser, "aftnnrlc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+    	ctrlWords.put("pgdsctbl", new RtfCtrlWordHandler(rtfParser, "pgdsctbl", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument"));
+    	ctrlWords.put("pgdsc", new RtfCtrlWordHandler(rtfParser, "pgdsc", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null));
+    	ctrlWords.put("pgdscuse", new RtfCtrlWordHandler(rtfParser, "pgdscuse", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null));
+    	ctrlWords.put("pgdscnxt", new RtfCtrlWordHandler(rtfParser, "pgdscnxt", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null));
+    	ctrlWords.put("pgdscno", new RtfCtrlWordHandler(rtfParser, "pgdsctbl", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument"));
+
+    	//office
+		ctrlWords.put("'", new RtfCtrlWordHandler(rtfParser, "'", 0, false, RtfCtrlWordType.SYMBOL, "\\", "", "'"));
+		ctrlWords.put("*", new RtfCtrlWordHandler(rtfParser, "*", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", "*"));
+		ctrlWords.put("-", new RtfCtrlWordHandler(rtfParser, "-", 0, false, RtfCtrlWordType.SYMBOL, "\\", "", "-"));
+		ctrlWords.put(":", new RtfCtrlWordHandler(rtfParser, ":", 0, false, RtfCtrlWordType.SYMBOL, "\\", "", ":"));
+		ctrlWords.put("ApplyBrkRules", new RtfCtrlWordHandler(rtfParser, "ApplyBrkRules", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));// "ApplyBrkRules",
+		ctrlWords.put("\\", new RtfCtrlWordHandler(rtfParser, "\\", 0, false, RtfCtrlWordType.SYMBOL, "\\", "", "\\"));
+		ctrlWords.put("_", new RtfCtrlWordHandler(rtfParser, "_", 0, false, RtfCtrlWordType.SYMBOL, "\\", "", "_"));
+		ctrlWords.put("ab", new RtfCtrlWordHandler(rtfParser, "ab", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));//"ab",
+		ctrlWords.put("absh", new RtfCtrlWordHandler(rtfParser, "absh", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));//"absh",
+		ctrlWords.put("abslock", new RtfCtrlWordHandler(rtfParser, "abslock", 0, false, RtfCtrlWordType.FLAG, "", " ", null));//"abslock",
+		ctrlWords.put("absnoovrlp", new RtfCtrlWordHandler(rtfParser, "absnoovrlp", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));//"absnoovrlp",
+		ctrlWords.put("absw", new RtfCtrlWordHandler(rtfParser, "absw", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));//"absw",
+		ctrlWords.put("acaps", new RtfCtrlWordHandler(rtfParser, "acaps", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));//"acaps",
+		ctrlWords.put("acccircle", new RtfCtrlWordHandler(rtfParser, "acccircle", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));//"acccircle",
+		ctrlWords.put("acccomma", new RtfCtrlWordHandler(rtfParser, "acccomma", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("accdot", new RtfCtrlWordHandler(rtfParser, "accdot", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("accnone", new RtfCtrlWordHandler(rtfParser, "accnone", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("accunderdot", new RtfCtrlWordHandler(rtfParser, "accunderdot", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("acf", new RtfCtrlWordHandler(rtfParser, "acf", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("additive", new RtfCtrlWordHandler(rtfParser, "additive", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("adeflang", new RtfCtrlWordHandler(rtfParser, "adeflang", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("adjustright", new RtfCtrlWordHandler(rtfParser, "adjustright", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("adn", new RtfCtrlWordHandler(rtfParser, "adn", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("aenddoc", new RtfCtrlWordHandler(rtfParser, "aenddoc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("aendnotes", new RtfCtrlWordHandler(rtfParser, "aendnotes", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("aexpnd", new RtfCtrlWordHandler(rtfParser, "aexpnd", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("af", new RtfCtrlWordHandler(rtfParser, "af", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("afelev", new RtfCtrlWordHandler(rtfParser, "afelev", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("affixed", new RtfCtrlWordHandler(rtfParser, "affixed", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("afs", new RtfCtrlWordHandler(rtfParser, "afs", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("aftnbj", new RtfCtrlWordHandler(rtfParser, "aftnbj", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("aftncn", new RtfCtrlWordHandler(rtfParser, "aftncn", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("aftnnalc", new RtfCtrlWordHandler(rtfParser, "aftnnalc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("aftnnar", new RtfCtrlWordHandler(rtfParser, "aftnnar", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("aftnnauc", new RtfCtrlWordHandler(rtfParser, "aftnnauc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("aftnnchi", new RtfCtrlWordHandler(rtfParser, "aftnnchi", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("aftnnchosung", new RtfCtrlWordHandler(rtfParser, "aftnnchosung", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("aftnncnum", new RtfCtrlWordHandler(rtfParser, "aftnncnum", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("aftnndbar", new RtfCtrlWordHandler(rtfParser, "aftnndbar", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("aftnndbnum", new RtfCtrlWordHandler(rtfParser, "aftnndbnum", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("aftnndbnumd", new RtfCtrlWordHandler(rtfParser, "aftnndbnumd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("aftnndbnumk", new RtfCtrlWordHandler(rtfParser, "aftnndbnumk", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("aftnndbnumt", new RtfCtrlWordHandler(rtfParser, "aftnndbnumt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("aftnnganada", new RtfCtrlWordHandler(rtfParser, "aftnnganada", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("aftnngbnum", new RtfCtrlWordHandler(rtfParser, "aftnngbnum", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("aftnngbnumd", new RtfCtrlWordHandler(rtfParser, "aftnngbnumd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("aftnngbnumk", new RtfCtrlWordHandler(rtfParser, "aftnngbnumk", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("aftnngbnuml", new RtfCtrlWordHandler(rtfParser, "aftnngbnuml", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("aftnnrlc", new RtfCtrlWordHandler(rtfParser, "aftnnrlc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("aftnnruc", new RtfCtrlWordHandler(rtfParser, "aftnnruc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("aftnnzodiac", new RtfCtrlWordHandler(rtfParser, "aftnnzodiac", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("aftnnzodiacd", new RtfCtrlWordHandler(rtfParser, "aftnnzodiacd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("aftnnzodiacl", new RtfCtrlWordHandler(rtfParser, "aftnnzodiacl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("aftnrestart", new RtfCtrlWordHandler(rtfParser, "aftnrestart", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("aftnrstcont", new RtfCtrlWordHandler(rtfParser, "aftnrstcont", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("aftnsep", new RtfCtrlWordHandler(rtfParser, "aftnsep", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("aftnsepc", new RtfCtrlWordHandler(rtfParser, "aftnsepc", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("aftnstart", new RtfCtrlWordHandler(rtfParser, "aftnstart", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("aftntj", new RtfCtrlWordHandler(rtfParser, "aftntj", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("ai", new RtfCtrlWordHandler(rtfParser, "ai", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("alang", new RtfCtrlWordHandler(rtfParser, "alang", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("allowfieldendsel", new RtfCtrlWordHandler(rtfParser, "allowfieldendsel", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("allprot", new RtfCtrlWordHandler(rtfParser, "allprot", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("alntblind", new RtfCtrlWordHandler(rtfParser, "alntblind", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("alt", new RtfCtrlWordHandler(rtfParser, "alt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("animtext", new RtfCtrlWordHandler(rtfParser, "animtext", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("annotation", new RtfCtrlWordHandler(rtfParser, "annotation", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("annotprot", new RtfCtrlWordHandler(rtfParser, "annotprot", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("ansi", new RtfCtrlWordHandler(rtfParser, "ansi", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("ansicpg", new RtfCtrlWordHandler(rtfParser, "ansicpg", 1252, false, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("aoutl", new RtfCtrlWordHandler(rtfParser, "aoutl", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("ascaps", new RtfCtrlWordHandler(rtfParser, "ascaps", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("ashad", new RtfCtrlWordHandler(rtfParser, "ashad", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("asianbrkrule", new RtfCtrlWordHandler(rtfParser, "asianbrkrule", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("aspalpha", new RtfCtrlWordHandler(rtfParser, "aspalpha", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("aspnum", new RtfCtrlWordHandler(rtfParser, "aspnum", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("astrike", new RtfCtrlWordHandler(rtfParser, "astrike", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("atnauthor", new RtfCtrlWordHandler(rtfParser, "atnauthor", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("atndate", new RtfCtrlWordHandler(rtfParser, "atndate", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("atnicn", new RtfCtrlWordHandler(rtfParser, "atnicn", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("atnid", new RtfCtrlWordHandler(rtfParser, "atnid", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("atnparent", new RtfCtrlWordHandler(rtfParser, "atnparent", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("atnref", new RtfCtrlWordHandler(rtfParser, "atnref", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("atntime", new RtfCtrlWordHandler(rtfParser, "atntime", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("atrfend", new RtfCtrlWordHandler(rtfParser, "atrfend", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("atrfstart", new RtfCtrlWordHandler(rtfParser, "atrfstart", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("aul", new RtfCtrlWordHandler(rtfParser, "aul", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("auld", new RtfCtrlWordHandler(rtfParser, "auld", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("auldb", new RtfCtrlWordHandler(rtfParser, "auldb", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("aulnone", new RtfCtrlWordHandler(rtfParser, "aulnone", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("aulw", new RtfCtrlWordHandler(rtfParser, "aulw", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("aup", new RtfCtrlWordHandler(rtfParser, "aup", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("author", new RtfCtrlWordHandler(rtfParser, "author", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationInfo"));
+		ctrlWords.put("autofmtoverride", new RtfCtrlWordHandler(rtfParser, "autofmtoverride", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("b", new RtfCtrlWordHandler(rtfParser, "b", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", RtfProperty.CHARACTER_BOLD));
+		ctrlWords.put("background", new RtfCtrlWordHandler(rtfParser, "background", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("bdbfhdr", new RtfCtrlWordHandler(rtfParser, "bdbfhdr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("bdrrlswsix", new RtfCtrlWordHandler(rtfParser, "bdrrlswsix", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("bgbdiag", new RtfCtrlWordHandler(rtfParser, "bgbdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("bgcross", new RtfCtrlWordHandler(rtfParser, "bgcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("bgdcross", new RtfCtrlWordHandler(rtfParser, "bgdcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("bgdkbdiag", new RtfCtrlWordHandler(rtfParser, "bgdkbdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("bgdkcross", new RtfCtrlWordHandler(rtfParser, "bgdkcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("bgdkdcross", new RtfCtrlWordHandler(rtfParser, "bgdkdcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("bgdkfdiag", new RtfCtrlWordHandler(rtfParser, "bgdkfdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("bgdkhoriz", new RtfCtrlWordHandler(rtfParser, "bgdkhoriz", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("bgdkvert", new RtfCtrlWordHandler(rtfParser, "bgdkvert", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("bgfdiag", new RtfCtrlWordHandler(rtfParser, "bgfdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("bghoriz", new RtfCtrlWordHandler(rtfParser, "bghoriz", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("bgvert", new RtfCtrlWordHandler(rtfParser, "bgvert", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("bin", new RtfCtrlWordHandler(rtfParser, "bin", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("binfsxn", new RtfCtrlWordHandler(rtfParser, "binfsxn", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("binsxn", new RtfCtrlWordHandler(rtfParser, "binsxn", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("bkmkcolf", new RtfCtrlWordHandler(rtfParser, "bkmkcolf", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("bkmkcoll", new RtfCtrlWordHandler(rtfParser, "bkmkcoll", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("bkmkend", new RtfCtrlWordHandler(rtfParser, "bkmkend", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("bkmkpub", new RtfCtrlWordHandler(rtfParser, "bkmkpub", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("bkmkstart", new RtfCtrlWordHandler(rtfParser, "bkmkstart", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("bliptag", new RtfCtrlWordHandler(rtfParser, "bliptag", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("blipuid", new RtfCtrlWordHandler(rtfParser, "blipuid", 0, false, RtfCtrlWordType.VALUE, "\\*\\", " ", "RtfDestinationShppict" ));//"RtfDestinationBlipuid"));
+		ctrlWords.put("blipupi", new RtfCtrlWordHandler(rtfParser, "blipupi", 0, true, RtfCtrlWordType.VALUE, "\\", " ", "RtfDestinationShppict"));
+		ctrlWords.put("blue", new RtfCtrlWordHandler(rtfParser, "blue", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("bookfold", new RtfCtrlWordHandler(rtfParser, "bookfold", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("bookfoldrev", new RtfCtrlWordHandler(rtfParser, "bookfoldrev", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("bookfoldsheets", new RtfCtrlWordHandler(rtfParser, "bookfoldsheets", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("box", new RtfCtrlWordHandler(rtfParser, "box", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("brdrart", new RtfCtrlWordHandler(rtfParser, "brdrart", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("brdrb", new RtfCtrlWordHandler(rtfParser, "brdrb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("brdrbar", new RtfCtrlWordHandler(rtfParser, "brdrbar", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("brdrbtw", new RtfCtrlWordHandler(rtfParser, "brdrbtw", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("brdrcf", new RtfCtrlWordHandler(rtfParser, "brdrcf", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("brdrdash", new RtfCtrlWordHandler(rtfParser, "brdrdash", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("brdrdashd", new RtfCtrlWordHandler(rtfParser, "brdrdashd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("brdrdashdd", new RtfCtrlWordHandler(rtfParser, "brdrdashdd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("brdrdashdotstr", new RtfCtrlWordHandler(rtfParser, "brdrdashdotstr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("brdrdashsm", new RtfCtrlWordHandler(rtfParser, "brdrdashsm", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("brdrdb", new RtfCtrlWordHandler(rtfParser, "brdrdb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("brdrdot", new RtfCtrlWordHandler(rtfParser, "brdrdot", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("brdremboss", new RtfCtrlWordHandler(rtfParser, "brdremboss", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("brdrengrave", new RtfCtrlWordHandler(rtfParser, "brdrengrave", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("brdrframe", new RtfCtrlWordHandler(rtfParser, "brdrframe", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("brdrhair", new RtfCtrlWordHandler(rtfParser, "brdrhair", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("brdrinset", new RtfCtrlWordHandler(rtfParser, "brdrinset", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("brdrl", new RtfCtrlWordHandler(rtfParser, "brdrl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("brdrnil", new RtfCtrlWordHandler(rtfParser, "brdrnil", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("brdrnone", new RtfCtrlWordHandler(rtfParser, "brdrnone", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("brdroutset", new RtfCtrlWordHandler(rtfParser, "brdroutset", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("brdrr", new RtfCtrlWordHandler(rtfParser, "brdrr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("brdrs", new RtfCtrlWordHandler(rtfParser, "brdrs", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("brdrsh", new RtfCtrlWordHandler(rtfParser, "brdrsh", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("brdrt", new RtfCtrlWordHandler(rtfParser, "brdrt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("brdrtbl", new RtfCtrlWordHandler(rtfParser, "brdrtbl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("brdrth", new RtfCtrlWordHandler(rtfParser, "brdrth", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("brdrthtnlg", new RtfCtrlWordHandler(rtfParser, "brdrthtnlg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("brdrthtnmg", new RtfCtrlWordHandler(rtfParser, "brdrthtnmg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("brdrthtnsg", new RtfCtrlWordHandler(rtfParser, "brdrthtnsg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("brdrtnthlg", new RtfCtrlWordHandler(rtfParser, "brdrtnthlg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("brdrtnthmg", new RtfCtrlWordHandler(rtfParser, "brdrtnthmg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("brdrtnthsg", new RtfCtrlWordHandler(rtfParser, "brdrtnthsg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("brdrtnthtnlg", new RtfCtrlWordHandler(rtfParser, "brdrtnthtnlg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("brdrtnthtnmg", new RtfCtrlWordHandler(rtfParser, "brdrtnthtnmg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("brdrtnthtnsg", new RtfCtrlWordHandler(rtfParser, "brdrtnthtnsg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("brdrtriple", new RtfCtrlWordHandler(rtfParser, "brdrtriple", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("brdrw", new RtfCtrlWordHandler(rtfParser, "brdrw", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("brdrwavy", new RtfCtrlWordHandler(rtfParser, "brdrwavy", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("brdrwavydb", new RtfCtrlWordHandler(rtfParser, "brdrwavydb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("brkfrm", new RtfCtrlWordHandler(rtfParser, "brkfrm", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("brsp", new RtfCtrlWordHandler(rtfParser, "brsp", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("bullet", new RtfCtrlWordHandler(rtfParser, "bullet", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", "\0x149"));
+		ctrlWords.put("buptim", new RtfCtrlWordHandler(rtfParser, "buptim", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("bxe", new RtfCtrlWordHandler(rtfParser, "bxe", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("caccentfive", new RtfCtrlWordHandler(rtfParser, "caccentfive", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("caccentfour", new RtfCtrlWordHandler(rtfParser, "caccentfour", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("caccentone", new RtfCtrlWordHandler(rtfParser, "caccentone", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("caccentsix", new RtfCtrlWordHandler(rtfParser, "caccentsix", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("caccentthree", new RtfCtrlWordHandler(rtfParser, "caccentthree", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("caccenttwo", new RtfCtrlWordHandler(rtfParser, "caccenttwo", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("cachedcolbal", new RtfCtrlWordHandler(rtfParser, "cachedcolbal", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("caps", new RtfCtrlWordHandler(rtfParser, "caps", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("category", new RtfCtrlWordHandler(rtfParser, "category", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("cb", new RtfCtrlWordHandler(rtfParser, "cb", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("cbackgroundone", new RtfCtrlWordHandler(rtfParser, "cbackgroundone", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("cbackgroundtwo", new RtfCtrlWordHandler(rtfParser, "cbackgroundtwo", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("cbpat", new RtfCtrlWordHandler(rtfParser, "cbpat", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("cchs", new RtfCtrlWordHandler(rtfParser, "cchs", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("cell", new RtfCtrlWordHandler(rtfParser, "cell", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null));
+		ctrlWords.put("cellx", new RtfCtrlWordHandler(rtfParser, "cellx", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("cf", new RtfCtrlWordHandler(rtfParser, "cf", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("cfollowedhyperlink", new RtfCtrlWordHandler(rtfParser, "cfollowedhyperlink", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("cfpat", new RtfCtrlWordHandler(rtfParser, "cfpat", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("cgrid", new RtfCtrlWordHandler(rtfParser, "cgrid", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("charrsid", new RtfCtrlWordHandler(rtfParser, "charrsid", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("charscalex", new RtfCtrlWordHandler(rtfParser, "charscalex", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("chatn", new RtfCtrlWordHandler(rtfParser, "chatn", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null));
+		ctrlWords.put("chbgbdiag", new RtfCtrlWordHandler(rtfParser, "chbgbdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("chbgcross", new RtfCtrlWordHandler(rtfParser, "chbgcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("chbgdcross", new RtfCtrlWordHandler(rtfParser, "chbgdcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("chbgdkbdiag", new RtfCtrlWordHandler(rtfParser, "chbgdkbdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("chbgdkcross", new RtfCtrlWordHandler(rtfParser, "chbgdkcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("chbgdkdcross", new RtfCtrlWordHandler(rtfParser, "chbgdkdcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("chbgdkfdiag", new RtfCtrlWordHandler(rtfParser, "chbgdkfdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("chbgdkhoriz", new RtfCtrlWordHandler(rtfParser, "chbgdkhoriz", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("chbgdkvert", new RtfCtrlWordHandler(rtfParser, "chbgdkvert", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("chbgfdiag", new RtfCtrlWordHandler(rtfParser, "chbgfdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("chbghoriz", new RtfCtrlWordHandler(rtfParser, "chbghoriz", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("chbgvert", new RtfCtrlWordHandler(rtfParser, "chbgvert", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("chbrdr", new RtfCtrlWordHandler(rtfParser, "chbrdr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("chcbpat", new RtfCtrlWordHandler(rtfParser, "chcbpat", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("chcfpat", new RtfCtrlWordHandler(rtfParser, "chcfpat", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("chdate", new RtfCtrlWordHandler(rtfParser, "chdate", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null));
+		ctrlWords.put("chdpa", new RtfCtrlWordHandler(rtfParser, "chdpa", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null));
+		ctrlWords.put("chdpl", new RtfCtrlWordHandler(rtfParser, "chdpl", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null));
+		ctrlWords.put("chftn", new RtfCtrlWordHandler(rtfParser, "chftn", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null));
+		ctrlWords.put("chftnsep", new RtfCtrlWordHandler(rtfParser, "chftnsep", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null));
+		ctrlWords.put("chftnsepc", new RtfCtrlWordHandler(rtfParser, "chftnsepc", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null));
+		ctrlWords.put("chpgn", new RtfCtrlWordHandler(rtfParser, "chpgn", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null));
+		ctrlWords.put("chshdng", new RtfCtrlWordHandler(rtfParser, "chshdng", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("chtime", new RtfCtrlWordHandler(rtfParser, "chtime", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null));
+		ctrlWords.put("chyperlink", new RtfCtrlWordHandler(rtfParser, "chyperlink", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("clFitText", new RtfCtrlWordHandler(rtfParser, "clFitText", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("clNoWrap", new RtfCtrlWordHandler(rtfParser, "clNoWrap", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("clbgbdiag", new RtfCtrlWordHandler(rtfParser, "clbgbdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("clbgcross", new RtfCtrlWordHandler(rtfParser, "clbgcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("clbgdcross", new RtfCtrlWordHandler(rtfParser, "clbgdcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("clbgdkbdiag", new RtfCtrlWordHandler(rtfParser, "clbgdkbdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("clbgdkcross", new RtfCtrlWordHandler(rtfParser, "clbgdkcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("clbgdkdcross", new RtfCtrlWordHandler(rtfParser, "clbgdkdcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("clbgdkfdiag", new RtfCtrlWordHandler(rtfParser, "clbgdkfdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("clbgdkhor", new RtfCtrlWordHandler(rtfParser, "clbgdkhor", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("clbgdkvert", new RtfCtrlWordHandler(rtfParser, "clbgdkvert", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("clbgfdiag", new RtfCtrlWordHandler(rtfParser, "clbgfdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("clbghoriz", new RtfCtrlWordHandler(rtfParser, "clbghoriz", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("clbgvert", new RtfCtrlWordHandler(rtfParser, "clbgvert", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("clbrdrb", new RtfCtrlWordHandler(rtfParser, "clbrdrb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("clbrdrl", new RtfCtrlWordHandler(rtfParser, "clbrdrl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("clbrdrr", new RtfCtrlWordHandler(rtfParser, "clbrdrr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("clbrdrt", new RtfCtrlWordHandler(rtfParser, "clbrdrt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("clcbpat", new RtfCtrlWordHandler(rtfParser, "clcbpat", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("clcbpatraw", new RtfCtrlWordHandler(rtfParser, "clcbpatraw", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("clcfpat", new RtfCtrlWordHandler(rtfParser, "clcfpat", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("clcfpatraw", new RtfCtrlWordHandler(rtfParser, "clcfpatraw", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("cldel", new RtfCtrlWordHandler(rtfParser, "cldel", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("cldelauth", new RtfCtrlWordHandler(rtfParser, "cldelauth", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("cldeldttm", new RtfCtrlWordHandler(rtfParser, "cldeldttm", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("cldgll", new RtfCtrlWordHandler(rtfParser, "cldgll", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("cldglu", new RtfCtrlWordHandler(rtfParser, "cldglu", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("clftsWidth", new RtfCtrlWordHandler(rtfParser, "clftsWidth", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("clhidemark", new RtfCtrlWordHandler(rtfParser, "clhidemark", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("clins", new RtfCtrlWordHandler(rtfParser, "clins", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("clinsauth", new RtfCtrlWordHandler(rtfParser, "clinsauth", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("clinsdttm", new RtfCtrlWordHandler(rtfParser, "clinsdttm", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("clmgf", new RtfCtrlWordHandler(rtfParser, "clmgf", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("clmrg", new RtfCtrlWordHandler(rtfParser, "clmrg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("clmrgd", new RtfCtrlWordHandler(rtfParser, "clmrgd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("clmrgdauth", new RtfCtrlWordHandler(rtfParser, "clmrgdauth", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("clmrgddttm", new RtfCtrlWordHandler(rtfParser, "clmrgddttm", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("clmrgdr", new RtfCtrlWordHandler(rtfParser, "clmrgdr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("clpadb", new RtfCtrlWordHandler(rtfParser, "clpadb", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("clpadfb", new RtfCtrlWordHandler(rtfParser, "clpadfb", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("clpadfl", new RtfCtrlWordHandler(rtfParser, "clpadfl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("clpadfr", new RtfCtrlWordHandler(rtfParser, "clpadfr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("clpadft", new RtfCtrlWordHandler(rtfParser, "clpadft", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("clpadl", new RtfCtrlWordHandler(rtfParser, "clpadl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("clpadr", new RtfCtrlWordHandler(rtfParser, "clpadr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("clpadt", new RtfCtrlWordHandler(rtfParser, "clpadt", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("clshdng", new RtfCtrlWordHandler(rtfParser, "clshdng", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("clshdngraw", new RtfCtrlWordHandler(rtfParser, "clshdngraw", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("clshdrawnil", new RtfCtrlWordHandler(rtfParser, "clshdrawnil", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("clsplit", new RtfCtrlWordHandler(rtfParser, "clsplit", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("clsplitr", new RtfCtrlWordHandler(rtfParser, "clsplitr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("cltxbtlr", new RtfCtrlWordHandler(rtfParser, "cltxbtlr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("cltxlrtb", new RtfCtrlWordHandler(rtfParser, "cltxlrtb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("cltxlrtbv", new RtfCtrlWordHandler(rtfParser, "cltxlrtbv", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("cltxtbrl", new RtfCtrlWordHandler(rtfParser, "cltxtbrl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("cltxtbrlv", new RtfCtrlWordHandler(rtfParser, "cltxtbrlv", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("clvertalb", new RtfCtrlWordHandler(rtfParser, "clvertalb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("clvertalc", new RtfCtrlWordHandler(rtfParser, "clvertalc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("clvertalt", new RtfCtrlWordHandler(rtfParser, "clvertalt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("clvmgf", new RtfCtrlWordHandler(rtfParser, "clvmgf", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("clvmrg", new RtfCtrlWordHandler(rtfParser, "clvmrg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("clwWidth", new RtfCtrlWordHandler(rtfParser, "clwWidth", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("cmaindarkone", new RtfCtrlWordHandler(rtfParser, "cmaindarkone", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("cmaindarktwo", new RtfCtrlWordHandler(rtfParser, "cmaindarktwo", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("cmainlightone", new RtfCtrlWordHandler(rtfParser, "cmainlightone", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("cmainlighttwo", new RtfCtrlWordHandler(rtfParser, "cmainlighttwo", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("collapsed", new RtfCtrlWordHandler(rtfParser, "collapsed", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("colno", new RtfCtrlWordHandler(rtfParser, "colno", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("colorschememapping", new RtfCtrlWordHandler(rtfParser, "colorschememapping", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", null));
+		ctrlWords.put("colortbl", new RtfCtrlWordHandler(rtfParser, "colortbl", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationColorTable"));
+		ctrlWords.put("cols", new RtfCtrlWordHandler(rtfParser, "cols", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("colsr", new RtfCtrlWordHandler(rtfParser, "colsr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("colsx", new RtfCtrlWordHandler(rtfParser, "colsx", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("column", new RtfCtrlWordHandler(rtfParser, "column", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null));
+		ctrlWords.put("colw", new RtfCtrlWordHandler(rtfParser, "colw", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("comment", new RtfCtrlWordHandler(rtfParser, "comment", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationInfo"));
+		ctrlWords.put("company", new RtfCtrlWordHandler(rtfParser, "company", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationInfo"));
+		ctrlWords.put("contextualspace", new RtfCtrlWordHandler(rtfParser, "contextualspace", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("cpg", new RtfCtrlWordHandler(rtfParser, "cpg", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("crauth", new RtfCtrlWordHandler(rtfParser, "crauth", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("crdate", new RtfCtrlWordHandler(rtfParser, "crdate", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("creatim", new RtfCtrlWordHandler(rtfParser, "creatim", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationNull"));
+		ctrlWords.put("cs", new RtfCtrlWordHandler(rtfParser, "cs", 0, true, RtfCtrlWordType.VALUE, "\\*\\", " ", null));
+		ctrlWords.put("cshade", new RtfCtrlWordHandler(rtfParser, "cshade", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("ctextone", new RtfCtrlWordHandler(rtfParser, "ctextone", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("ctexttwo", new RtfCtrlWordHandler(rtfParser, "ctexttwo", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("ctint", new RtfCtrlWordHandler(rtfParser, "ctint", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("ctrl", new RtfCtrlWordHandler(rtfParser, "ctrl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("cts", new RtfCtrlWordHandler(rtfParser, "cts", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("cufi", new RtfCtrlWordHandler(rtfParser, "cufi", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("culi", new RtfCtrlWordHandler(rtfParser, "culi", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("curi", new RtfCtrlWordHandler(rtfParser, "curi", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("cvmme", new RtfCtrlWordHandler(rtfParser, "cvmme", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("datafield", new RtfCtrlWordHandler(rtfParser, "datafield", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("datastore", new RtfCtrlWordHandler(rtfParser, "datastore", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("date", new RtfCtrlWordHandler(rtfParser, "date", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("dbch", new RtfCtrlWordHandler(rtfParser, "dbch", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("defchp", new RtfCtrlWordHandler(rtfParser, "defchp", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("deff", new RtfCtrlWordHandler(rtfParser, "deff", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("defformat", new RtfCtrlWordHandler(rtfParser, "defformat", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("deflang", new RtfCtrlWordHandler(rtfParser, "deflang", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("deflangfe", new RtfCtrlWordHandler(rtfParser, "deflangfe", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("defpap", new RtfCtrlWordHandler(rtfParser, "defpap", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("defshp", new RtfCtrlWordHandler(rtfParser, "defshp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("deftab", new RtfCtrlWordHandler(rtfParser, "deftab", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("deleted", new RtfCtrlWordHandler(rtfParser, "deleted", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("delrsid", new RtfCtrlWordHandler(rtfParser, "delrsid", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("dfrauth", new RtfCtrlWordHandler(rtfParser, "dfrauth", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("dfrdate", new RtfCtrlWordHandler(rtfParser, "dfrdate", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("dfrmtxtx", new RtfCtrlWordHandler(rtfParser, "dfrmtxtx", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("dfrmtxty", new RtfCtrlWordHandler(rtfParser, "dfrmtxty", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("dfrstart", new RtfCtrlWordHandler(rtfParser, "dfrstart", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("dfrstop", new RtfCtrlWordHandler(rtfParser, "dfrstop", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("dfrxst", new RtfCtrlWordHandler(rtfParser, "dfrxst", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("dghorigin", new RtfCtrlWordHandler(rtfParser, "dghorigin", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("dghshow", new RtfCtrlWordHandler(rtfParser, "dghshow", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("dghspace", new RtfCtrlWordHandler(rtfParser, "dghspace", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("dgmargin", new RtfCtrlWordHandler(rtfParser, "dgmargin", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("dgsnap", new RtfCtrlWordHandler(rtfParser, "dgsnap", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("dgvorigin", new RtfCtrlWordHandler(rtfParser, "dgvorigin", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("dgvshow", new RtfCtrlWordHandler(rtfParser, "dgvshow", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("dgvspace", new RtfCtrlWordHandler(rtfParser, "dgvspace", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("dibitmap", new RtfCtrlWordHandler(rtfParser, "dibitmap", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("dn", new RtfCtrlWordHandler(rtfParser, "dn", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("dntblnsbdb", new RtfCtrlWordHandler(rtfParser, "dntblnsbdb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("do", new RtfCtrlWordHandler(rtfParser, "do", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("dobxcolumn", new RtfCtrlWordHandler(rtfParser, "dobxcolumn", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("dobxmargin", new RtfCtrlWordHandler(rtfParser, "dobxmargin", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("dobxpage", new RtfCtrlWordHandler(rtfParser, "dobxpage", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("dobymargin", new RtfCtrlWordHandler(rtfParser, "dobymargin", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("dobypage", new RtfCtrlWordHandler(rtfParser, "dobypage", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("dobypara", new RtfCtrlWordHandler(rtfParser, "dobypara", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("doccomm", new RtfCtrlWordHandler(rtfParser, "doccomm", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("doctemp", new RtfCtrlWordHandler(rtfParser, "doctemp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("doctype", new RtfCtrlWordHandler(rtfParser, "doctype", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("docvar", new RtfCtrlWordHandler(rtfParser, "docvar", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("dodhgt", new RtfCtrlWordHandler(rtfParser, "dodhgt", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("dolock", new RtfCtrlWordHandler(rtfParser, "dolock", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("donotembedlingdata", new RtfCtrlWordHandler(rtfParser, "donotembedlingdata", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("donotembedsysfont", new RtfCtrlWordHandler(rtfParser, "donotembedsysfont", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("donotshowcomments", new RtfCtrlWordHandler(rtfParser, "donotshowcomments", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("donotshowinsdel", new RtfCtrlWordHandler(rtfParser, "donotshowinsdel", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("donotshowmarkup", new RtfCtrlWordHandler(rtfParser, "donotshowmarkup", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("donotshowprops", new RtfCtrlWordHandler(rtfParser, "donotshowprops", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("dpaendhol", new RtfCtrlWordHandler(rtfParser, "dpaendhol", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("dpaendl", new RtfCtrlWordHandler(rtfParser, "dpaendl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("dpaendsol", new RtfCtrlWordHandler(rtfParser, "dpaendsol", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("dpaendw", new RtfCtrlWordHandler(rtfParser, "dpaendw", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("dparc", new RtfCtrlWordHandler(rtfParser, "dparc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("dparcflipx", new RtfCtrlWordHandler(rtfParser, "dparcflipx", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("dparcflipy", new RtfCtrlWordHandler(rtfParser, "dparcflipy", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("dpastarthol", new RtfCtrlWordHandler(rtfParser, "dpastarthol", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("dpastartl", new RtfCtrlWordHandler(rtfParser, "dpastartl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("dpastartsol", new RtfCtrlWordHandler(rtfParser, "dpastartsol", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("dpastartw", new RtfCtrlWordHandler(rtfParser, "dpastartw", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("dpcallout", new RtfCtrlWordHandler(rtfParser, "dpcallout", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("dpcoa", new RtfCtrlWordHandler(rtfParser, "dpcoa", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("dpcoaccent", new RtfCtrlWordHandler(rtfParser, "dpcoaccent", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("dpcobestfit", new RtfCtrlWordHandler(rtfParser, "dpcobestfit", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("dpcoborder", new RtfCtrlWordHandler(rtfParser, "dpcoborder", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("dpcodabs", new RtfCtrlWordHandler(rtfParser, "dpcodabs", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("dpcodbottom", new RtfCtrlWordHandler(rtfParser, "dpcodbottom", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("dpcodcenter", new RtfCtrlWordHandler(rtfParser, "dpcodcenter", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("dpcodescent", new RtfCtrlWordHandler(rtfParser, "dpcodescent", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("dpcodtop", new RtfCtrlWordHandler(rtfParser, "dpcodtop", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("dpcolength", new RtfCtrlWordHandler(rtfParser, "dpcolength", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("dpcominusx", new RtfCtrlWordHandler(rtfParser, "dpcominusx", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("dpcominusy", new RtfCtrlWordHandler(rtfParser, "dpcominusy", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("dpcooffset", new RtfCtrlWordHandler(rtfParser, "dpcooffset", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("dpcosmarta", new RtfCtrlWordHandler(rtfParser, "dpcosmarta", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("dpcotdouble", new RtfCtrlWordHandler(rtfParser, "dpcotdouble", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("dpcotright", new RtfCtrlWordHandler(rtfParser, "dpcotright", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("dpcotsingle", new RtfCtrlWordHandler(rtfParser, "dpcotsingle", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("dpcottriple", new RtfCtrlWordHandler(rtfParser, "dpcottriple", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("dpcount", new RtfCtrlWordHandler(rtfParser, "dpcount", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("dpellipse", new RtfCtrlWordHandler(rtfParser, "dpellipse", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("dpendgroup", new RtfCtrlWordHandler(rtfParser, "dpendgroup", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("dpfillbgcb", new RtfCtrlWordHandler(rtfParser, "dpfillbgcb", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("dpfillbgcg", new RtfCtrlWordHandler(rtfParser, "dpfillbgcg", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("dpfillbgcr", new RtfCtrlWordHandler(rtfParser, "dpfillbgcr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("dpfillbggray", new RtfCtrlWordHandler(rtfParser, "dpfillbggray", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("dpfillbgpal", new RtfCtrlWordHandler(rtfParser, "dpfillbgpal", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("dpfillfgcb", new RtfCtrlWordHandler(rtfParser, "dpfillfgcb", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("dpfillfgcg", new RtfCtrlWordHandler(rtfParser, "dpfillfgcg", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("dpfillfgcr", new RtfCtrlWordHandler(rtfParser, "dpfillfgcr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("dpfillfggray", new RtfCtrlWordHandler(rtfParser, "dpfillfggray", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("dpfillfgpal", new RtfCtrlWordHandler(rtfParser, "dpfillfgpal", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("dpfillpat", new RtfCtrlWordHandler(rtfParser, "dpfillpat", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("dpgroup", new RtfCtrlWordHandler(rtfParser, "dpgroup", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("dpline", new RtfCtrlWordHandler(rtfParser, "dpline", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("dplinecob", new RtfCtrlWordHandler(rtfParser, "dplinecob", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("dplinecog", new RtfCtrlWordHandler(rtfParser, "dplinecog", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("dplinecor", new RtfCtrlWordHandler(rtfParser, "dplinecor", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("dplinedado", new RtfCtrlWordHandler(rtfParser, "dplinedado", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("dplinedadodo", new RtfCtrlWordHandler(rtfParser, "dplinedadodo", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("dplinedash", new RtfCtrlWordHandler(rtfParser, "dplinedash", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("dplinedot", new RtfCtrlWordHandler(rtfParser, "dplinedot", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("dplinegray", new RtfCtrlWordHandler(rtfParser, "dplinegray", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("dplinehollow", new RtfCtrlWordHandler(rtfParser, "dplinehollow", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("dplinepal", new RtfCtrlWordHandler(rtfParser, "dplinepal", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("dplinesolid", new RtfCtrlWordHandler(rtfParser, "dplinesolid", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("dplinew", new RtfCtrlWordHandler(rtfParser, "dplinew", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("dppolycount", new RtfCtrlWordHandler(rtfParser, "dppolycount", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("dppolygon", new RtfCtrlWordHandler(rtfParser, "dppolygon", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("dppolyline", new RtfCtrlWordHandler(rtfParser, "dppolyline", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("dpptx", new RtfCtrlWordHandler(rtfParser, "dpptx", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("dppty", new RtfCtrlWordHandler(rtfParser, "dppty", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("dprect", new RtfCtrlWordHandler(rtfParser, "dprect", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("dproundr", new RtfCtrlWordHandler(rtfParser, "dproundr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("dpshadow", new RtfCtrlWordHandler(rtfParser, "dpshadow", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("dpshadx", new RtfCtrlWordHandler(rtfParser, "dpshadx", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("dpshady", new RtfCtrlWordHandler(rtfParser, "dpshady", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("dptxbtlr", new RtfCtrlWordHandler(rtfParser, "dptxbtlr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("dptxbx", new RtfCtrlWordHandler(rtfParser, "dptxbx", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("dptxbxmar", new RtfCtrlWordHandler(rtfParser, "dptxbxmar", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("dptxbxtext", new RtfCtrlWordHandler(rtfParser, "dptxbxtext", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", null));
+		ctrlWords.put("dptxlrtb", new RtfCtrlWordHandler(rtfParser, "dptxlrtb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("dptxlrtbv", new RtfCtrlWordHandler(rtfParser, "dptxlrtbv", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("dptxtbrl", new RtfCtrlWordHandler(rtfParser, "dptxtbrl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("dptxtbrlv", new RtfCtrlWordHandler(rtfParser, "dptxtbrlv", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("dpx", new RtfCtrlWordHandler(rtfParser, "dpx", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("dpxsize", new RtfCtrlWordHandler(rtfParser, "dpxsize", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("dpy", new RtfCtrlWordHandler(rtfParser, "dpy", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("dpysize", new RtfCtrlWordHandler(rtfParser, "dpysize", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("dropcapli", new RtfCtrlWordHandler(rtfParser, "dropcapli", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("dropcapt", new RtfCtrlWordHandler(rtfParser, "dropcapt", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("ds", new RtfCtrlWordHandler(rtfParser, "ds", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("dxfrtext", new RtfCtrlWordHandler(rtfParser, "dxfrtext", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("dy", new RtfCtrlWordHandler(rtfParser, "dy", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("ebcend", new RtfCtrlWordHandler(rtfParser, "ebcend", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", null));
+		ctrlWords.put("ebcstart", new RtfCtrlWordHandler(rtfParser, "ebcstart", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", null));
+		ctrlWords.put("edmins", new RtfCtrlWordHandler(rtfParser, "edmins", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("embo", new RtfCtrlWordHandler(rtfParser, "embo", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("emdash", new RtfCtrlWordHandler(rtfParser, "emdash", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", "\0x151"));
+		ctrlWords.put("emfblip", new RtfCtrlWordHandler(rtfParser, "emfblip", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("emspace", new RtfCtrlWordHandler(rtfParser, "emspace", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null));
+		ctrlWords.put("endash", new RtfCtrlWordHandler(rtfParser, "endash", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", "\0x150"));
+		ctrlWords.put("enddoc", new RtfCtrlWordHandler(rtfParser, "enddoc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("endnhere", new RtfCtrlWordHandler(rtfParser, "endnhere", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("endnotes", new RtfCtrlWordHandler(rtfParser, "endnotes", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("enforceprot", new RtfCtrlWordHandler(rtfParser, "enforceprot", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("enspace", new RtfCtrlWordHandler(rtfParser, "enspace", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null));
+		ctrlWords.put("expnd", new RtfCtrlWordHandler(rtfParser, "expnd", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("expndtw", new RtfCtrlWordHandler(rtfParser, "expndtw", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("expshrtn", new RtfCtrlWordHandler(rtfParser, "expshrtn", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("f", new RtfCtrlWordHandler(rtfParser, "f", 0, true, RtfCtrlWordType.VALUE, "\\", " ", RtfProperty.CHARACTER_FONT));
+		ctrlWords.put("faauto", new RtfCtrlWordHandler(rtfParser, "faauto", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("facenter", new RtfCtrlWordHandler(rtfParser, "facenter", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("facingp", new RtfCtrlWordHandler(rtfParser, "facingp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("factoidname", new RtfCtrlWordHandler(rtfParser, "factoidname", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", null));
+		ctrlWords.put("fafixed", new RtfCtrlWordHandler(rtfParser, "fafixed", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("fahang", new RtfCtrlWordHandler(rtfParser, "fahang", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("falt", new RtfCtrlWordHandler(rtfParser, "falt", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationFontTable")); //"RtfDestinationAlternateFont"));
+		ctrlWords.put("faroman", new RtfCtrlWordHandler(rtfParser, "faroman", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("favar", new RtfCtrlWordHandler(rtfParser, "favar", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("fbias", new RtfCtrlWordHandler(rtfParser, "fbias", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("fbidi", new RtfCtrlWordHandler(rtfParser, "fbidi", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("fbimajor", new RtfCtrlWordHandler(rtfParser, "fbimajor", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("fbiminor", new RtfCtrlWordHandler(rtfParser, "fbiminor", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("fchars", new RtfCtrlWordHandler(rtfParser, "fchars", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", null));
+		ctrlWords.put("fcharset", new RtfCtrlWordHandler(rtfParser, "fcharset", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("fdbmajor", new RtfCtrlWordHandler(rtfParser, "fdbmajor", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("fdbminor", new RtfCtrlWordHandler(rtfParser, "fdbminor", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("fdecor", new RtfCtrlWordHandler(rtfParser, "fdecor", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("felnbrelev", new RtfCtrlWordHandler(rtfParser, "felnbrelev", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("fet", new RtfCtrlWordHandler(rtfParser, "fet", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("fetch", new RtfCtrlWordHandler(rtfParser, "fetch", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("ffdefres", new RtfCtrlWordHandler(rtfParser, "ffdefres", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("ffdeftext", new RtfCtrlWordHandler(rtfParser, "ffdeftext", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("ffentrymcr", new RtfCtrlWordHandler(rtfParser, "ffentrymcr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("ffexitmcr", new RtfCtrlWordHandler(rtfParser, "ffexitmcr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("ffformat", new RtfCtrlWordHandler(rtfParser, "ffformat", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("ffhaslistbox", new RtfCtrlWordHandler(rtfParser, "ffhaslistbox", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("ffhelptext", new RtfCtrlWordHandler(rtfParser, "ffhelptext", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("ffhps", new RtfCtrlWordHandler(rtfParser, "ffhps", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("ffl", new RtfCtrlWordHandler(rtfParser, "ffl", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("ffmaxlen", new RtfCtrlWordHandler(rtfParser, "ffmaxlen", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("ffname", new RtfCtrlWordHandler(rtfParser, "ffname", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("ffownhelp", new RtfCtrlWordHandler(rtfParser, "ffownhelp", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("ffownstat", new RtfCtrlWordHandler(rtfParser, "ffownstat", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("ffprot", new RtfCtrlWordHandler(rtfParser, "ffprot", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("ffrecalc", new RtfCtrlWordHandler(rtfParser, "ffrecalc", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("ffres", new RtfCtrlWordHandler(rtfParser, "ffres", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("ffsize", new RtfCtrlWordHandler(rtfParser, "ffsize", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("ffstattext", new RtfCtrlWordHandler(rtfParser, "ffstattext", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("fftype", new RtfCtrlWordHandler(rtfParser, "fftype", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("fftypetxt", new RtfCtrlWordHandler(rtfParser, "fftypetxt", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("fhimajor", new RtfCtrlWordHandler(rtfParser, "fhimajor", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("fhiminor", new RtfCtrlWordHandler(rtfParser, "fhiminor", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("fi", new RtfCtrlWordHandler(rtfParser, "fi", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("fid", new RtfCtrlWordHandler(rtfParser, "fid", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("field", new RtfCtrlWordHandler(rtfParser, "field", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("file", new RtfCtrlWordHandler(rtfParser, "file", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("filetbl", new RtfCtrlWordHandler(rtfParser, "filetbl", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("fittext", new RtfCtrlWordHandler(rtfParser, "fittext", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("fjgothic", new RtfCtrlWordHandler(rtfParser, "fjgothic", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("fjminchou", new RtfCtrlWordHandler(rtfParser, "fjminchou", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("fldalt", new RtfCtrlWordHandler(rtfParser, "fldalt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("flddirty", new RtfCtrlWordHandler(rtfParser, "flddirty", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("fldedit", new RtfCtrlWordHandler(rtfParser, "fldedit", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("fldinst", new RtfCtrlWordHandler(rtfParser, "fldinst", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("fldlock", new RtfCtrlWordHandler(rtfParser, "fldlock", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("fldpriv", new RtfCtrlWordHandler(rtfParser, "fldpriv", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("fldrslt", new RtfCtrlWordHandler(rtfParser, "fldrslt", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("fldtype", new RtfCtrlWordHandler(rtfParser, "fldtype", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("flomajor", new RtfCtrlWordHandler(rtfParser, "flomajor", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("flominor", new RtfCtrlWordHandler(rtfParser, "flominor", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("fmodern", new RtfCtrlWordHandler(rtfParser, "fmodern", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("fn", new RtfCtrlWordHandler(rtfParser, "fn", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("fname", new RtfCtrlWordHandler(rtfParser, "fname", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("fnetwork", new RtfCtrlWordHandler(rtfParser, "fnetwork", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("fnil", new RtfCtrlWordHandler(rtfParser, "fnil", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("fnonfilesys", new RtfCtrlWordHandler(rtfParser, "fnonfilesys", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("fontemb", new RtfCtrlWordHandler(rtfParser, "fontemb", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("fontfile", new RtfCtrlWordHandler(rtfParser, "fontfile", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("fonttbl", new RtfCtrlWordHandler(rtfParser, "fonttbl", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationFontTable"));
+		ctrlWords.put("footer", new RtfCtrlWordHandler(rtfParser, "footer", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("footerf", new RtfCtrlWordHandler(rtfParser, "footerf", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("footerl", new RtfCtrlWordHandler(rtfParser, "footerl", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", null));
+		ctrlWords.put("footerr", new RtfCtrlWordHandler(rtfParser, "footerr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("footery", new RtfCtrlWordHandler(rtfParser, "footery", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("footnote", new RtfCtrlWordHandler(rtfParser, "footnote", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("forceupgrade", new RtfCtrlWordHandler(rtfParser, "forceupgrade", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("formdisp", new RtfCtrlWordHandler(rtfParser, "formdisp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("formfield", new RtfCtrlWordHandler(rtfParser, "formfield", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("formprot", new RtfCtrlWordHandler(rtfParser, "formprot", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("formshade", new RtfCtrlWordHandler(rtfParser, "formshade", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("fosnum", new RtfCtrlWordHandler(rtfParser, "fosnum", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("fprq", new RtfCtrlWordHandler(rtfParser, "fprq", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("fracwidth", new RtfCtrlWordHandler(rtfParser, "fracwidth", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("frelative", new RtfCtrlWordHandler(rtfParser, "frelative", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("frmtxbtlr", new RtfCtrlWordHandler(rtfParser, "frmtxbtlr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("frmtxlrtb", new RtfCtrlWordHandler(rtfParser, "frmtxlrtb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("frmtxlrtbv", new RtfCtrlWordHandler(rtfParser, "frmtxlrtbv", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("frmtxtbrl", new RtfCtrlWordHandler(rtfParser, "frmtxtbrl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("frmtxtbrlv", new RtfCtrlWordHandler(rtfParser, "frmtxtbrlv", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("froman", new RtfCtrlWordHandler(rtfParser, "froman", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("fromhtml", new RtfCtrlWordHandler(rtfParser, "fromhtml", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("fromtext", new RtfCtrlWordHandler(rtfParser, "fromtext", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("fs", new RtfCtrlWordHandler(rtfParser, "fs", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("fscript", new RtfCtrlWordHandler(rtfParser, "fscript", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("fswiss", new RtfCtrlWordHandler(rtfParser, "fswiss", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("ftech", new RtfCtrlWordHandler(rtfParser, "ftech", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("ftnalt", new RtfCtrlWordHandler(rtfParser, "ftnalt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("ftnbj", new RtfCtrlWordHandler(rtfParser, "ftnbj", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("ftncn", new RtfCtrlWordHandler(rtfParser, "ftncn", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("ftnil", new RtfCtrlWordHandler(rtfParser, "ftnil", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("ftnlytwnine", new RtfCtrlWordHandler(rtfParser, "ftnlytwnine", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("ftnnalc", new RtfCtrlWordHandler(rtfParser, "ftnnalc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("ftnnar", new RtfCtrlWordHandler(rtfParser, "ftnnar", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("ftnnauc", new RtfCtrlWordHandler(rtfParser, "ftnnauc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("ftnnchi", new RtfCtrlWordHandler(rtfParser, "ftnnchi", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("ftnnchosung", new RtfCtrlWordHandler(rtfParser, "ftnnchosung", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("ftnncnum", new RtfCtrlWordHandler(rtfParser, "ftnncnum", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("ftnndbar", new RtfCtrlWordHandler(rtfParser, "ftnndbar", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("ftnndbnum", new RtfCtrlWordHandler(rtfParser, "ftnndbnum", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("ftnndbnumd", new RtfCtrlWordHandler(rtfParser, "ftnndbnumd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("ftnndbnumk", new RtfCtrlWordHandler(rtfParser, "ftnndbnumk", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("ftnndbnumt", new RtfCtrlWordHandler(rtfParser, "ftnndbnumt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("ftnnganada", new RtfCtrlWordHandler(rtfParser, "ftnnganada", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("ftnngbnum", new RtfCtrlWordHandler(rtfParser, "ftnngbnum", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("ftnngbnumd", new RtfCtrlWordHandler(rtfParser, "ftnngbnumd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("ftnngbnumk", new RtfCtrlWordHandler(rtfParser, "ftnngbnumk", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("ftnngbnuml", new RtfCtrlWordHandler(rtfParser, "ftnngbnuml", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("ftnnrlc", new RtfCtrlWordHandler(rtfParser, "ftnnrlc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("ftnnruc", new RtfCtrlWordHandler(rtfParser, "ftnnruc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("ftnnzodiac", new RtfCtrlWordHandler(rtfParser, "ftnnzodiac", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("ftnnzodiacd", new RtfCtrlWordHandler(rtfParser, "ftnnzodiacd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("ftnnzodiacl", new RtfCtrlWordHandler(rtfParser, "ftnnzodiacl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("ftnrestart", new RtfCtrlWordHandler(rtfParser, "ftnrestart", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("ftnrstcont", new RtfCtrlWordHandler(rtfParser, "ftnrstcont", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("ftnrstpg", new RtfCtrlWordHandler(rtfParser, "ftnrstpg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("ftnsep", new RtfCtrlWordHandler(rtfParser, "ftnsep", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("ftnsepc", new RtfCtrlWordHandler(rtfParser, "ftnsepc", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("ftnstart", new RtfCtrlWordHandler(rtfParser, "ftnstart", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("ftntj", new RtfCtrlWordHandler(rtfParser, "ftntj", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("fttruetype", new RtfCtrlWordHandler(rtfParser, "fttruetype", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("fvaliddos", new RtfCtrlWordHandler(rtfParser, "fvaliddos", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("fvalidhpfs", new RtfCtrlWordHandler(rtfParser, "fvalidhpfs", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("fvalidmac", new RtfCtrlWordHandler(rtfParser, "fvalidmac", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("fvalidntfs", new RtfCtrlWordHandler(rtfParser, "fvalidntfs", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("g", new RtfCtrlWordHandler(rtfParser, "g", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("gcw", new RtfCtrlWordHandler(rtfParser, "gcw", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("generator", new RtfCtrlWordHandler(rtfParser, "generator", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationNull"));
+		ctrlWords.put("green", new RtfCtrlWordHandler(rtfParser, "green", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("gridtbl", new RtfCtrlWordHandler(rtfParser, "gridtbl", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("gutter", new RtfCtrlWordHandler(rtfParser, "gutter", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("gutterprl", new RtfCtrlWordHandler(rtfParser, "gutterprl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("guttersxn", new RtfCtrlWordHandler(rtfParser, "guttersxn", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("header", new RtfCtrlWordHandler(rtfParser, "header", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("headerf", new RtfCtrlWordHandler(rtfParser, "headerf", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("headerl", new RtfCtrlWordHandler(rtfParser, "headerl", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("headerr", new RtfCtrlWordHandler(rtfParser, "headerr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("headery", new RtfCtrlWordHandler(rtfParser, "headery", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("hich", new RtfCtrlWordHandler(rtfParser, "hich", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("highlight", new RtfCtrlWordHandler(rtfParser, "highlight", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("hlfr", new RtfCtrlWordHandler(rtfParser, "hlfr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("hlinkbase", new RtfCtrlWordHandler(rtfParser, "hlinkbase", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("hlloc", new RtfCtrlWordHandler(rtfParser, "hlloc", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("hlsrc", new RtfCtrlWordHandler(rtfParser, "hlsrc", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("horzdoc", new RtfCtrlWordHandler(rtfParser, "horzdoc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("horzsect", new RtfCtrlWordHandler(rtfParser, "horzsect", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("horzvert", new RtfCtrlWordHandler(rtfParser, "horzvert", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("hr", new RtfCtrlWordHandler(rtfParser, "hr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("hsv", new RtfCtrlWordHandler(rtfParser, "hsv", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("htmautsp", new RtfCtrlWordHandler(rtfParser, "htmautsp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("htmlbase", new RtfCtrlWordHandler(rtfParser, "htmlbase", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("htmlrtf", new RtfCtrlWordHandler(rtfParser, "htmlrtf", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("htmltag", new RtfCtrlWordHandler(rtfParser, "htmltag", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("hwelev", new RtfCtrlWordHandler(rtfParser, "hwelev", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("hyphauto", new RtfCtrlWordHandler(rtfParser, "hyphauto", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("hyphcaps", new RtfCtrlWordHandler(rtfParser, "hyphcaps", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("hyphconsec", new RtfCtrlWordHandler(rtfParser, "hyphconsec", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("hyphhotz", new RtfCtrlWordHandler(rtfParser, "hyphhotz", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("hyphpar", new RtfCtrlWordHandler(rtfParser, "hyphpar", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("i", new RtfCtrlWordHandler(rtfParser, "i", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("id", new RtfCtrlWordHandler(rtfParser, "id", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("ignoremixedcontent", new RtfCtrlWordHandler(rtfParser, "ignoremixedcontent", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("ilfomacatclnup", new RtfCtrlWordHandler(rtfParser, "ilfomacatclnup", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("ilvl", new RtfCtrlWordHandler(rtfParser, "ilvl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("impr", new RtfCtrlWordHandler(rtfParser, "impr", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("indmirror", new RtfCtrlWordHandler(rtfParser, "indmirror", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("indrlsweleven", new RtfCtrlWordHandler(rtfParser, "indrlsweleven", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("info", new RtfCtrlWordHandler(rtfParser, "info", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationInfo"));
+		ctrlWords.put("insrsid", new RtfCtrlWordHandler(rtfParser, "insrsid", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("intbl", new RtfCtrlWordHandler(rtfParser, "intbl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("ipgp", new RtfCtrlWordHandler(rtfParser, "ipgp", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("irow", new RtfCtrlWordHandler(rtfParser, "irow", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("irowband", new RtfCtrlWordHandler(rtfParser, "irowband", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("itap", new RtfCtrlWordHandler(rtfParser, "itap", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("ixe", new RtfCtrlWordHandler(rtfParser, "ixe", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("jclisttab", new RtfCtrlWordHandler(rtfParser, "jclisttab", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("jcompress", new RtfCtrlWordHandler(rtfParser, "jcompress", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("jexpand", new RtfCtrlWordHandler(rtfParser, "jexpand", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("jis", new RtfCtrlWordHandler(rtfParser, "jis", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("jpegblip", new RtfCtrlWordHandler(rtfParser, "jpegblip", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("jsksu", new RtfCtrlWordHandler(rtfParser, "jsksu", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("keep", new RtfCtrlWordHandler(rtfParser, "keep", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("keepn", new RtfCtrlWordHandler(rtfParser, "keepn", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("kerning", new RtfCtrlWordHandler(rtfParser, "kerning", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("keycode", new RtfCtrlWordHandler(rtfParser, "keycode", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("keywords", new RtfCtrlWordHandler(rtfParser, "keywords", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationInfo"));
+		ctrlWords.put("krnprsnet", new RtfCtrlWordHandler(rtfParser, "krnprsnet", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("ksulang", new RtfCtrlWordHandler(rtfParser, "ksulang", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("landscape", new RtfCtrlWordHandler(rtfParser, "landscape", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("lang", new RtfCtrlWordHandler(rtfParser, "lang", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("langfe", new RtfCtrlWordHandler(rtfParser, "langfe", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("langfenp", new RtfCtrlWordHandler(rtfParser, "langfenp", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("langnp", new RtfCtrlWordHandler(rtfParser, "langnp", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("lastrow", new RtfCtrlWordHandler(rtfParser, "lastrow", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("latentstyles", new RtfCtrlWordHandler(rtfParser, "latentstyles", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("lbr", new RtfCtrlWordHandler(rtfParser, "lbr", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null));
+		ctrlWords.put("lchars", new RtfCtrlWordHandler(rtfParser, "lchars", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("ldblquote", new RtfCtrlWordHandler(rtfParser, "ldblquote", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", "\0x147"));
+		ctrlWords.put("level", new RtfCtrlWordHandler(rtfParser, "level", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("levelfollow", new RtfCtrlWordHandler(rtfParser, "levelfollow", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("levelindent", new RtfCtrlWordHandler(rtfParser, "levelindent", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("leveljc", new RtfCtrlWordHandler(rtfParser, "leveljc", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("leveljcn", new RtfCtrlWordHandler(rtfParser, "leveljcn", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("levellegal", new RtfCtrlWordHandler(rtfParser, "levellegal", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("levelnfc", new RtfCtrlWordHandler(rtfParser, "levelnfc", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("levelnfcn", new RtfCtrlWordHandler(rtfParser, "levelnfcn", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("levelnorestart", new RtfCtrlWordHandler(rtfParser, "levelnorestart", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("levelnumbers", new RtfCtrlWordHandler(rtfParser, "levelnumbers", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null));
+//		ctrlWords.put("levelnumbers", new RtfCtrlWordHandler(rtfParser, "levelnumbers", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationListTable"));
+		ctrlWords.put("levelold", new RtfCtrlWordHandler(rtfParser, "levelold", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("levelpicture", new RtfCtrlWordHandler(rtfParser, "levelpicture", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("levelprev", new RtfCtrlWordHandler(rtfParser, "levelprev", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("levelprevspace", new RtfCtrlWordHandler(rtfParser, "levelprevspace", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("levelspace", new RtfCtrlWordHandler(rtfParser, "levelspace", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("levelstartat", new RtfCtrlWordHandler(rtfParser, "levelstartat", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("leveltemplateid", new RtfCtrlWordHandler(rtfParser, "leveltemplateid", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("leveltext", new RtfCtrlWordHandler(rtfParser, "leveltext", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("li", new RtfCtrlWordHandler(rtfParser, "li", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("lin", new RtfCtrlWordHandler(rtfParser, "lin", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("line", new RtfCtrlWordHandler(rtfParser, "line", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null));
+		ctrlWords.put("linebetcol", new RtfCtrlWordHandler(rtfParser, "linebetcol", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("linecont", new RtfCtrlWordHandler(rtfParser, "linecont", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("linemod", new RtfCtrlWordHandler(rtfParser, "linemod", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("lineppage", new RtfCtrlWordHandler(rtfParser, "lineppage", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("linerestart", new RtfCtrlWordHandler(rtfParser, "linerestart", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("linestart", new RtfCtrlWordHandler(rtfParser, "linestart", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("linestarts", new RtfCtrlWordHandler(rtfParser, "linestarts", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("linex", new RtfCtrlWordHandler(rtfParser, "linex", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("linkself", new RtfCtrlWordHandler(rtfParser, "linkself", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("linkstyles", new RtfCtrlWordHandler(rtfParser, "linkstyles", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("linktoquery", new RtfCtrlWordHandler(rtfParser, "linktoquery", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("linkval", new RtfCtrlWordHandler(rtfParser, "linkval", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("lisa", new RtfCtrlWordHandler(rtfParser, "lisa", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("lisb", new RtfCtrlWordHandler(rtfParser, "lisb", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("list", new RtfCtrlWordHandler(rtfParser, "list", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("listlevel", new RtfCtrlWordHandler(rtfParser, "listlevel", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("listhybrid", new RtfCtrlWordHandler(rtfParser, "listhybrid", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("listid", new RtfCtrlWordHandler(rtfParser, "listid", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("listname", new RtfCtrlWordHandler(rtfParser, "listname", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationNull"));
+		ctrlWords.put("listoverride", new RtfCtrlWordHandler(rtfParser, "listoverride", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationNull"));
+		ctrlWords.put("listoverridecount", new RtfCtrlWordHandler(rtfParser, "listoverridecount", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("listoverrideformat", new RtfCtrlWordHandler(rtfParser, "listoverrideformat", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("listoverridestart", new RtfCtrlWordHandler(rtfParser, "listoverridestart", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("listoverridestartat", new RtfCtrlWordHandler(rtfParser, "listoverridestartat", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("listoverridetable", new RtfCtrlWordHandler(rtfParser, "listoverridetable", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationNull"));
+		ctrlWords.put("listpicture", new RtfCtrlWordHandler(rtfParser, "listpicture", 0, true, RtfCtrlWordType.DESTINATION, "\\*\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("listrestarthdn", new RtfCtrlWordHandler(rtfParser, "listrestarthdn", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("listsimple", new RtfCtrlWordHandler(rtfParser, "listsimple", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("liststyleid", new RtfCtrlWordHandler(rtfParser, "liststyleid", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("liststylename", new RtfCtrlWordHandler(rtfParser, "liststylename", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("listtable", new RtfCtrlWordHandler(rtfParser, "listtable", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationListTable"));
+		ctrlWords.put("listtemplateid", new RtfCtrlWordHandler(rtfParser, "listtemplateid", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("listtext", new RtfCtrlWordHandler(rtfParser, "listtext", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationNull"));	// ignore this because we understand 97-2007
+		ctrlWords.put("lnbrkrule", new RtfCtrlWordHandler(rtfParser, "lnbrkrule", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("lndscpsxn", new RtfCtrlWordHandler(rtfParser, "lndscpsxn", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("lnongrid", new RtfCtrlWordHandler(rtfParser, "lnongrid", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("loch", new RtfCtrlWordHandler(rtfParser, "loch", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("lquote", new RtfCtrlWordHandler(rtfParser, "lquote", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", "\0x145"));
+		ctrlWords.put("ls", new RtfCtrlWordHandler(rtfParser, "ls", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("lsdlocked", new RtfCtrlWordHandler(rtfParser, "lsdlocked", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("lsdlockeddef", new RtfCtrlWordHandler(rtfParser, "lsdlockeddef", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("lsdlockedexcept", new RtfCtrlWordHandler(rtfParser, "lsdlockedexcept", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("lsdpriority", new RtfCtrlWordHandler(rtfParser, "lsdpriority", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("lsdprioritydef", new RtfCtrlWordHandler(rtfParser, "lsdprioritydef", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("lsdqformat", new RtfCtrlWordHandler(rtfParser, "lsdqformat", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("lsdqformatdef", new RtfCtrlWordHandler(rtfParser, "lsdqformatdef", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("lsdsemihidden", new RtfCtrlWordHandler(rtfParser, "lsdsemihidden", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("lsdsemihiddendef", new RtfCtrlWordHandler(rtfParser, "lsdsemihiddendef", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("lsdstimax", new RtfCtrlWordHandler(rtfParser, "lsdstimax", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("lsdunhideused", new RtfCtrlWordHandler(rtfParser, "lsdunhideused", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("lsdunhideuseddef", new RtfCtrlWordHandler(rtfParser, "lsdunhideuseddef", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("ltrch", new RtfCtrlWordHandler(rtfParser, "ltrch", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("ltrdoc", new RtfCtrlWordHandler(rtfParser, "ltrdoc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("ltrmark", new RtfCtrlWordHandler(rtfParser, "ltrmark", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null));
+		ctrlWords.put("ltrpar", new RtfCtrlWordHandler(rtfParser, "ltrpar", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("ltrrow", new RtfCtrlWordHandler(rtfParser, "ltrrow", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("ltrsect", new RtfCtrlWordHandler(rtfParser, "ltrsect", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("lvltentative", new RtfCtrlWordHandler(rtfParser, "lvltentative", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("lytcalctblwd", new RtfCtrlWordHandler(rtfParser, "lytcalctblwd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("lytexcttp", new RtfCtrlWordHandler(rtfParser, "lytexcttp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("lytprtmet", new RtfCtrlWordHandler(rtfParser, "lytprtmet", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("lyttblrtgr", new RtfCtrlWordHandler(rtfParser, "lyttblrtgr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("mac", new RtfCtrlWordHandler(rtfParser, "mac", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("macc", new RtfCtrlWordHandler(rtfParser, "macc", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("maccpr", new RtfCtrlWordHandler(rtfParser, "maccpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("macpict", new RtfCtrlWordHandler(rtfParser, "macpict", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("mailmerge", new RtfCtrlWordHandler(rtfParser, "mailmerge", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("makebackup", new RtfCtrlWordHandler(rtfParser, "makebackup", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("maln", new RtfCtrlWordHandler(rtfParser, "maln", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("malnscr", new RtfCtrlWordHandler(rtfParser, "malnscr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("manager", new RtfCtrlWordHandler(rtfParser, "manager", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationInfo"));
+		ctrlWords.put("margb", new RtfCtrlWordHandler(rtfParser, "margb", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("margbsxn", new RtfCtrlWordHandler(rtfParser, "margbsxn", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("margl", new RtfCtrlWordHandler(rtfParser, "margl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("marglsxn", new RtfCtrlWordHandler(rtfParser, "marglsxn", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("margmirror", new RtfCtrlWordHandler(rtfParser, "margmirror", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("margmirsxn", new RtfCtrlWordHandler(rtfParser, "margmirsxn", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("margpr", new RtfCtrlWordHandler(rtfParser, "margpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("margr", new RtfCtrlWordHandler(rtfParser, "margr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("margrsxn", new RtfCtrlWordHandler(rtfParser, "margrsxn", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("margsz", new RtfCtrlWordHandler(rtfParser, "margsz", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("margt", new RtfCtrlWordHandler(rtfParser, "margt", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("margtsxn", new RtfCtrlWordHandler(rtfParser, "margtsxn", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("mbar", new RtfCtrlWordHandler(rtfParser, "mbar", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mbarpr", new RtfCtrlWordHandler(rtfParser, "mbarpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mbasejc", new RtfCtrlWordHandler(rtfParser, "mbasejc", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mbegchr", new RtfCtrlWordHandler(rtfParser, "mbegchr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mborderbox", new RtfCtrlWordHandler(rtfParser, "mborderbox", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mborderboxpr", new RtfCtrlWordHandler(rtfParser, "mborderboxpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mbox", new RtfCtrlWordHandler(rtfParser, "mbox", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mboxpr", new RtfCtrlWordHandler(rtfParser, "mboxpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mbrk", new RtfCtrlWordHandler(rtfParser, "mbrk", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("mbrkbin", new RtfCtrlWordHandler(rtfParser, "mbrkbin", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("mbrkbinsub", new RtfCtrlWordHandler(rtfParser, "mbrkbinsub", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("mcgp", new RtfCtrlWordHandler(rtfParser, "mcgp", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("mcgprule", new RtfCtrlWordHandler(rtfParser, "mcgprule", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("mchr", new RtfCtrlWordHandler(rtfParser, "mchr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mcount", new RtfCtrlWordHandler(rtfParser, "mcount", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mcsp", new RtfCtrlWordHandler(rtfParser, "mcsp", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("mctrlpr", new RtfCtrlWordHandler(rtfParser, "mctrlpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("md", new RtfCtrlWordHandler(rtfParser, "md", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mdefjc", new RtfCtrlWordHandler(rtfParser, "mdefjc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("mdeg", new RtfCtrlWordHandler(rtfParser, "mdeg", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mdeghide", new RtfCtrlWordHandler(rtfParser, "mdeghide", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mden", new RtfCtrlWordHandler(rtfParser, "mden", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mdiff", new RtfCtrlWordHandler(rtfParser, "mdiff", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mdispdef", new RtfCtrlWordHandler(rtfParser, "mdispdef", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("mdpr", new RtfCtrlWordHandler(rtfParser, "mdpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("me", new RtfCtrlWordHandler(rtfParser, "me", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mendchr", new RtfCtrlWordHandler(rtfParser, "mendchr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("meqarr", new RtfCtrlWordHandler(rtfParser, "meqarr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("meqarrpr", new RtfCtrlWordHandler(rtfParser, "meqarrpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mf", new RtfCtrlWordHandler(rtfParser, "mf", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mfname", new RtfCtrlWordHandler(rtfParser, "mfname", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mfpr", new RtfCtrlWordHandler(rtfParser, "mfpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mfunc", new RtfCtrlWordHandler(rtfParser, "mfunc", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mfuncpr", new RtfCtrlWordHandler(rtfParser, "mfuncpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mgroupchr", new RtfCtrlWordHandler(rtfParser, "mgroupchr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mgroupchrpr", new RtfCtrlWordHandler(rtfParser, "mgroupchrpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mgrow", new RtfCtrlWordHandler(rtfParser, "mgrow", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mhidebot", new RtfCtrlWordHandler(rtfParser, "mhidebot", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mhideleft", new RtfCtrlWordHandler(rtfParser, "mhideleft", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mhideright", new RtfCtrlWordHandler(rtfParser, "mhideright", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mhidetop", new RtfCtrlWordHandler(rtfParser, "mhidetop", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mhtmltag", new RtfCtrlWordHandler(rtfParser, "mhtmltag", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("min", new RtfCtrlWordHandler(rtfParser, "min", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("mintersp", new RtfCtrlWordHandler(rtfParser, "mintersp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("mintlim", new RtfCtrlWordHandler(rtfParser, "mintlim", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mintrasp", new RtfCtrlWordHandler(rtfParser, "mintrasp", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mjc", new RtfCtrlWordHandler(rtfParser, "mjc", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mlim", new RtfCtrlWordHandler(rtfParser, "mlim", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mlimloc", new RtfCtrlWordHandler(rtfParser, "mlimloc", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mlimlow", new RtfCtrlWordHandler(rtfParser, "mlimlow", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mlimlowpr", new RtfCtrlWordHandler(rtfParser, "mlimlowpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mlimupp", new RtfCtrlWordHandler(rtfParser, "mlimupp", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mlimupppr", new RtfCtrlWordHandler(rtfParser, "mlimupppr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mlit", new RtfCtrlWordHandler(rtfParser, "mlit", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("mlmargin", new RtfCtrlWordHandler(rtfParser, "mlmargin", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("mm", new RtfCtrlWordHandler(rtfParser, "mm", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mmaddfieldname", new RtfCtrlWordHandler(rtfParser, "mmaddfieldname", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mmath", new RtfCtrlWordHandler(rtfParser, "mmath", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mmathfont", new RtfCtrlWordHandler(rtfParser, "mmathfont", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("mmathpara", new RtfCtrlWordHandler(rtfParser, "mmathpara", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mmathpict", new RtfCtrlWordHandler(rtfParser, "mmathpict", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mmathpr", new RtfCtrlWordHandler(rtfParser, "mmathpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mmattach", new RtfCtrlWordHandler(rtfParser, "mmattach", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("mmaxdist", new RtfCtrlWordHandler(rtfParser, "mmaxdist", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mmblanklines", new RtfCtrlWordHandler(rtfParser, "mmblanklines", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("mmblanklinks", new RtfCtrlWordHandler(rtfParser, "mmblanklinks", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("mmc", new RtfCtrlWordHandler(rtfParser, "mmc", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mmcjc", new RtfCtrlWordHandler(rtfParser, "mmcjc", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mmconnectstrdata", new RtfCtrlWordHandler(rtfParser, "mmconnectstrdata", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", null));
+		ctrlWords.put("mmcpr", new RtfCtrlWordHandler(rtfParser, "mmcpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mmcs", new RtfCtrlWordHandler(rtfParser, "mmcs", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mmdatasource", new RtfCtrlWordHandler(rtfParser, "mmdatasource", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mmdatatypeaccess", new RtfCtrlWordHandler(rtfParser, "mmdatatypeaccess", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("mmdatatypeexcel", new RtfCtrlWordHandler(rtfParser, "mmdatatypeexcel", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("mmdatatypefile", new RtfCtrlWordHandler(rtfParser, "mmdatatypefile", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("mmdatatypeodbc", new RtfCtrlWordHandler(rtfParser, "mmdatatypeodbc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("mmdatatypeodso", new RtfCtrlWordHandler(rtfParser, "mmdatatypeodso", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("mmdatatypeqt", new RtfCtrlWordHandler(rtfParser, "mmdatatypeqt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("mmdefaultStructuredQueryLanguage", new RtfCtrlWordHandler(rtfParser, "mmdefaultStructuredQueryLanguage", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("mmdestemail", new RtfCtrlWordHandler(rtfParser, "mmdestemail", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("mmdestfax", new RtfCtrlWordHandler(rtfParser, "mmdestfax", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("mmdestnewdoc", new RtfCtrlWordHandler(rtfParser, "mmdestnewdoc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("mmdestprinter", new RtfCtrlWordHandler(rtfParser, "mmdestprinter", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("mmerrors", new RtfCtrlWordHandler(rtfParser, "mmerrors", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("mmfttypeaddress", new RtfCtrlWordHandler(rtfParser, "mmfttypeaddress", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("mmfttypebarcode", new RtfCtrlWordHandler(rtfParser, "mmfttypebarcode", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("mmfttypedbcolumn", new RtfCtrlWordHandler(rtfParser, "mmfttypedbcolumn", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("mmfttypemapped", new RtfCtrlWordHandler(rtfParser, "mmfttypemapped", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("mmfttypenull", new RtfCtrlWordHandler(rtfParser, "mmfttypenull", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("mmfttypesalutation", new RtfCtrlWordHandler(rtfParser, "mmfttypesalutation", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("mmheadersource", new RtfCtrlWordHandler(rtfParser, "mmheadersource", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mmjdsotype", new RtfCtrlWordHandler(rtfParser, "mmjdsotype", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("mmlinktoquery", new RtfCtrlWordHandler(rtfParser, "mmlinktoquery", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("mmmailsubject", new RtfCtrlWordHandler(rtfParser, "mmmailsubject", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mmmaintypecatalog", new RtfCtrlWordHandler(rtfParser, "mmmaintypecatalog", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("mmmaintypeemail", new RtfCtrlWordHandler(rtfParser, "mmmaintypeemail", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("mmmaintypeenvelopes", new RtfCtrlWordHandler(rtfParser, "mmmaintypeenvelopes", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("mmmaintypefax", new RtfCtrlWordHandler(rtfParser, "mmmaintypefax", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("mmmaintypelabels", new RtfCtrlWordHandler(rtfParser, "mmmaintypelabels", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("mmmaintypeletters", new RtfCtrlWordHandler(rtfParser, "mmmaintypeletters", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("mmodso", new RtfCtrlWordHandler(rtfParser, "mmodso", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mmodsoactive", new RtfCtrlWordHandler(rtfParser, "mmodsoactive", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("mmodsocoldelim", new RtfCtrlWordHandler(rtfParser, "mmodsocoldelim", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("mmodsocolumn", new RtfCtrlWordHandler(rtfParser, "mmodsocolumn", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("mmodsodynaddr", new RtfCtrlWordHandler(rtfParser, "mmodsodynaddr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("mmodsofhdr", new RtfCtrlWordHandler(rtfParser, "mmodsofhdr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("mmodsofilter", new RtfCtrlWordHandler(rtfParser, "mmodsofilter", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mmodsofldmpdata", new RtfCtrlWordHandler(rtfParser, "mmodsofldmpdata", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mmodsofmcolumn", new RtfCtrlWordHandler(rtfParser, "mmodsofmcolumn", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("mmodsohash", new RtfCtrlWordHandler(rtfParser, "mmodsohash", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("mmodsolid", new RtfCtrlWordHandler(rtfParser, "mmodsolid", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("mmodsomappedname", new RtfCtrlWordHandler(rtfParser, "mmodsomappedname", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mmodsoname", new RtfCtrlWordHandler(rtfParser, "mmodsoname", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", null));
+		ctrlWords.put("mmodsorecipdata", new RtfCtrlWordHandler(rtfParser, "mmodsorecipdata", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mmodsosort", new RtfCtrlWordHandler(rtfParser, "mmodsosort", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mmodsosrc", new RtfCtrlWordHandler(rtfParser, "mmodsosrc", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mmodsotable", new RtfCtrlWordHandler(rtfParser, "mmodsotable", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mmodsoudldata", new RtfCtrlWordHandler(rtfParser, "mmodsoudldata", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mmodsouniquetag", new RtfCtrlWordHandler(rtfParser, "mmodsouniquetag", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mmpr", new RtfCtrlWordHandler(rtfParser, "mmpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mmquery", new RtfCtrlWordHandler(rtfParser, "mmquery", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mmr", new RtfCtrlWordHandler(rtfParser, "mmr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mmreccur", new RtfCtrlWordHandler(rtfParser, "mmreccur", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("mmshowdata", new RtfCtrlWordHandler(rtfParser, "mmshowdata", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("mnary", new RtfCtrlWordHandler(rtfParser, "mnary", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mnarylim", new RtfCtrlWordHandler(rtfParser, "mnarylim", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("mnarypr", new RtfCtrlWordHandler(rtfParser, "mnarypr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mnobreak", new RtfCtrlWordHandler(rtfParser, "mnobreak", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mnor", new RtfCtrlWordHandler(rtfParser, "mnor", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("mnum", new RtfCtrlWordHandler(rtfParser, "mnum", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mo", new RtfCtrlWordHandler(rtfParser, "mo", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("mobjdist", new RtfCtrlWordHandler(rtfParser, "mobjdist", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("momath", new RtfCtrlWordHandler(rtfParser, "momath", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("momathpara", new RtfCtrlWordHandler(rtfParser, "momathpara", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("momathparapr", new RtfCtrlWordHandler(rtfParser, "momathparapr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mopemu", new RtfCtrlWordHandler(rtfParser, "mopemu", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mphant", new RtfCtrlWordHandler(rtfParser, "mphant", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mphantpr", new RtfCtrlWordHandler(rtfParser, "mphantpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mplchide", new RtfCtrlWordHandler(rtfParser, "mplchide", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mpos", new RtfCtrlWordHandler(rtfParser, "mpos", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mpostsp", new RtfCtrlWordHandler(rtfParser, "mpostsp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("mpresp", new RtfCtrlWordHandler(rtfParser, "mpresp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("mr", new RtfCtrlWordHandler(rtfParser, "mr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mrad", new RtfCtrlWordHandler(rtfParser, "mrad", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mradpr", new RtfCtrlWordHandler(rtfParser, "mradpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mrmargin", new RtfCtrlWordHandler(rtfParser, "mrmargin", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("mrpr", new RtfCtrlWordHandler(rtfParser, "mrpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mrsp", new RtfCtrlWordHandler(rtfParser, "mrsp", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("mrsprule", new RtfCtrlWordHandler(rtfParser, "mrsprule", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("mscr", new RtfCtrlWordHandler(rtfParser, "mscr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("msepchr", new RtfCtrlWordHandler(rtfParser, "msepchr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mshow", new RtfCtrlWordHandler(rtfParser, "mshow", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mshp", new RtfCtrlWordHandler(rtfParser, "mshp", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("msize", new RtfCtrlWordHandler(rtfParser, "msize", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("msmallfrac", new RtfCtrlWordHandler(rtfParser, "msmallfrac", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("msmcap", new RtfCtrlWordHandler(rtfParser, "msmcap", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("mspre", new RtfCtrlWordHandler(rtfParser, "mspre", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("msprepr", new RtfCtrlWordHandler(rtfParser, "msprepr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mssub", new RtfCtrlWordHandler(rtfParser, "mssub", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mssubpr", new RtfCtrlWordHandler(rtfParser, "mssubpr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mssubsup", new RtfCtrlWordHandler(rtfParser, "mssubsup", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mssubsuppr", new RtfCtrlWordHandler(rtfParser, "mssubsuppr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mssup", new RtfCtrlWordHandler(rtfParser, "mssup", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mssuppr", new RtfCtrlWordHandler(rtfParser, "mssuppr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mstrikebltr", new RtfCtrlWordHandler(rtfParser, "mstrikebltr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mstrikeh", new RtfCtrlWordHandler(rtfParser, "mstrikeh", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mstriketlbr", new RtfCtrlWordHandler(rtfParser, "mstriketlbr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mstrikev", new RtfCtrlWordHandler(rtfParser, "mstrikev", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("msty", new RtfCtrlWordHandler(rtfParser, "msty", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("msub", new RtfCtrlWordHandler(rtfParser, "msub", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("msubhide", new RtfCtrlWordHandler(rtfParser, "msubhide", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("msup", new RtfCtrlWordHandler(rtfParser, "msup", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("msuphide", new RtfCtrlWordHandler(rtfParser, "msuphide", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mt", new RtfCtrlWordHandler(rtfParser, "mt", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("mtext", new RtfCtrlWordHandler(rtfParser, "mtext", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mtransp", new RtfCtrlWordHandler(rtfParser, "mtransp", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mtype", new RtfCtrlWordHandler(rtfParser, "mtype", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mvauth", new RtfCtrlWordHandler(rtfParser, "mvauth", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("mvdate", new RtfCtrlWordHandler(rtfParser, "mvdate", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("mvertjc", new RtfCtrlWordHandler(rtfParser, "mvertjc", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mvf", new RtfCtrlWordHandler(rtfParser, "mvf", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("mvfmf", new RtfCtrlWordHandler(rtfParser, "mvfmf", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mvfml", new RtfCtrlWordHandler(rtfParser, "mvfml", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mvt", new RtfCtrlWordHandler(rtfParser, "mvt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("mvtof", new RtfCtrlWordHandler(rtfParser, "mvtof", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mvtol", new RtfCtrlWordHandler(rtfParser, "mvtol", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mwrapindent", new RtfCtrlWordHandler(rtfParser, "mwrapindent", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("mwrapindet", new RtfCtrlWordHandler(rtfParser, "mwrapindet", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("mwrapright", new RtfCtrlWordHandler(rtfParser, "mwrapright", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("mzeroasc", new RtfCtrlWordHandler(rtfParser, "mzeroasc", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mzerodesc", new RtfCtrlWordHandler(rtfParser, "mzerodesc", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("mzerowid", new RtfCtrlWordHandler(rtfParser, "mzerowid", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("nestcell", new RtfCtrlWordHandler(rtfParser, "nestcell", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null));
+		ctrlWords.put("nestrow", new RtfCtrlWordHandler(rtfParser, "nestrow", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null));
+		ctrlWords.put("nesttableprops", new RtfCtrlWordHandler(rtfParser, "nesttableprops", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("newtblstyruls", new RtfCtrlWordHandler(rtfParser, "newtblstyruls", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("nextfile", new RtfCtrlWordHandler(rtfParser, "nextfile", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("noafcnsttbl", new RtfCtrlWordHandler(rtfParser, "noafcnsttbl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("nobrkwrptbl", new RtfCtrlWordHandler(rtfParser, "nobrkwrptbl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("nocolbal", new RtfCtrlWordHandler(rtfParser, "nocolbal", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("nocompatoptions", new RtfCtrlWordHandler(rtfParser, "nocompatoptions", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("nocwrap", new RtfCtrlWordHandler(rtfParser, "nocwrap", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("nocxsptable", new RtfCtrlWordHandler(rtfParser, "nocxsptable", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("noextrasprl", new RtfCtrlWordHandler(rtfParser, "noextrasprl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("nofchars", new RtfCtrlWordHandler(rtfParser, "nofchars", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("nofcharsws", new RtfCtrlWordHandler(rtfParser, "nofcharsws", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("nofeaturethrottle", new RtfCtrlWordHandler(rtfParser, "nofeaturethrottle", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("nofpages", new RtfCtrlWordHandler(rtfParser, "nofpages", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("nofwords", new RtfCtrlWordHandler(rtfParser, "nofwords", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("nogrowautofit", new RtfCtrlWordHandler(rtfParser, "nogrowautofit", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("noindnmbrts", new RtfCtrlWordHandler(rtfParser, "noindnmbrts", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("nojkernpunct", new RtfCtrlWordHandler(rtfParser, "nojkernpunct", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("nolead", new RtfCtrlWordHandler(rtfParser, "nolead", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("noline", new RtfCtrlWordHandler(rtfParser, "noline", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("nolnhtadjtbl", new RtfCtrlWordHandler(rtfParser, "nolnhtadjtbl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("nonesttables", new RtfCtrlWordHandler(rtfParser, "nonesttables", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+
+//		  new RtfCtrlWordHandler(rtfParser, "shppict", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationShppict" ));//"RtfDestinationShppict"));
+		ctrlWords.put("nonshppict", new RtfCtrlWordHandler(rtfParser, "nonshppict", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationNull"));// "RtfDestinationShppict"));
+		ctrlWords.put("nooverflow", new RtfCtrlWordHandler(rtfParser, "nooverflow", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("noproof", new RtfCtrlWordHandler(rtfParser, "noproof", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("noqfpromote", new RtfCtrlWordHandler(rtfParser, "noqfpromote", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("nosectexpand", new RtfCtrlWordHandler(rtfParser, "nosectexpand", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("nosnaplinegrid", new RtfCtrlWordHandler(rtfParser, "nosnaplinegrid", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("nospaceforul", new RtfCtrlWordHandler(rtfParser, "nospaceforul", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("nosupersub", new RtfCtrlWordHandler(rtfParser, "nosupersub", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("notabind", new RtfCtrlWordHandler(rtfParser, "notabind", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("notbrkcnstfrctbl", new RtfCtrlWordHandler(rtfParser, "notbrkcnstfrctbl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("notcvasp", new RtfCtrlWordHandler(rtfParser, "notcvasp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("notvatxbx", new RtfCtrlWordHandler(rtfParser, "notvatxbx", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("nouicompat", new RtfCtrlWordHandler(rtfParser, "nouicompat", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("noultrlspc", new RtfCtrlWordHandler(rtfParser, "noultrlspc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("nowidctlpar", new RtfCtrlWordHandler(rtfParser, "nowidctlpar", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("nowrap", new RtfCtrlWordHandler(rtfParser, "nowrap", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("nowwrap", new RtfCtrlWordHandler(rtfParser, "nowwrap", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("noxlattoyen", new RtfCtrlWordHandler(rtfParser, "noxlattoyen", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("objalias", new RtfCtrlWordHandler(rtfParser, "objalias", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("objalign", new RtfCtrlWordHandler(rtfParser, "objalign", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("objattph", new RtfCtrlWordHandler(rtfParser, "objattph", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("objautlink", new RtfCtrlWordHandler(rtfParser, "objautlink", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("objclass", new RtfCtrlWordHandler(rtfParser, "objclass", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("objcropb", new RtfCtrlWordHandler(rtfParser, "objcropb", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("objcropl", new RtfCtrlWordHandler(rtfParser, "objcropl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("objcropr", new RtfCtrlWordHandler(rtfParser, "objcropr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("objcropt", new RtfCtrlWordHandler(rtfParser, "objcropt", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("objdata", new RtfCtrlWordHandler(rtfParser, "objdata", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("object", new RtfCtrlWordHandler(rtfParser, "object", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("objemb", new RtfCtrlWordHandler(rtfParser, "objemb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("objh", new RtfCtrlWordHandler(rtfParser, "objh", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("objhtml", new RtfCtrlWordHandler(rtfParser, "objhtml", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("objicemb", new RtfCtrlWordHandler(rtfParser, "objicemb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("objlink", new RtfCtrlWordHandler(rtfParser, "objlink", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("objlock", new RtfCtrlWordHandler(rtfParser, "objlock", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("objname", new RtfCtrlWordHandler(rtfParser, "objname", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("objocx", new RtfCtrlWordHandler(rtfParser, "objocx", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("objpub", new RtfCtrlWordHandler(rtfParser, "objpub", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("objscalex", new RtfCtrlWordHandler(rtfParser, "objscalex", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("objscaley", new RtfCtrlWordHandler(rtfParser, "objscaley", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("objsect", new RtfCtrlWordHandler(rtfParser, "objsect", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("objsetsize", new RtfCtrlWordHandler(rtfParser, "objsetsize", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("objsub", new RtfCtrlWordHandler(rtfParser, "objsub", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("objtime", new RtfCtrlWordHandler(rtfParser, "objtime", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("objtransy", new RtfCtrlWordHandler(rtfParser, "objtransy", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("objupdate", new RtfCtrlWordHandler(rtfParser, "objupdate", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("objw", new RtfCtrlWordHandler(rtfParser, "objw", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("oldas", new RtfCtrlWordHandler(rtfParser, "oldas", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("oldcprops", new RtfCtrlWordHandler(rtfParser, "oldcprops", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("oldlinewrap", new RtfCtrlWordHandler(rtfParser, "oldlinewrap", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("oldpprops", new RtfCtrlWordHandler(rtfParser, "oldpprops", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("oldsprops", new RtfCtrlWordHandler(rtfParser, "oldsprops", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("oldtprops", new RtfCtrlWordHandler(rtfParser, "oldtprops", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("oleclsid", new RtfCtrlWordHandler(rtfParser, "oleclsid", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("operator", new RtfCtrlWordHandler(rtfParser, "operator", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationInfo"));
+		ctrlWords.put("otblrul", new RtfCtrlWordHandler(rtfParser, "otblrul", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("outl", new RtfCtrlWordHandler(rtfParser, "outl", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("outlinelevel", new RtfCtrlWordHandler(rtfParser, "outlinelevel", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("overlay", new RtfCtrlWordHandler(rtfParser, "overlay", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("page", new RtfCtrlWordHandler(rtfParser, "page", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null));
+		ctrlWords.put("pagebb", new RtfCtrlWordHandler(rtfParser, "pagebb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("panose", new RtfCtrlWordHandler(rtfParser, "panose", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationNull"));
+		ctrlWords.put("paperh", new RtfCtrlWordHandler(rtfParser, "paperh", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("paperw", new RtfCtrlWordHandler(rtfParser, "paperw", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("par", new RtfCtrlWordHandler(rtfParser, "par", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", "\n"));
+		ctrlWords.put("pararsid", new RtfCtrlWordHandler(rtfParser, "pararsid", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("pard", new RtfCtrlWordHandler(rtfParser, "pard", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("passwordhash", new RtfCtrlWordHandler(rtfParser, "passwordhash", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("pc", new RtfCtrlWordHandler(rtfParser, "pc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pca", new RtfCtrlWordHandler(rtfParser, "pca", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pgbrdrb", new RtfCtrlWordHandler(rtfParser, "pgbrdrb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pgbrdrfoot", new RtfCtrlWordHandler(rtfParser, "pgbrdrfoot", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pgbrdrhead", new RtfCtrlWordHandler(rtfParser, "pgbrdrhead", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pgbrdrl", new RtfCtrlWordHandler(rtfParser, "pgbrdrl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pgbrdropt", new RtfCtrlWordHandler(rtfParser, "pgbrdropt", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("pgbrdrr", new RtfCtrlWordHandler(rtfParser, "pgbrdrr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pgbrdrsnap", new RtfCtrlWordHandler(rtfParser, "pgbrdrsnap", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pgbrdrt", new RtfCtrlWordHandler(rtfParser, "pgbrdrt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pghsxn", new RtfCtrlWordHandler(rtfParser, "pghsxn", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("pgnbidia", new RtfCtrlWordHandler(rtfParser, "pgnbidia", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pgnbidib", new RtfCtrlWordHandler(rtfParser, "pgnbidib", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pgnchosung", new RtfCtrlWordHandler(rtfParser, "pgnchosung", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pgncnum", new RtfCtrlWordHandler(rtfParser, "pgncnum", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pgncont", new RtfCtrlWordHandler(rtfParser, "pgncont", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pgndbnum", new RtfCtrlWordHandler(rtfParser, "pgndbnum", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pgndbnumd", new RtfCtrlWordHandler(rtfParser, "pgndbnumd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pgndbnumk", new RtfCtrlWordHandler(rtfParser, "pgndbnumk", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pgndbnumt", new RtfCtrlWordHandler(rtfParser, "pgndbnumt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pgndec", new RtfCtrlWordHandler(rtfParser, "pgndec", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pgndecd", new RtfCtrlWordHandler(rtfParser, "pgndecd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pgnganada", new RtfCtrlWordHandler(rtfParser, "pgnganada", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pgngbnum", new RtfCtrlWordHandler(rtfParser, "pgngbnum", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pgngbnumd", new RtfCtrlWordHandler(rtfParser, "pgngbnumd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pgngbnumk", new RtfCtrlWordHandler(rtfParser, "pgngbnumk", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pgngbnuml", new RtfCtrlWordHandler(rtfParser, "pgngbnuml", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pgnhindia", new RtfCtrlWordHandler(rtfParser, "pgnhindia", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pgnhindib", new RtfCtrlWordHandler(rtfParser, "pgnhindib", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pgnhindic", new RtfCtrlWordHandler(rtfParser, "pgnhindic", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pgnhindid", new RtfCtrlWordHandler(rtfParser, "pgnhindid", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pgnhn", new RtfCtrlWordHandler(rtfParser, "pgnhn", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("pgnhnsc", new RtfCtrlWordHandler(rtfParser, "pgnhnsc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pgnhnsh", new RtfCtrlWordHandler(rtfParser, "pgnhnsh", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pgnhnsm", new RtfCtrlWordHandler(rtfParser, "pgnhnsm", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pgnhnsn", new RtfCtrlWordHandler(rtfParser, "pgnhnsn", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pgnhnsp", new RtfCtrlWordHandler(rtfParser, "pgnhnsp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pgnid", new RtfCtrlWordHandler(rtfParser, "pgnid", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("pgnlcltr", new RtfCtrlWordHandler(rtfParser, "pgnlcltr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pgnlcrm", new RtfCtrlWordHandler(rtfParser, "pgnlcrm", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pgnrestart", new RtfCtrlWordHandler(rtfParser, "pgnrestart", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pgnstart", new RtfCtrlWordHandler(rtfParser, "pgnstart", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("pgnstarts", new RtfCtrlWordHandler(rtfParser, "pgnstarts", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("pgnthaia", new RtfCtrlWordHandler(rtfParser, "pgnthaia", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pgnthaib", new RtfCtrlWordHandler(rtfParser, "pgnthaib", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pgnthaic", new RtfCtrlWordHandler(rtfParser, "pgnthaic", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pgnucltr", new RtfCtrlWordHandler(rtfParser, "pgnucltr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pgnucrm", new RtfCtrlWordHandler(rtfParser, "pgnucrm", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pgnvieta", new RtfCtrlWordHandler(rtfParser, "pgnvieta", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pgnx", new RtfCtrlWordHandler(rtfParser, "pgnx", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("pgny", new RtfCtrlWordHandler(rtfParser, "pgny", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("pgnzodiac", new RtfCtrlWordHandler(rtfParser, "pgnzodiac", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pgnzodiacd", new RtfCtrlWordHandler(rtfParser, "pgnzodiacd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pgnzodiacl", new RtfCtrlWordHandler(rtfParser, "pgnzodiacl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pgp", new RtfCtrlWordHandler(rtfParser, "pgp", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationNull"));
+		ctrlWords.put("pgptbl", new RtfCtrlWordHandler(rtfParser, "pgptbl", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationNull"));
+		ctrlWords.put("pgwsxn", new RtfCtrlWordHandler(rtfParser, "pgwsxn", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("phcol", new RtfCtrlWordHandler(rtfParser, "phcol", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("phmrg", new RtfCtrlWordHandler(rtfParser, "phmrg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("phnthaia", new RtfCtrlWordHandler(rtfParser, "phnthaia", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("phpg", new RtfCtrlWordHandler(rtfParser, "phpg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("picbmp", new RtfCtrlWordHandler(rtfParser, "picbmp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("picbpp", new RtfCtrlWordHandler(rtfParser, "picbpp", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("piccropb", new RtfCtrlWordHandler(rtfParser, "piccropb", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("piccropl", new RtfCtrlWordHandler(rtfParser, "piccropl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("piccropr", new RtfCtrlWordHandler(rtfParser, "piccropr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("piccropt", new RtfCtrlWordHandler(rtfParser, "piccropt", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("pich", new RtfCtrlWordHandler(rtfParser, "pich", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("pichgoal", new RtfCtrlWordHandler(rtfParser, "pichgoal", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("picprop", new RtfCtrlWordHandler(rtfParser, "picprop", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationShppict" ));
+		ctrlWords.put("picscaled", new RtfCtrlWordHandler(rtfParser, "picscaled", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("picscalex", new RtfCtrlWordHandler(rtfParser, "picscalex", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("picscaley", new RtfCtrlWordHandler(rtfParser, "picscaley", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("pict", new RtfCtrlWordHandler(rtfParser, "pict", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationShppict" ));
+		ctrlWords.put("picw", new RtfCtrlWordHandler(rtfParser, "picw", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("picwgoal", new RtfCtrlWordHandler(rtfParser, "picwgoal", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("pindtabqc", new RtfCtrlWordHandler(rtfParser, "pindtabqc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pindtabql", new RtfCtrlWordHandler(rtfParser, "pindtabql", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pindtabqr", new RtfCtrlWordHandler(rtfParser, "pindtabqr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("plain", new RtfCtrlWordHandler(rtfParser, "plain", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pmartabqc", new RtfCtrlWordHandler(rtfParser, "pmartabqc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pmartabql", new RtfCtrlWordHandler(rtfParser, "pmartabql", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pmartabqr", new RtfCtrlWordHandler(rtfParser, "pmartabqr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pmmetafile", new RtfCtrlWordHandler(rtfParser, "pmmetafile", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("pn", new RtfCtrlWordHandler(rtfParser, "pn", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("pnacross", new RtfCtrlWordHandler(rtfParser, "pnacross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pnaiu", new RtfCtrlWordHandler(rtfParser, "pnaiu", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pnaiud", new RtfCtrlWordHandler(rtfParser, "pnaiud", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pnaiueo", new RtfCtrlWordHandler(rtfParser, "pnaiueo", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pnaiueod", new RtfCtrlWordHandler(rtfParser, "pnaiueod", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pnb", new RtfCtrlWordHandler(rtfParser, "pnb", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("pnbidia", new RtfCtrlWordHandler(rtfParser, "pnbidia", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pnbidib", new RtfCtrlWordHandler(rtfParser, "pnbidib", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pncaps", new RtfCtrlWordHandler(rtfParser, "pncaps", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("pncard", new RtfCtrlWordHandler(rtfParser, "pncard", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pncf", new RtfCtrlWordHandler(rtfParser, "pncf", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("pnchosung", new RtfCtrlWordHandler(rtfParser, "pnchosung", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pncnum", new RtfCtrlWordHandler(rtfParser, "pncnum", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pndbnum", new RtfCtrlWordHandler(rtfParser, "pndbnum", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pndbnumd", new RtfCtrlWordHandler(rtfParser, "pndbnumd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pndbnumk", new RtfCtrlWordHandler(rtfParser, "pndbnumk", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pndbnuml", new RtfCtrlWordHandler(rtfParser, "pndbnuml", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pndbnumt", new RtfCtrlWordHandler(rtfParser, "pndbnumt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pndec", new RtfCtrlWordHandler(rtfParser, "pndec", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pndecd", new RtfCtrlWordHandler(rtfParser, "pndecd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pnf", new RtfCtrlWordHandler(rtfParser, "pnf", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("pnfs", new RtfCtrlWordHandler(rtfParser, "pnfs", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("pnganada", new RtfCtrlWordHandler(rtfParser, "pnganada", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pngblip", new RtfCtrlWordHandler(rtfParser, "pngblip", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pngbnum", new RtfCtrlWordHandler(rtfParser, "pngbnum", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pngbnumd", new RtfCtrlWordHandler(rtfParser, "pngbnumd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pngbnumk", new RtfCtrlWordHandler(rtfParser, "pngbnumk", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pngbnuml", new RtfCtrlWordHandler(rtfParser, "pngbnuml", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pnhang", new RtfCtrlWordHandler(rtfParser, "pnhang", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pni", new RtfCtrlWordHandler(rtfParser, "pni", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("pnindent", new RtfCtrlWordHandler(rtfParser, "pnindent", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("pniroha", new RtfCtrlWordHandler(rtfParser, "pniroha", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pnirohad", new RtfCtrlWordHandler(rtfParser, "pnirohad", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pnlcltr", new RtfCtrlWordHandler(rtfParser, "pnlcltr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pnlcrm", new RtfCtrlWordHandler(rtfParser, "pnlcrm", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pnlvl", new RtfCtrlWordHandler(rtfParser, "pnlvl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("pnlvlblt", new RtfCtrlWordHandler(rtfParser, "pnlvlblt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pnlvlbody", new RtfCtrlWordHandler(rtfParser, "pnlvlbody", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pnlvlcont", new RtfCtrlWordHandler(rtfParser, "pnlvlcont", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pnnumonce", new RtfCtrlWordHandler(rtfParser, "pnnumonce", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pnord", new RtfCtrlWordHandler(rtfParser, "pnord", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pnordt", new RtfCtrlWordHandler(rtfParser, "pnordt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pnprev", new RtfCtrlWordHandler(rtfParser, "pnprev", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pnqc", new RtfCtrlWordHandler(rtfParser, "pnqc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pnql", new RtfCtrlWordHandler(rtfParser, "pnql", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pnqr", new RtfCtrlWordHandler(rtfParser, "pnqr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pnrauth", new RtfCtrlWordHandler(rtfParser, "pnrauth", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("pnrdate", new RtfCtrlWordHandler(rtfParser, "pnrdate", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("pnrestart", new RtfCtrlWordHandler(rtfParser, "pnrestart", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pnrnfc", new RtfCtrlWordHandler(rtfParser, "pnrnfc", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("pnrnot", new RtfCtrlWordHandler(rtfParser, "pnrnot", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pnrpnbr", new RtfCtrlWordHandler(rtfParser, "pnrpnbr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("pnrrgb", new RtfCtrlWordHandler(rtfParser, "pnrrgb", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("pnrstart", new RtfCtrlWordHandler(rtfParser, "pnrstart", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("pnrstop", new RtfCtrlWordHandler(rtfParser, "pnrstop", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("pnrxst", new RtfCtrlWordHandler(rtfParser, "pnrxst", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("pnscaps", new RtfCtrlWordHandler(rtfParser, "pnscaps", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("pnseclvl", new RtfCtrlWordHandler(rtfParser, "pnseclvl", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("pnsp", new RtfCtrlWordHandler(rtfParser, "pnsp", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("pnstart", new RtfCtrlWordHandler(rtfParser, "pnstart", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("pnstrike", new RtfCtrlWordHandler(rtfParser, "pnstrike", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("pntext", new RtfCtrlWordHandler(rtfParser, "pntext", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("pntxta", new RtfCtrlWordHandler(rtfParser, "pntxta", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("pntxtb", new RtfCtrlWordHandler(rtfParser, "pntxtb", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("pnucltr", new RtfCtrlWordHandler(rtfParser, "pnucltr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pnucrm", new RtfCtrlWordHandler(rtfParser, "pnucrm", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pnul", new RtfCtrlWordHandler(rtfParser, "pnul", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("pnuld", new RtfCtrlWordHandler(rtfParser, "pnuld", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pnuldash", new RtfCtrlWordHandler(rtfParser, "pnuldash", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pnuldashd", new RtfCtrlWordHandler(rtfParser, "pnuldashd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pnuldashdd", new RtfCtrlWordHandler(rtfParser, "pnuldashdd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pnuldb", new RtfCtrlWordHandler(rtfParser, "pnuldb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pnulhair", new RtfCtrlWordHandler(rtfParser, "pnulhair", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pnulnone", new RtfCtrlWordHandler(rtfParser, "pnulnone", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pnulth", new RtfCtrlWordHandler(rtfParser, "pnulth", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pnulw", new RtfCtrlWordHandler(rtfParser, "pnulw", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pnulwave", new RtfCtrlWordHandler(rtfParser, "pnulwave", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pnzodiac", new RtfCtrlWordHandler(rtfParser, "pnzodiac", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pnzodiacd", new RtfCtrlWordHandler(rtfParser, "pnzodiacd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pnzodiacl", new RtfCtrlWordHandler(rtfParser, "pnzodiacl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("posnegx", new RtfCtrlWordHandler(rtfParser, "posnegx", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("posnegy", new RtfCtrlWordHandler(rtfParser, "posnegy", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("posx", new RtfCtrlWordHandler(rtfParser, "posx", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("posxc", new RtfCtrlWordHandler(rtfParser, "posxc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("posxi", new RtfCtrlWordHandler(rtfParser, "posxi", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("posxl", new RtfCtrlWordHandler(rtfParser, "posxl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("posxo", new RtfCtrlWordHandler(rtfParser, "posxo", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("posxr", new RtfCtrlWordHandler(rtfParser, "posxr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("posy", new RtfCtrlWordHandler(rtfParser, "posy", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("posyb", new RtfCtrlWordHandler(rtfParser, "posyb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("posyc", new RtfCtrlWordHandler(rtfParser, "posyc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("posyil", new RtfCtrlWordHandler(rtfParser, "posyil", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("posyin", new RtfCtrlWordHandler(rtfParser, "posyin", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("posyout", new RtfCtrlWordHandler(rtfParser, "posyout", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("posyt", new RtfCtrlWordHandler(rtfParser, "posyt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("prcolbl", new RtfCtrlWordHandler(rtfParser, "prcolbl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("printdata", new RtfCtrlWordHandler(rtfParser, "printdata", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("printim", new RtfCtrlWordHandler(rtfParser, "printim", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationNull"));
+		ctrlWords.put("private", new RtfCtrlWordHandler(rtfParser, "private", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("propname", new RtfCtrlWordHandler(rtfParser, "propname", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("proptype", new RtfCtrlWordHandler(rtfParser, "proptype", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("protend", new RtfCtrlWordHandler(rtfParser, "protend", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("protlevel", new RtfCtrlWordHandler(rtfParser, "protlevel", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("protstart", new RtfCtrlWordHandler(rtfParser, "protstart", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("protusertbl", new RtfCtrlWordHandler(rtfParser, "protusertbl", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("psover", new RtfCtrlWordHandler(rtfParser, "psover", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("psz", new RtfCtrlWordHandler(rtfParser, "psz", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("ptabldot", new RtfCtrlWordHandler(rtfParser, "ptabldot", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("ptablmdot", new RtfCtrlWordHandler(rtfParser, "ptablmdot", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("ptablminus", new RtfCtrlWordHandler(rtfParser, "ptablminus", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("ptablnone", new RtfCtrlWordHandler(rtfParser, "ptablnone", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("ptabluscore", new RtfCtrlWordHandler(rtfParser, "ptabluscore", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pubauto", new RtfCtrlWordHandler(rtfParser, "pubauto", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pvmrg", new RtfCtrlWordHandler(rtfParser, "pvmrg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pvpara", new RtfCtrlWordHandler(rtfParser, "pvpara", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pvpg", new RtfCtrlWordHandler(rtfParser, "pvpg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("pwd", new RtfCtrlWordHandler(rtfParser, "pwd", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("pxe", new RtfCtrlWordHandler(rtfParser, "pxe", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("qc", new RtfCtrlWordHandler(rtfParser, "qc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("qd", new RtfCtrlWordHandler(rtfParser, "qd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("qj", new RtfCtrlWordHandler(rtfParser, "qj", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("qk", new RtfCtrlWordHandler(rtfParser, "qk", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("ql", new RtfCtrlWordHandler(rtfParser, "ql", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("qmspace", new RtfCtrlWordHandler(rtfParser, "qmspace", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null));
+		ctrlWords.put("qr", new RtfCtrlWordHandler(rtfParser, "qr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("qt", new RtfCtrlWordHandler(rtfParser, "qt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("rawbgdkbdiag", new RtfCtrlWordHandler(rtfParser, "rawbgdkbdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("rawclbgbdiag", new RtfCtrlWordHandler(rtfParser, "rawclbgbdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("rawclbgcross", new RtfCtrlWordHandler(rtfParser, "rawclbgcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("rawclbgdcross", new RtfCtrlWordHandler(rtfParser, "rawclbgdcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("rawclbgdkbdiag", new RtfCtrlWordHandler(rtfParser, "rawclbgdkbdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("rawclbgdkcross", new RtfCtrlWordHandler(rtfParser, "rawclbgdkcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("rawclbgdkdcross", new RtfCtrlWordHandler(rtfParser, "rawclbgdkdcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("rawclbgdkfdiag", new RtfCtrlWordHandler(rtfParser, "rawclbgdkfdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("rawclbgdkhor", new RtfCtrlWordHandler(rtfParser, "rawclbgdkhor", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("rawclbgdkvert", new RtfCtrlWordHandler(rtfParser, "rawclbgdkvert", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("rawclbgfdiag", new RtfCtrlWordHandler(rtfParser, "rawclbgfdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("rawclbghoriz", new RtfCtrlWordHandler(rtfParser, "rawclbghoriz", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("rawclbgvert", new RtfCtrlWordHandler(rtfParser, "rawclbgvert", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("rdblquote", new RtfCtrlWordHandler(rtfParser, "rdblquote", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", "\0x148"));
+		ctrlWords.put("readonlyrecommended", new RtfCtrlWordHandler(rtfParser, "readonlyrecommended", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("readprot", new RtfCtrlWordHandler(rtfParser, "readprot", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("red", new RtfCtrlWordHandler(rtfParser, "red", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("relyonvml", new RtfCtrlWordHandler(rtfParser, "relyonvml", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("rempersonalinfo", new RtfCtrlWordHandler(rtfParser, "rempersonalinfo", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("result", new RtfCtrlWordHandler(rtfParser, "result", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("revauth", new RtfCtrlWordHandler(rtfParser, "revauth", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("revauthdel", new RtfCtrlWordHandler(rtfParser, "revauthdel", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("revbar", new RtfCtrlWordHandler(rtfParser, "revbar", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("revdttm", new RtfCtrlWordHandler(rtfParser, "revdttm", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("revdttmdel", new RtfCtrlWordHandler(rtfParser, "revdttmdel", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("revised", new RtfCtrlWordHandler(rtfParser, "revised", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("revisions", new RtfCtrlWordHandler(rtfParser, "revisions", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("revprop", new RtfCtrlWordHandler(rtfParser, "revprop", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("revprot", new RtfCtrlWordHandler(rtfParser, "revprot", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("revtbl", new RtfCtrlWordHandler(rtfParser, "revtbl", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationNull"));
+		ctrlWords.put("revtim", new RtfCtrlWordHandler(rtfParser, "revtim", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationNull"));
+		ctrlWords.put("ri", new RtfCtrlWordHandler(rtfParser, "ri", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("rin", new RtfCtrlWordHandler(rtfParser, "rin", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("row", new RtfCtrlWordHandler(rtfParser, "row", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null));
+		ctrlWords.put("rquote", new RtfCtrlWordHandler(rtfParser, "rquote", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", "\0x146"));
+		ctrlWords.put("rsid", new RtfCtrlWordHandler(rtfParser, "rsid", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("rsidroot", new RtfCtrlWordHandler(rtfParser, "rsidroot", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("rsidtbl", new RtfCtrlWordHandler(rtfParser, "rsidtbl", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationNull"));
+		ctrlWords.put("rsltbmp", new RtfCtrlWordHandler(rtfParser, "rsltbmp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("rslthtml", new RtfCtrlWordHandler(rtfParser, "rslthtml", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("rsltmerge", new RtfCtrlWordHandler(rtfParser, "rsltmerge", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("rsltpict", new RtfCtrlWordHandler(rtfParser, "rsltpict", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("rsltrtf", new RtfCtrlWordHandler(rtfParser, "rsltrtf", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("rslttxt", new RtfCtrlWordHandler(rtfParser, "rslttxt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("rtf", new RtfCtrlWordHandler(rtfParser, "rtf", 1, true, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("rtlch", new RtfCtrlWordHandler(rtfParser, "rtlch", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("rtldoc", new RtfCtrlWordHandler(rtfParser, "rtldoc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("rtlgutter", new RtfCtrlWordHandler(rtfParser, "rtlgutter", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("rtlmark", new RtfCtrlWordHandler(rtfParser, "rtlmark", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null));
+		ctrlWords.put("rtlpar", new RtfCtrlWordHandler(rtfParser, "rtlpar", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("rtlrow", new RtfCtrlWordHandler(rtfParser, "rtlrow", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("rtlsect", new RtfCtrlWordHandler(rtfParser, "rtlsect", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("rxe", new RtfCtrlWordHandler(rtfParser, "rxe", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("s", new RtfCtrlWordHandler(rtfParser, "s", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("sa", new RtfCtrlWordHandler(rtfParser, "sa", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("saauto", new RtfCtrlWordHandler(rtfParser, "saauto", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("saftnnalc", new RtfCtrlWordHandler(rtfParser, "saftnnalc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("saftnnar", new RtfCtrlWordHandler(rtfParser, "saftnnar", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("saftnnauc", new RtfCtrlWordHandler(rtfParser, "saftnnauc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("saftnnchi", new RtfCtrlWordHandler(rtfParser, "saftnnchi", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("saftnnchosung", new RtfCtrlWordHandler(rtfParser, "saftnnchosung", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("saftnncnum", new RtfCtrlWordHandler(rtfParser, "saftnncnum", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("saftnndbar", new RtfCtrlWordHandler(rtfParser, "saftnndbar", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("saftnndbnum", new RtfCtrlWordHandler(rtfParser, "saftnndbnum", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("saftnndbnumd", new RtfCtrlWordHandler(rtfParser, "saftnndbnumd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("saftnndbnumk", new RtfCtrlWordHandler(rtfParser, "saftnndbnumk", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("saftnndbnumt", new RtfCtrlWordHandler(rtfParser, "saftnndbnumt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("saftnnganada", new RtfCtrlWordHandler(rtfParser, "saftnnganada", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("saftnngbnum", new RtfCtrlWordHandler(rtfParser, "saftnngbnum", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("saftnngbnumd", new RtfCtrlWordHandler(rtfParser, "saftnngbnumd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("saftnngbnumk", new RtfCtrlWordHandler(rtfParser, "saftnngbnumk", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("saftnngbnuml", new RtfCtrlWordHandler(rtfParser, "saftnngbnuml", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("saftnnrlc", new RtfCtrlWordHandler(rtfParser, "saftnnrlc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("saftnnruc", new RtfCtrlWordHandler(rtfParser, "saftnnruc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("saftnnzodiac", new RtfCtrlWordHandler(rtfParser, "saftnnzodiac", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("saftnnzodiacd", new RtfCtrlWordHandler(rtfParser, "saftnnzodiacd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("saftnnzodiacl", new RtfCtrlWordHandler(rtfParser, "saftnnzodiacl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("saftnrestart", new RtfCtrlWordHandler(rtfParser, "saftnrestart", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("saftnrstcont", new RtfCtrlWordHandler(rtfParser, "saftnrstcont", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("saftnstart", new RtfCtrlWordHandler(rtfParser, "saftnstart", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("sautoupd", new RtfCtrlWordHandler(rtfParser, "sautoupd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("saveinvalidxml", new RtfCtrlWordHandler(rtfParser, "saveinvalidxml", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("saveprevpict", new RtfCtrlWordHandler(rtfParser, "saveprevpict", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("sb", new RtfCtrlWordHandler(rtfParser, "sb", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("sbasedon", new RtfCtrlWordHandler(rtfParser, "sbasedon", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("sbauto", new RtfCtrlWordHandler(rtfParser, "sbauto", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("sbkcol", new RtfCtrlWordHandler(rtfParser, "sbkcol", RtfProperty.SBK_COLUMN, false, RtfCtrlWordType.FLAG, "\\", " ", RtfProperty.SECTION_BREAK_TYPE));
+		ctrlWords.put("sbkeven", new RtfCtrlWordHandler(rtfParser, "sbkeven", RtfProperty.SBK_EVEN, false, RtfCtrlWordType.FLAG, "\\", " ", RtfProperty.SECTION_BREAK_TYPE));
+		ctrlWords.put("sbknone", new RtfCtrlWordHandler(rtfParser, "sbknone", RtfProperty.SBK_NONE, false, RtfCtrlWordType.FLAG, "\\", " ", RtfProperty.SECTION_BREAK_TYPE));
+		ctrlWords.put("sbkodd", new RtfCtrlWordHandler(rtfParser, "sbkodd", RtfProperty.SBK_ODD, false, RtfCtrlWordType.FLAG, "\\", " ", RtfProperty.SECTION_BREAK_TYPE));
+		ctrlWords.put("sbkpage", new RtfCtrlWordHandler(rtfParser, "sbkpage", RtfProperty.SBK_PAGE, false, RtfCtrlWordType.FLAG, "\\", " ", RtfProperty.SECTION_BREAK_TYPE));
+		ctrlWords.put("sbys", new RtfCtrlWordHandler(rtfParser, "sbys", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("scaps", new RtfCtrlWordHandler(rtfParser, "scaps", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("scompose", new RtfCtrlWordHandler(rtfParser, "scompose", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("sec", new RtfCtrlWordHandler(rtfParser, "sec", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("sect", new RtfCtrlWordHandler(rtfParser, "sect", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null));
+		ctrlWords.put("sectd", new RtfCtrlWordHandler(rtfParser, "sectd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("sectdefaultcl", new RtfCtrlWordHandler(rtfParser, "sectdefaultcl", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("sectexpand", new RtfCtrlWordHandler(rtfParser, "sectexpand", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("sectlinegrid", new RtfCtrlWordHandler(rtfParser, "sectlinegrid", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("sectnum", new RtfCtrlWordHandler(rtfParser, "sectnum", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null));
+		ctrlWords.put("sectrsid", new RtfCtrlWordHandler(rtfParser, "sectrsid", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("sectspecifycl", new RtfCtrlWordHandler(rtfParser, "sectspecifycl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("sectspecifygen", new RtfCtrlWordHandler(rtfParser, "sectspecifygen", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("sectspecifyl", new RtfCtrlWordHandler(rtfParser, "sectspecifyl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("sectunlocked", new RtfCtrlWordHandler(rtfParser, "sectunlocked", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("sftnbj", new RtfCtrlWordHandler(rtfParser, "sftnbj", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("sftnnalc", new RtfCtrlWordHandler(rtfParser, "sftnnalc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("sftnnar", new RtfCtrlWordHandler(rtfParser, "sftnnar", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("sftnnauc", new RtfCtrlWordHandler(rtfParser, "sftnnauc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("sftnnchi", new RtfCtrlWordHandler(rtfParser, "sftnnchi", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("sftnnchosung", new RtfCtrlWordHandler(rtfParser, "sftnnchosung", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("sftnncnum", new RtfCtrlWordHandler(rtfParser, "sftnncnum", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("sftnndbar", new RtfCtrlWordHandler(rtfParser, "sftnndbar", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("sftnndbnum", new RtfCtrlWordHandler(rtfParser, "sftnndbnum", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("sftnndbnumd", new RtfCtrlWordHandler(rtfParser, "sftnndbnumd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("sftnndbnumk", new RtfCtrlWordHandler(rtfParser, "sftnndbnumk", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("sftnndbnumt", new RtfCtrlWordHandler(rtfParser, "sftnndbnumt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("sftnnganada", new RtfCtrlWordHandler(rtfParser, "sftnnganada", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("sftnngbnum", new RtfCtrlWordHandler(rtfParser, "sftnngbnum", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("sftnngbnumd", new RtfCtrlWordHandler(rtfParser, "sftnngbnumd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("sftnngbnumk", new RtfCtrlWordHandler(rtfParser, "sftnngbnumk", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("sftnngbnuml", new RtfCtrlWordHandler(rtfParser, "sftnngbnuml", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("sftnnrlc", new RtfCtrlWordHandler(rtfParser, "sftnnrlc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("sftnnruc", new RtfCtrlWordHandler(rtfParser, "sftnnruc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("sftnnzodiac", new RtfCtrlWordHandler(rtfParser, "sftnnzodiac", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("sftnnzodiacd", new RtfCtrlWordHandler(rtfParser, "sftnnzodiacd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("sftnnzodiacl", new RtfCtrlWordHandler(rtfParser, "sftnnzodiacl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("sftnrestart", new RtfCtrlWordHandler(rtfParser, "sftnrestart", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("sftnrstcont", new RtfCtrlWordHandler(rtfParser, "sftnrstcont", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("sftnrstpg", new RtfCtrlWordHandler(rtfParser, "sftnrstpg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("sftnstart", new RtfCtrlWordHandler(rtfParser, "sftnstart", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("sftntj", new RtfCtrlWordHandler(rtfParser, "sftntj", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("shad", new RtfCtrlWordHandler(rtfParser, "shad", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("shading", new RtfCtrlWordHandler(rtfParser, "shading", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("shidden", new RtfCtrlWordHandler(rtfParser, "shidden", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("shift", new RtfCtrlWordHandler(rtfParser, "shift", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("showplaceholdtext", new RtfCtrlWordHandler(rtfParser, "showplaceholdtext", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("showxmlerrors", new RtfCtrlWordHandler(rtfParser, "showxmlerrors", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("shp", new RtfCtrlWordHandler(rtfParser, "shp", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("shpbottom", new RtfCtrlWordHandler(rtfParser, "shpbottom", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("shpbxcolumn", new RtfCtrlWordHandler(rtfParser, "shpbxcolumn", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("shpbxignore", new RtfCtrlWordHandler(rtfParser, "shpbxignore", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("shpbxmargin", new RtfCtrlWordHandler(rtfParser, "shpbxmargin", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("shpbxpage", new RtfCtrlWordHandler(rtfParser, "shpbxpage", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("shpbyignore", new RtfCtrlWordHandler(rtfParser, "shpbyignore", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("shpbymargin", new RtfCtrlWordHandler(rtfParser, "shpbymargin", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("shpbypage", new RtfCtrlWordHandler(rtfParser, "shpbypage", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("shpbypara", new RtfCtrlWordHandler(rtfParser, "shpbypara", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("shpfblwtxt", new RtfCtrlWordHandler(rtfParser, "shpfblwtxt", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("shpfhdr", new RtfCtrlWordHandler(rtfParser, "shpfhdr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("shpgrp", new RtfCtrlWordHandler(rtfParser, "shpgrp", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("shpinst", new RtfCtrlWordHandler(rtfParser, "shpinst", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("shpleft", new RtfCtrlWordHandler(rtfParser, "shpleft", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("shplid", new RtfCtrlWordHandler(rtfParser, "shplid", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("shplockanchor", new RtfCtrlWordHandler(rtfParser, "shplockanchor", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("shppict", new RtfCtrlWordHandler(rtfParser, "shppict", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationShppict" ));//"RtfDestinationShppict"));
+		ctrlWords.put("shpright", new RtfCtrlWordHandler(rtfParser, "shpright", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("shprslt", new RtfCtrlWordHandler(rtfParser, "shprslt", 0, true, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationNull"));
+		ctrlWords.put("shptop", new RtfCtrlWordHandler(rtfParser, "shptop", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("shptxt", new RtfCtrlWordHandler(rtfParser, "shptxt", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("shpwr", new RtfCtrlWordHandler(rtfParser, "shpwr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("shpwrk", new RtfCtrlWordHandler(rtfParser, "shpwrk", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("shpz", new RtfCtrlWordHandler(rtfParser, "shpz", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("sl", new RtfCtrlWordHandler(rtfParser, "sl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("slink", new RtfCtrlWordHandler(rtfParser, "slink", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("slmult", new RtfCtrlWordHandler(rtfParser, "slmult", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("slocked", new RtfCtrlWordHandler(rtfParser, "slocked", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("sn", new RtfCtrlWordHandler(rtfParser, "sn", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("snapgridtocell", new RtfCtrlWordHandler(rtfParser, "snapgridtocell", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("snaptogridincell", new RtfCtrlWordHandler(rtfParser, "snaptogridincell", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("snext", new RtfCtrlWordHandler(rtfParser, "snext", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("softcol", new RtfCtrlWordHandler(rtfParser, "softcol", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("softlheight", new RtfCtrlWordHandler(rtfParser, "softlheight", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("softline", new RtfCtrlWordHandler(rtfParser, "softline", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("softpage", new RtfCtrlWordHandler(rtfParser, "softpage", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("sp", new RtfCtrlWordHandler(rtfParser, "sp", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("spersonal", new RtfCtrlWordHandler(rtfParser, "spersonal", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("spltpgpar", new RtfCtrlWordHandler(rtfParser, "spltpgpar", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("splytwnine", new RtfCtrlWordHandler(rtfParser, "splytwnine", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("spp", new RtfCtrlWordHandler(rtfParser, "spp", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("spriority", new RtfCtrlWordHandler(rtfParser, "spriority", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("sprsbsp", new RtfCtrlWordHandler(rtfParser, "sprsbsp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("sprslnsp", new RtfCtrlWordHandler(rtfParser, "sprslnsp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("sprsspbf", new RtfCtrlWordHandler(rtfParser, "sprsspbf", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("sprstsm", new RtfCtrlWordHandler(rtfParser, "sprstsm", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("sprstsp", new RtfCtrlWordHandler(rtfParser, "sprstsp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("spv", new RtfCtrlWordHandler(rtfParser, "spv", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("sqformat", new RtfCtrlWordHandler(rtfParser, "sqformat", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("sreply", new RtfCtrlWordHandler(rtfParser, "sreply", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("ssemihidden", new RtfCtrlWordHandler(rtfParser, "ssemihidden", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("staticval", new RtfCtrlWordHandler(rtfParser, "staticval", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("stextflow", new RtfCtrlWordHandler(rtfParser, "stextflow", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("strike", new RtfCtrlWordHandler(rtfParser, "strike", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("striked1", new RtfCtrlWordHandler(rtfParser, "striked1", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("stshfbi", new RtfCtrlWordHandler(rtfParser, "stshfbi", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("stshfdbch", new RtfCtrlWordHandler(rtfParser, "stshfdbch", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("stshfhich", new RtfCtrlWordHandler(rtfParser, "stshfhich", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("stshfloch", new RtfCtrlWordHandler(rtfParser, "stshfloch", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("stylelock", new RtfCtrlWordHandler(rtfParser, "stylelock", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("stylelockbackcomp", new RtfCtrlWordHandler(rtfParser, "stylelockbackcomp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("stylelockenforced", new RtfCtrlWordHandler(rtfParser, "stylelockenforced", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("stylelockqfset", new RtfCtrlWordHandler(rtfParser, "stylelockqfset", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("stylelocktheme", new RtfCtrlWordHandler(rtfParser, "stylelocktheme", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("stylesheet", new RtfCtrlWordHandler(rtfParser, "stylesheet", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationStylesheetTable"));
+		ctrlWords.put("stylesortmethod", new RtfCtrlWordHandler(rtfParser, "stylesortmethod", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("styrsid", new RtfCtrlWordHandler(rtfParser, "styrsid", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("sub", new RtfCtrlWordHandler(rtfParser, "sub", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("subdocument", new RtfCtrlWordHandler(rtfParser, "subdocument", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("subfontbysize", new RtfCtrlWordHandler(rtfParser, "subfontbysize", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("subject", new RtfCtrlWordHandler(rtfParser, "subject", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationInfo"));
+		ctrlWords.put("sunhideused", new RtfCtrlWordHandler(rtfParser, "sunhideused", 0, true, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("super", new RtfCtrlWordHandler(rtfParser, "super", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("sv", new RtfCtrlWordHandler(rtfParser, "sv", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("svb", new RtfCtrlWordHandler(rtfParser, "svb", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("swpbdr", new RtfCtrlWordHandler(rtfParser, "swpbdr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tab", new RtfCtrlWordHandler(rtfParser, "tab", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null));
+		ctrlWords.put("tabsnoovrlp", new RtfCtrlWordHandler(rtfParser, "tabsnoovrlp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("taprtl", new RtfCtrlWordHandler(rtfParser, "taprtl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tb", new RtfCtrlWordHandler(rtfParser, "tb", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("tblind", new RtfCtrlWordHandler(rtfParser, "tblind", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("tblindtype", new RtfCtrlWordHandler(rtfParser, "tblindtype", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("tbllkbestfit", new RtfCtrlWordHandler(rtfParser, "tbllkbestfit", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tbllkborder", new RtfCtrlWordHandler(rtfParser, "tbllkborder", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tbllkcolor", new RtfCtrlWordHandler(rtfParser, "tbllkcolor", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tbllkfont", new RtfCtrlWordHandler(rtfParser, "tbllkfont", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tbllkhdrcols", new RtfCtrlWordHandler(rtfParser, "tbllkhdrcols", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tbllkhdrrows", new RtfCtrlWordHandler(rtfParser, "tbllkhdrrows", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tbllklastcol", new RtfCtrlWordHandler(rtfParser, "tbllklastcol", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tbllklastrow", new RtfCtrlWordHandler(rtfParser, "tbllklastrow", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tbllknocolband", new RtfCtrlWordHandler(rtfParser, "tbllknocolband", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tbllknorowband", new RtfCtrlWordHandler(rtfParser, "tbllknorowband", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tbllkshading", new RtfCtrlWordHandler(rtfParser, "tbllkshading", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tblrsid", new RtfCtrlWordHandler(rtfParser, "tblrsid", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("tc", new RtfCtrlWordHandler(rtfParser, "tc", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("tcelld", new RtfCtrlWordHandler(rtfParser, "tcelld", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tcf", new RtfCtrlWordHandler(rtfParser, "tcf", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("tcl", new RtfCtrlWordHandler(rtfParser, "tcl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("tcn", new RtfCtrlWordHandler(rtfParser, "tcn", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tdfrmtxtBottom", new RtfCtrlWordHandler(rtfParser, "tdfrmtxtBottom", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("tdfrmtxtLeft", new RtfCtrlWordHandler(rtfParser, "tdfrmtxtLeft", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("tdfrmtxtRight", new RtfCtrlWordHandler(rtfParser, "tdfrmtxtRight", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("tdfrmtxtTop", new RtfCtrlWordHandler(rtfParser, "tdfrmtxtTop", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("template", new RtfCtrlWordHandler(rtfParser, "template", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("themedata", new RtfCtrlWordHandler(rtfParser, "themedata", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("themelang", new RtfCtrlWordHandler(rtfParser, "themelang", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("themelangcs", new RtfCtrlWordHandler(rtfParser, "themelangcs", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("themelangfe", new RtfCtrlWordHandler(rtfParser, "themelangfe", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("time", new RtfCtrlWordHandler(rtfParser, "time", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("title", new RtfCtrlWordHandler(rtfParser, "title", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationInfo"));
+		ctrlWords.put("titlepg", new RtfCtrlWordHandler(rtfParser, "titlepg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tldot", new RtfCtrlWordHandler(rtfParser, "tldot", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tleq", new RtfCtrlWordHandler(rtfParser, "tleq", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tlhyph", new RtfCtrlWordHandler(rtfParser, "tlhyph", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tlmdot", new RtfCtrlWordHandler(rtfParser, "tlmdot", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tlth", new RtfCtrlWordHandler(rtfParser, "tlth", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tlul", new RtfCtrlWordHandler(rtfParser, "tlul", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("toplinepunct", new RtfCtrlWordHandler(rtfParser, "toplinepunct", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tphcol", new RtfCtrlWordHandler(rtfParser, "tphcol", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tphmrg", new RtfCtrlWordHandler(rtfParser, "tphmrg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tphpg", new RtfCtrlWordHandler(rtfParser, "tphpg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tposnegx", new RtfCtrlWordHandler(rtfParser, "tposnegx", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("tposnegy", new RtfCtrlWordHandler(rtfParser, "tposnegy", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("tposx", new RtfCtrlWordHandler(rtfParser, "tposx", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("tposxc", new RtfCtrlWordHandler(rtfParser, "tposxc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tposxi", new RtfCtrlWordHandler(rtfParser, "tposxi", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tposxl", new RtfCtrlWordHandler(rtfParser, "tposxl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tposxo", new RtfCtrlWordHandler(rtfParser, "tposxo", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tposxr", new RtfCtrlWordHandler(rtfParser, "tposxr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tposy", new RtfCtrlWordHandler(rtfParser, "tposy", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tposyb", new RtfCtrlWordHandler(rtfParser, "tposyb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tposyc", new RtfCtrlWordHandler(rtfParser, "tposyc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tposyil", new RtfCtrlWordHandler(rtfParser, "tposyil", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tposyin", new RtfCtrlWordHandler(rtfParser, "tposyin", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tposyout", new RtfCtrlWordHandler(rtfParser, "tposyout", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tposyoutv", new RtfCtrlWordHandler(rtfParser, "tposyoutv", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tposyt", new RtfCtrlWordHandler(rtfParser, "tposyt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tpvmrg", new RtfCtrlWordHandler(rtfParser, "tpvmrg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tpvpara", new RtfCtrlWordHandler(rtfParser, "tpvpara", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tpvpg", new RtfCtrlWordHandler(rtfParser, "tpvpg", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tqc", new RtfCtrlWordHandler(rtfParser, "tqc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tqdec", new RtfCtrlWordHandler(rtfParser, "tqdec", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tqr", new RtfCtrlWordHandler(rtfParser, "tqr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("trackformatting", new RtfCtrlWordHandler(rtfParser, "trackformatting", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("trackmoves", new RtfCtrlWordHandler(rtfParser, "trackmoves", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("transmf", new RtfCtrlWordHandler(rtfParser, "transmf", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("trauth", new RtfCtrlWordHandler(rtfParser, "trauth", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("trautofit", new RtfCtrlWordHandler(rtfParser, "trautofit", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("trbgbdiag", new RtfCtrlWordHandler(rtfParser, "trbgbdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("trbgcross", new RtfCtrlWordHandler(rtfParser, "trbgcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("trbgdcross", new RtfCtrlWordHandler(rtfParser, "trbgdcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("trbgdkbdiag", new RtfCtrlWordHandler(rtfParser, "trbgdkbdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("trbgdkcross", new RtfCtrlWordHandler(rtfParser, "trbgdkcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("trbgdkdcross", new RtfCtrlWordHandler(rtfParser, "trbgdkdcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("trbgdkfdiag", new RtfCtrlWordHandler(rtfParser, "trbgdkfdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("trbgdkhor", new RtfCtrlWordHandler(rtfParser, "trbgdkhor", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("trbgdkvert", new RtfCtrlWordHandler(rtfParser, "trbgdkvert", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("trbgfdiag", new RtfCtrlWordHandler(rtfParser, "trbgfdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("trbghoriz", new RtfCtrlWordHandler(rtfParser, "trbghoriz", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("trbgvert", new RtfCtrlWordHandler(rtfParser, "trbgvert", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("trbrdrb", new RtfCtrlWordHandler(rtfParser, "trbrdrb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("trbrdrh", new RtfCtrlWordHandler(rtfParser, "trbrdrh", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("trbrdrl", new RtfCtrlWordHandler(rtfParser, "trbrdrl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("trbrdrr", new RtfCtrlWordHandler(rtfParser, "trbrdrr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("trbrdrt", new RtfCtrlWordHandler(rtfParser, "trbrdrt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("trbrdrv", new RtfCtrlWordHandler(rtfParser, "trbrdrv", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("trcbpat", new RtfCtrlWordHandler(rtfParser, "trcbpat", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("trcfpat", new RtfCtrlWordHandler(rtfParser, "trcfpat", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("trdate", new RtfCtrlWordHandler(rtfParser, "trdate", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("trftsWidth", new RtfCtrlWordHandler(rtfParser, "trftsWidth", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("trftsWidthA", new RtfCtrlWordHandler(rtfParser, "trftsWidthA", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("trftsWidthB", new RtfCtrlWordHandler(rtfParser, "trftsWidthB", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("trgaph", new RtfCtrlWordHandler(rtfParser, "trgaph", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("trhdr", new RtfCtrlWordHandler(rtfParser, "trhdr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("trkeep", new RtfCtrlWordHandler(rtfParser, "trkeep", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("trkeepfollow", new RtfCtrlWordHandler(rtfParser, "trkeepfollow", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("trleft", new RtfCtrlWordHandler(rtfParser, "trleft", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("trowd", new RtfCtrlWordHandler(rtfParser, "trowd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("trpaddb", new RtfCtrlWordHandler(rtfParser, "trpaddb", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("trpaddfb", new RtfCtrlWordHandler(rtfParser, "trpaddfb", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("trpaddfl", new RtfCtrlWordHandler(rtfParser, "trpaddfl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("trpaddfr", new RtfCtrlWordHandler(rtfParser, "trpaddfr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("trpaddft", new RtfCtrlWordHandler(rtfParser, "trpaddft", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("trpaddl", new RtfCtrlWordHandler(rtfParser, "trpaddl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("trpaddr", new RtfCtrlWordHandler(rtfParser, "trpaddr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("trpaddt", new RtfCtrlWordHandler(rtfParser, "trpaddt", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("trpat", new RtfCtrlWordHandler(rtfParser, "trpat", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("trqc", new RtfCtrlWordHandler(rtfParser, "trqc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("trql", new RtfCtrlWordHandler(rtfParser, "trql", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("trqr", new RtfCtrlWordHandler(rtfParser, "trqr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("trrh", new RtfCtrlWordHandler(rtfParser, "trrh", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("trshdng", new RtfCtrlWordHandler(rtfParser, "trshdng", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("trspdb", new RtfCtrlWordHandler(rtfParser, "trspdb", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("trspdfb", new RtfCtrlWordHandler(rtfParser, "trspdfb", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("trspdfl", new RtfCtrlWordHandler(rtfParser, "trspdfl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("trspdfr", new RtfCtrlWordHandler(rtfParser, "trspdfr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("trspdft", new RtfCtrlWordHandler(rtfParser, "trspdft", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("trspdl", new RtfCtrlWordHandler(rtfParser, "trspdl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("trspdr", new RtfCtrlWordHandler(rtfParser, "trspdr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("trspdt", new RtfCtrlWordHandler(rtfParser, "trspdt", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("truncatefontheight", new RtfCtrlWordHandler(rtfParser, "truncatefontheight", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("truncex", new RtfCtrlWordHandler(rtfParser, "truncex", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("trwWidth", new RtfCtrlWordHandler(rtfParser, "trwWidth", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("trwWidthA", new RtfCtrlWordHandler(rtfParser, "trwWidthA", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("trwWidthB", new RtfCtrlWordHandler(rtfParser, "trwWidthB", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("ts", new RtfCtrlWordHandler(rtfParser, "ts", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("tsbgbdiag", new RtfCtrlWordHandler(rtfParser, "tsbgbdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tsbgcross", new RtfCtrlWordHandler(rtfParser, "tsbgcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tsbgdcross", new RtfCtrlWordHandler(rtfParser, "tsbgdcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tsbgdkbdiag", new RtfCtrlWordHandler(rtfParser, "tsbgdkbdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tsbgdkcross", new RtfCtrlWordHandler(rtfParser, "tsbgdkcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tsbgdkdcross", new RtfCtrlWordHandler(rtfParser, "tsbgdkdcross", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tsbgdkfdiag", new RtfCtrlWordHandler(rtfParser, "tsbgdkfdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tsbgdkhor", new RtfCtrlWordHandler(rtfParser, "tsbgdkhor", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tsbgdkvert", new RtfCtrlWordHandler(rtfParser, "tsbgdkvert", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tsbgfdiag", new RtfCtrlWordHandler(rtfParser, "tsbgfdiag", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tsbghoriz", new RtfCtrlWordHandler(rtfParser, "tsbghoriz", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tsbgvert", new RtfCtrlWordHandler(rtfParser, "tsbgvert", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tsbrdrb", new RtfCtrlWordHandler(rtfParser, "tsbrdrb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tsbrdrdgl", new RtfCtrlWordHandler(rtfParser, "tsbrdrdgl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tsbrdrdgr", new RtfCtrlWordHandler(rtfParser, "tsbrdrdgr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tsbrdrh", new RtfCtrlWordHandler(rtfParser, "tsbrdrh", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tsbrdrl", new RtfCtrlWordHandler(rtfParser, "tsbrdrl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tsbrdrr", new RtfCtrlWordHandler(rtfParser, "tsbrdrr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tsbrdrt", new RtfCtrlWordHandler(rtfParser, "tsbrdrt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tsbrdrv", new RtfCtrlWordHandler(rtfParser, "tsbrdrv", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tscbandhorzeven", new RtfCtrlWordHandler(rtfParser, "tscbandhorzeven", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tscbandhorzodd", new RtfCtrlWordHandler(rtfParser, "tscbandhorzodd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tscbandsh", new RtfCtrlWordHandler(rtfParser, "tscbandsh", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("tscbandsv", new RtfCtrlWordHandler(rtfParser, "tscbandsv", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("tscbandverteven", new RtfCtrlWordHandler(rtfParser, "tscbandverteven", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tscbandvertodd", new RtfCtrlWordHandler(rtfParser, "tscbandvertodd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tscellcbpat", new RtfCtrlWordHandler(rtfParser, "tscellcbpat", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("tscellcfpat", new RtfCtrlWordHandler(rtfParser, "tscellcfpat", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("tscellpaddb", new RtfCtrlWordHandler(rtfParser, "tscellpaddb", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("tscellpaddfb", new RtfCtrlWordHandler(rtfParser, "tscellpaddfb", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("tscellpaddfl", new RtfCtrlWordHandler(rtfParser, "tscellpaddfl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("tscellpaddfr", new RtfCtrlWordHandler(rtfParser, "tscellpaddfr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("tscellpaddft", new RtfCtrlWordHandler(rtfParser, "tscellpaddft", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("tscellpaddl", new RtfCtrlWordHandler(rtfParser, "tscellpaddl", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("tscellpaddr", new RtfCtrlWordHandler(rtfParser, "tscellpaddr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("tscellpaddt", new RtfCtrlWordHandler(rtfParser, "tscellpaddt", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("tscellpct", new RtfCtrlWordHandler(rtfParser, "tscellpct", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("tscellwidth", new RtfCtrlWordHandler(rtfParser, "tscellwidth", 0, true, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tscellwidthfts", new RtfCtrlWordHandler(rtfParser, "tscellwidthfts", 0, true, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tscfirstcol", new RtfCtrlWordHandler(rtfParser, "tscfirstcol", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tscfirstrow", new RtfCtrlWordHandler(rtfParser, "tscfirstrow", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tsclastcol", new RtfCtrlWordHandler(rtfParser, "tsclastcol", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tsclastrow", new RtfCtrlWordHandler(rtfParser, "tsclastrow", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tscnecell", new RtfCtrlWordHandler(rtfParser, "tscnecell", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tscnwcell", new RtfCtrlWordHandler(rtfParser, "tscnwcell", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tscsecell", new RtfCtrlWordHandler(rtfParser, "tscsecell", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tscswcell", new RtfCtrlWordHandler(rtfParser, "tscswcell", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tsd", new RtfCtrlWordHandler(rtfParser, "tsd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tsnowrap", new RtfCtrlWordHandler(rtfParser, "tsnowrap", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tsrowd", new RtfCtrlWordHandler(rtfParser, "tsrowd", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tsvertalb", new RtfCtrlWordHandler(rtfParser, "tsvertalb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tsvertalc", new RtfCtrlWordHandler(rtfParser, "tsvertalc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tsvertalt", new RtfCtrlWordHandler(rtfParser, "tsvertalt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("twoonone", new RtfCtrlWordHandler(rtfParser, "twoonone", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("tx", new RtfCtrlWordHandler(rtfParser, "tx", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("txbxtwalways", new RtfCtrlWordHandler(rtfParser, "txbxtwalways", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("txbxtwfirst", new RtfCtrlWordHandler(rtfParser, "txbxtwfirst", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("txbxtwfirstlast", new RtfCtrlWordHandler(rtfParser, "txbxtwfirstlast", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("txbxtwlast", new RtfCtrlWordHandler(rtfParser, "txbxtwlast", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("txbxtwno", new RtfCtrlWordHandler(rtfParser, "txbxtwno", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("txe", new RtfCtrlWordHandler(rtfParser, "txe", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("u", new RtfCtrlWordHandler(rtfParser, "u", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("uc", new RtfCtrlWordHandler(rtfParser, "uc", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("ud", new RtfCtrlWordHandler(rtfParser, "ud", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("ul", new RtfCtrlWordHandler(rtfParser, "ul", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("ulc", new RtfCtrlWordHandler(rtfParser, "ulc", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("uld", new RtfCtrlWordHandler(rtfParser, "uld", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("uldash", new RtfCtrlWordHandler(rtfParser, "uldash", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("uldashd", new RtfCtrlWordHandler(rtfParser, "uldashd", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("uldashdd", new RtfCtrlWordHandler(rtfParser, "uldashdd", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("uldb", new RtfCtrlWordHandler(rtfParser, "uldb", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("ulhair", new RtfCtrlWordHandler(rtfParser, "ulhair", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("ulhwave", new RtfCtrlWordHandler(rtfParser, "ulhwave", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("ulldash", new RtfCtrlWordHandler(rtfParser, "ulldash", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("ulnone", new RtfCtrlWordHandler(rtfParser, "ulnone", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("ulth", new RtfCtrlWordHandler(rtfParser, "ulth", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("ulthd", new RtfCtrlWordHandler(rtfParser, "ulthd", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("ulthdash", new RtfCtrlWordHandler(rtfParser, "ulthdash", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("ulthdashd", new RtfCtrlWordHandler(rtfParser, "ulthdashd", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("ulthdashdd", new RtfCtrlWordHandler(rtfParser, "ulthdashdd", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("ulthldash", new RtfCtrlWordHandler(rtfParser, "ulthldash", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("ululdbwave", new RtfCtrlWordHandler(rtfParser, "ululdbwave", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("ulw", new RtfCtrlWordHandler(rtfParser, "ulw", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("ulwave", new RtfCtrlWordHandler(rtfParser, "ulwave", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("up", new RtfCtrlWordHandler(rtfParser, "up", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("upr", new RtfCtrlWordHandler(rtfParser, "upr", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("urtf", new RtfCtrlWordHandler(rtfParser, "urtf", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("useltbaln", new RtfCtrlWordHandler(rtfParser, "useltbaln", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("usenormstyforlist", new RtfCtrlWordHandler(rtfParser, "usenormstyforlist", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("userprops", new RtfCtrlWordHandler(rtfParser, "userprops", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", null));
+		ctrlWords.put("usexform", new RtfCtrlWordHandler(rtfParser, "usexform", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("utinl", new RtfCtrlWordHandler(rtfParser, "utinl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("v", new RtfCtrlWordHandler(rtfParser, "v", 0, false, RtfCtrlWordType.TOGGLE, "\\", " ", null));
+		ctrlWords.put("validatexml", new RtfCtrlWordHandler(rtfParser, "validatexml", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("vern", new RtfCtrlWordHandler(rtfParser, "vern", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("version", new RtfCtrlWordHandler(rtfParser, "version", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("vertalb", new RtfCtrlWordHandler(rtfParser, "vertalb", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("vertalc", new RtfCtrlWordHandler(rtfParser, "vertalc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("vertalj", new RtfCtrlWordHandler(rtfParser, "vertalj", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("vertalt", new RtfCtrlWordHandler(rtfParser, "vertalt", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("vertdoc", new RtfCtrlWordHandler(rtfParser, "vertdoc", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("vertsect", new RtfCtrlWordHandler(rtfParser, "vertsect", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("viewbksp", new RtfCtrlWordHandler(rtfParser, "viewbksp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("viewkind", new RtfCtrlWordHandler(rtfParser, "viewkind", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("viewnobound", new RtfCtrlWordHandler(rtfParser, "viewnobound", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("viewscale", new RtfCtrlWordHandler(rtfParser, "viewscale", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("viewzk", new RtfCtrlWordHandler(rtfParser, "viewzk", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("wbitmap", new RtfCtrlWordHandler(rtfParser, "wbitmap", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("wbmbitspixel", new RtfCtrlWordHandler(rtfParser, "wbmbitspixel", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("wbmplanes", new RtfCtrlWordHandler(rtfParser, "wbmplanes", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("wbmwidthbytes", new RtfCtrlWordHandler(rtfParser, "wbmwidthbytes", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("webhidden", new RtfCtrlWordHandler(rtfParser, "webhidden", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("wgrffmtfilter", new RtfCtrlWordHandler(rtfParser, "wgrffmtfilter", 0, false, RtfCtrlWordType.VALUE, "\\*\\", " ", null));
+		ctrlWords.put("widctlpar", new RtfCtrlWordHandler(rtfParser, "widctlpar", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("widowctrl", new RtfCtrlWordHandler(rtfParser, "widowctrl", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("windowcaption", new RtfCtrlWordHandler(rtfParser, "windowcaption", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("wmetafile", new RtfCtrlWordHandler(rtfParser, "wmetafile", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("wpeqn", new RtfCtrlWordHandler(rtfParser, "wpeqn", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("wpjst", new RtfCtrlWordHandler(rtfParser, "wpjst", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("wpsp", new RtfCtrlWordHandler(rtfParser, "wpsp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("wptab", new RtfCtrlWordHandler(rtfParser, "wptab", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("wraparound", new RtfCtrlWordHandler(rtfParser, "wraparound", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("wrapdefault", new RtfCtrlWordHandler(rtfParser, "wrapdefault", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("wrapthrough", new RtfCtrlWordHandler(rtfParser, "wrapthrough", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("wraptight", new RtfCtrlWordHandler(rtfParser, "wraptight", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("wraptrsp", new RtfCtrlWordHandler(rtfParser, "wraptrsp", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("writereservhash", new RtfCtrlWordHandler(rtfParser, "writereservhash", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", null));
+		ctrlWords.put("wrppunct", new RtfCtrlWordHandler(rtfParser, "wrppunct", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("xe", new RtfCtrlWordHandler(rtfParser, "xe", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("xef", new RtfCtrlWordHandler(rtfParser, "xef", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("xform", new RtfCtrlWordHandler(rtfParser, "xform", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("xmlattr", new RtfCtrlWordHandler(rtfParser, "xmlattr", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("xmlattrname", new RtfCtrlWordHandler(rtfParser, "xmlattrname", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("xmlattrns", new RtfCtrlWordHandler(rtfParser, "xmlattrns", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("xmlattrvalue", new RtfCtrlWordHandler(rtfParser, "xmlattrvalue", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("xmlclose", new RtfCtrlWordHandler(rtfParser, "xmlclose", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("xmlname", new RtfCtrlWordHandler(rtfParser, "xmlname", 0, false, RtfCtrlWordType.DESTINATION, "\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("xmlns", new RtfCtrlWordHandler(rtfParser, "xmlns", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("xmlnstbl", new RtfCtrlWordHandler(rtfParser, "xmlnstbl", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("xmlopen", new RtfCtrlWordHandler(rtfParser, "xmlopen", 0, false, RtfCtrlWordType.DESTINATION_EX, "\\*\\", " ", "RtfDestinationDocument"));
+		ctrlWords.put("xmlsdttcell", new RtfCtrlWordHandler(rtfParser, "xmlsdttcell", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("xmlsdttpara", new RtfCtrlWordHandler(rtfParser, "xmlsdttpara", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("xmlsdttregular", new RtfCtrlWordHandler(rtfParser, "xmlsdttregular", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("xmlsdttrow", new RtfCtrlWordHandler(rtfParser, "xmlsdttrow", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("xmlsdttunknown", new RtfCtrlWordHandler(rtfParser, "xmlsdttunknown", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("yr", new RtfCtrlWordHandler(rtfParser, "yr", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("yts", new RtfCtrlWordHandler(rtfParser, "yts", 0, true, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("yxe", new RtfCtrlWordHandler(rtfParser, "yxe", 0, false, RtfCtrlWordType.FLAG, "\\", " ", null));
+		ctrlWords.put("zwbo", new RtfCtrlWordHandler(rtfParser, "zwbo", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null));
+		ctrlWords.put("zwj", new RtfCtrlWordHandler(rtfParser, "zwj", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null));
+		ctrlWords.put("zwnbo", new RtfCtrlWordHandler(rtfParser, "zwnbo", 0, false, RtfCtrlWordType.SYMBOL, "\\", " ", null));
+		ctrlWords.put("zwnj", new RtfCtrlWordHandler(rtfParser, "zwnj", 0, false, RtfCtrlWordType.VALUE, "\\", " ", null));
+		ctrlWords.put("{", new RtfCtrlWordHandler(rtfParser, "{", 0, false, RtfCtrlWordType.SYMBOL, "\\", "", "{"));
+		ctrlWords.put("|", new RtfCtrlWordHandler(rtfParser, "|", 0, false, RtfCtrlWordType.SYMBOL, "\\", "", "|"));
+		ctrlWords.put("}", new RtfCtrlWordHandler(rtfParser, "}", 0, false, RtfCtrlWordType.SYMBOL, "\\", "", "}"));
+		ctrlWords.put("~", new RtfCtrlWordHandler(rtfParser, "~", 0, false, RtfCtrlWordType.SYMBOL, "\\", "", "~"));
+		ctrlWords.put("unknown", new RtfCtrlWordHandler(rtfParser, "unknown", 0,false, RtfCtrlWordType.UNIDENTIFIED, "\\", " ", null));
+	}
+}
Index: src/core/com/lowagie/text/rtf/style/RtfColor.java
===================================================================
--- src/core/com/lowagie/text/rtf/style/RtfColor.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/style/RtfColor.java	(revision 0)
@@ -0,0 +1,295 @@
+/*
+ * $Id: RtfColor.java 3580 2008-08-06 15:52:00Z howard_s $
+ *
+ * Copyright 2001, 2002, 2003, 2004 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.rtf.style;
+
+import java.awt.Color;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import com.lowagie.text.DocWriter;
+import com.lowagie.text.rtf.RtfElement;
+import com.lowagie.text.rtf.RtfExtendedElement;
+import com.lowagie.text.rtf.document.RtfDocument;
+
+
+/**
+ * The RtfColor stores one rtf color value for a rtf document
+ * 
+ * @version $Id: RtfColor.java 3580 2008-08-06 15:52:00Z howard_s $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Thomas Bickel (tmb99@inode.at)
+ */
+public class RtfColor extends RtfElement implements RtfExtendedElement {
+
+    /**
+     * Constant for RED value
+     */
+    private static final byte[] COLOR_RED = DocWriter.getISOBytes("\\red");
+    /**
+     * Constant for GREEN value
+     */
+    private static final byte[] COLOR_GREEN = DocWriter.getISOBytes("\\green");
+    /**
+     * Constant for BLUE value
+     */
+    private static final byte[] COLOR_BLUE = DocWriter.getISOBytes("\\blue");
+    /**
+     * Constant for the end of one color entry
+     */
+    private static final byte COLON = (byte) ';';
+    /**
+     * Constant for the number of the color in the list of colors
+     */
+    private static final byte[] COLOR_NUMBER = DocWriter.getISOBytes("\\cf");
+
+    /**
+     * The number of the color in the list of colors
+     */
+    private int colorNumber = 0;
+    /**
+     * The red value
+     */
+    private int red = 0;
+    /**
+     * The green value
+     */
+    private int green = 0;
+    /**
+     * The blue value
+     */
+    private int blue = 0;
+    
+    /**
+     * Constructor only for use when initializing the RtfColorList
+     * 
+     * @param doc The RtfDocument this RtfColor belongs to
+     * @param red The red value to use
+     * @param green The green value to use
+     * @param blue The blue value to use
+     * @param colorNumber The number of the color in the color list
+     */
+    protected RtfColor(RtfDocument doc, int red, int green, int blue, int colorNumber) {
+        super(doc);
+        this.red = red;
+        this.blue = blue;
+        this.green = green;
+        this.colorNumber = colorNumber;
+    }
+    
+    /**
+     * Constructs a RtfColor as a clone of an existing RtfColor
+     * 
+     * @param doc The RtfDocument this RtfColor belongs to
+     * @param col The RtfColor to use as a base
+     */
+    public RtfColor(RtfDocument doc, RtfColor col) {
+        super(doc);
+        if(col != null) {
+            this.red = col.getRed();
+            this.green = col.getGreen();
+            this.blue = col.getBlue();
+        }
+        if(this.document != null) {
+            this.colorNumber = this.document.getDocumentHeader().getColorNumber(this);
+        }
+    }
+    
+    /**
+     * Constructs a RtfColor based on the Color
+     * 
+     * @param doc The RtfDocument this RtfColor belongs to
+     * @param col The Color to base this RtfColor on
+     */
+    public RtfColor(RtfDocument doc, Color col) {
+        super(doc);
+        if(col != null) {
+            this.red = col.getRed();
+            this.blue = col.getBlue();
+            this.green = col.getGreen();
+        }
+        if(this.document != null) {
+            this.colorNumber = this.document.getDocumentHeader().getColorNumber(this);
+        }
+    }
+    
+    /**
+     * Constructs a RtfColor based on the red/green/blue values
+     * 
+     * @param doc The RtfDocument this RtfColor belongs to
+     * @param red The red value to use
+     * @param green The green value to use
+     * @param blue The blue value to use
+     */
+    public RtfColor(RtfDocument doc, int red, int green, int blue) {
+        super(doc);
+        this.red = red;
+        this.blue = blue;
+        this.green = green;
+        if(this.document != null) {
+            this.colorNumber = this.document.getDocumentHeader().getColorNumber(this);
+        }
+    }
+
+    /**
+     * unused
+     */
+    public void writeContent(final OutputStream out) throws IOException
+    {    	
+    }
+    
+    /**
+     * Write the definition part of this RtfColor.
+     */
+    public void writeDefinition(final OutputStream result) throws IOException
+    {
+        result.write(COLOR_RED);
+        result.write(intToByteArray(red));
+        result.write(COLOR_GREEN);
+        result.write(intToByteArray(green));
+        result.write(COLOR_BLUE);
+        result.write(intToByteArray(blue));
+        result.write(COLON);    	
+    }
+
+    /**
+     * Writes the beginning of this RtfColor
+     * 
+     */
+    public void writeBegin(final OutputStream result) {
+        try {
+            result.write(COLOR_NUMBER);
+            result.write(intToByteArray(colorNumber));
+        } catch(IOException ioe) {
+            ioe.printStackTrace();
+        }
+    }
+    
+    /**
+     * Unused
+     * 
+     * @param result The <code>OutputStream</code> to which nothing will be written
+     */
+    public void writeEnd(final OutputStream result) {
+    }
+    
+    /**
+     * Tests if this RtfColor is equal to another RtfColor.
+     * 
+     * @param obj another RtfColor
+     * @return <code>True</code> if red, green and blue values of the two colors match,
+     *   <code>false</code> otherwise.
+     */
+    public boolean equals(Object obj) {
+        if(!(obj instanceof RtfColor)) {
+            return false;
+        }
+        RtfColor color = (RtfColor) obj;
+        return (this.red == color.getRed() && this.green == color.getGreen() && this.blue == color.getBlue());
+    }
+
+    /**
+     * Returns the hash code of this RtfColor. The hash code is
+     * an integer with the lowest three bytes containing the values
+     * of red, green and blue.
+     * 
+     * @return The hash code of this RtfColor
+     */
+    public int hashCode() {
+        return (this.red << 16) | (this.green << 8) | this.blue;
+    }
+    
+    /**
+     * Get the blue value of this RtfColor
+     * 
+     * @return The blue value
+     */
+    public int getBlue() {
+        return blue;
+    }
+
+    /**
+     * Get the green value of this RtfColor
+     * 
+     * @return The green value
+     */
+    public int getGreen() {
+        return green;
+    }
+
+    /**
+     * Get the red value of this RtfColor
+     * 
+     * @return The red value
+     */
+    public int getRed() {
+        return red;
+    }
+    
+    /**
+     * Gets the number of this RtfColor in the list of colors
+     * 
+     * @return Returns the colorNumber.
+     */
+    public int getColorNumber() {
+        return colorNumber;
+    }
+
+    /**
+     * Sets the RtfDocument this RtfColor belongs to
+     * 
+     * @param doc The RtfDocument to use
+     */
+    public void setRtfDocument(RtfDocument doc) {
+        super.setRtfDocument(doc);
+        if(document != null) {
+            this.colorNumber = document.getDocumentHeader().getColorNumber(this);
+        }
+    }
+}
Index: src/core/com/lowagie/text/rtf/text/RtfPhrase.java
===================================================================
--- src/core/com/lowagie/text/rtf/text/RtfPhrase.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/text/RtfPhrase.java	(revision 0)
@@ -0,0 +1,206 @@
+/*
+ * $Id: RtfPhrase.java 3580 2008-08-06 15:52:00Z howard_s $
+ *
+ * Copyright 2001, 2002, 2003, 2004 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.rtf.text;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+
+import com.lowagie.text.Chunk;
+import com.lowagie.text.DocWriter;
+import com.lowagie.text.DocumentException;
+import com.lowagie.text.Element;
+import com.lowagie.text.Phrase;
+import com.lowagie.text.rtf.RtfBasicElement;
+import com.lowagie.text.rtf.RtfElement;
+import com.lowagie.text.rtf.document.RtfDocument;
+import com.lowagie.text.rtf.style.RtfFont;
+
+
+/**
+ * The RtfPhrase contains multiple RtfChunks
+ * 
+ * @version $Id: RtfPhrase.java 3580 2008-08-06 15:52:00Z howard_s $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Thomas Bickel (tmb99@inode.at)
+ */
+public class RtfPhrase extends RtfElement {
+
+    /**
+     * Constant for the resetting of the paragraph defaults
+     */
+    public static final byte[] PARAGRAPH_DEFAULTS = DocWriter.getISOBytes("\\pard");
+    /**
+     * Constant for resetting of font settings to their defaults
+     */
+    public static final byte[] PLAIN = DocWriter.getISOBytes("\\plain");
+    /**
+     * Constant for phrase in a table indication
+     */
+    public static final byte[] IN_TABLE = DocWriter.getISOBytes("\\intbl");
+    /**
+     * Constant for the line spacing.
+     */
+    public static final byte[] LINE_SPACING = DocWriter.getISOBytes("\\sl");
+    
+    /**
+     * ArrayList containing the RtfChunks of this RtfPhrase
+     */
+    protected ArrayList chunks = new ArrayList();
+    /**
+     * The height of each line.
+     */
+    private int lineLeading = 0; 
+    
+    /**
+     * A basically empty constructor that is used by the RtfParagraph.
+     * 
+     * @param doc The RtfDocument this RtfPhrase belongs to.
+     */
+    protected RtfPhrase(RtfDocument doc) {
+        super(doc);
+    }
+    
+    /**
+     * Constructs a new RtfPhrase for the RtfDocument with the given Phrase
+     * 
+     * @param doc The RtfDocument this RtfPhrase belongs to
+     * @param phrase The Phrase this RtfPhrase is based on
+     */
+    public RtfPhrase(RtfDocument doc, Phrase phrase) {
+        super(doc);
+        
+        if(phrase == null) {
+            return;
+        }
+        
+        if(phrase.hasLeading()) {
+            this.lineLeading = (int) (phrase.getLeading() * RtfElement.TWIPS_FACTOR);
+        } else {
+            this.lineLeading = 0;
+        }
+        
+        RtfFont phraseFont = new RtfFont(null, phrase.getFont());
+        for(int i = 0; i < phrase.size(); i++) {
+            Element chunk = (Element) phrase.get(i);
+            if(chunk instanceof Chunk) {
+                ((Chunk) chunk).setFont(phraseFont.difference(((Chunk) chunk).getFont()));
+            }
+            try {
+                RtfBasicElement[] rtfElements = doc.getMapper().mapElement(chunk);
+                for(int j = 0; j < rtfElements.length; j++) {
+                    chunks.add(rtfElements[j]);
+                }
+            } catch(DocumentException de) {
+            }
+        }
+    }
+    
+    /**
+     * Write the content of this RtfPhrase. First resets to the paragraph defaults
+     * then if the RtfPhrase is in a RtfCell a marker for this is written and finally
+     * the RtfChunks of this RtfPhrase are written.
+     */    
+    public void writeContent(final OutputStream result) throws IOException
+    {
+        result.write(PARAGRAPH_DEFAULTS);
+        result.write(PLAIN);
+        if(inTable) {
+            result.write(IN_TABLE);
+        }
+        if(this.lineLeading > 0) {
+            result.write(LINE_SPACING);
+            result.write(intToByteArray(this.lineLeading));
+        }
+        for(int i = 0; i < chunks.size(); i++) {
+        	RtfBasicElement rbe = (RtfBasicElement) chunks.get(i);
+        	rbe.writeContent(result);
+        }
+    }        
+    
+    /**
+     * Sets whether this RtfPhrase is in a table. Sets the correct inTable setting for all
+     * child elements.
+     * 
+     * @param inTable <code>True</code> if this RtfPhrase is in a table, <code>false</code> otherwise
+     */
+    public void setInTable(boolean inTable) {
+        super.setInTable(inTable);
+        for(int i = 0; i < this.chunks.size(); i++) {
+            ((RtfBasicElement) this.chunks.get(i)).setInTable(inTable);
+        }
+    }
+    
+    /**
+     * Sets whether this RtfPhrase is in a header. Sets the correct inTable setting for all
+     * child elements.
+     * 
+     * @param inHeader <code>True</code> if this RtfPhrase is in a header, <code>false</code> otherwise
+     */
+    public void setInHeader(boolean inHeader) {
+        super.setInHeader(inHeader);
+        for(int i = 0; i < this.chunks.size(); i++) {
+            ((RtfBasicElement) this.chunks.get(i)).setInHeader(inHeader);
+        }
+    }
+    
+    /**
+     * Sets the RtfDocument this RtfPhrase belongs to. Also sets the RtfDocument for all child
+     * elements.
+     * 
+     * @param doc The RtfDocument to use
+     */
+    public void setRtfDocument(RtfDocument doc) {
+        super.setRtfDocument(doc);
+        for(int i = 0; i < this.chunks.size(); i++) {
+            ((RtfBasicElement) this.chunks.get(i)).setRtfDocument(this.document);
+        }
+    }
+}
Index: src/core/com/lowagie/text/rtf/table/RtfTable.java
===================================================================
--- src/core/com/lowagie/text/rtf/table/RtfTable.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/table/RtfTable.java	(revision 0)
@@ -0,0 +1,341 @@
+/*
+ * $Id: RtfTable.java 3533 2008-07-07 21:27:13Z Howard_s $
+ *
+ * Copyright 2001, 2002, 2003, 2004 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.rtf.table;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import com.lowagie.text.Element;
+import com.lowagie.text.Row;
+import com.lowagie.text.Table;
+import com.lowagie.text.pdf.PdfPRow;
+import com.lowagie.text.pdf.PdfPTable;
+import com.lowagie.text.rtf.RtfElement;
+import com.lowagie.text.rtf.document.RtfDocument;
+import com.lowagie.text.rtf.style.RtfFont;
+import com.lowagie.text.rtf.text.RtfParagraph;
+
+
+/**
+ * The RtfTable wraps a Table.
+ * INTERNAL USE ONLY
+ * 
+ * @version $Id: RtfTable.java 3533 2008-07-07 21:27:13Z Howard_s $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Steffen Stundzig
+ * @author Benoit Wiart
+ * @author Thomas Bickel (tmb99@inode.at)
+ */
+public class RtfTable extends RtfElement {
+
+    /**
+     * The rows of this RtfTable
+     */
+    private ArrayList rows = null;
+    /**
+     * The percentage of the page width that this RtfTable covers
+     */
+    private float tableWidthPercent = 80;
+    /**
+     * An array with the proportional widths of the cells in each row
+     */
+    private float[] proportionalWidths = null;
+    /**
+     * The cell padding
+     */
+    private float cellPadding = 0;
+    /**
+     * The cell spacing
+     */
+    private float cellSpacing = 0;
+    
+    /**
+     * The border style of this RtfTable 
+     */
+    private RtfBorderGroup borders = null;
+    /**
+     * The alignment of this RtfTable
+     */
+    private int alignment = Element.ALIGN_CENTER;
+    /**
+     * Whether the cells in this RtfTable must fit in a page
+     */
+    private boolean cellsFitToPage = false;
+    /**
+     * Whether the whole RtfTable must fit in a page
+     */
+    private boolean tableFitToPage = false;
+    /**
+     * The number of header rows in this RtfTable
+     */
+    private int headerRows = 0;
+    /**
+     * The offset from the previous text
+     */
+    private int offset = -1;
+    
+    /**
+     * Constructs a RtfTable based on a Table for a RtfDocument.
+     * 
+     * @param doc The RtfDocument this RtfTable belongs to
+     * @param table The Table that this RtfTable wraps
+     */
+    public RtfTable(RtfDocument doc, Table table) {
+        super(doc);
+        table.complete();
+        importTable(table);
+    }
+
+    /**
+     * Constructs a RtfTable based on a PdfTable for a RtfDocument.
+     * 
+     * @param doc The RtfDocument this RtfTable belongs to
+     * @param table The PdfPTable that this RtfTable wraps
+     * @since 2.1.3
+     */
+    public RtfTable(RtfDocument doc, PdfPTable table) {
+        super(doc);
+        importTable(table);
+    }
+    /**
+     * Imports the rows and settings from the Table into this
+     * RtfTable.
+     * 
+     * @param table The source Table
+     */
+    private void importTable(Table table) {
+        this.rows = new ArrayList();
+        this.tableWidthPercent = table.getWidth();
+        this.proportionalWidths = table.getProportionalWidths();
+        this.cellPadding = (float) (table.getPadding() * TWIPS_FACTOR);
+        this.cellSpacing = (float) (table.getSpacing() * TWIPS_FACTOR);
+        this.borders = new RtfBorderGroup(this.document, RtfBorder.ROW_BORDER, table.getBorder(), table.getBorderWidth(), table.getBorderColor());
+        this.alignment = table.getAlignment();
+        
+        int i = 0;
+        Iterator rowIterator = table.iterator();
+        while(rowIterator.hasNext()) {
+            this.rows.add(new RtfRow(this.document, this, (Row) rowIterator.next(), i));
+            i++;
+        }
+        for(i = 0; i < this.rows.size(); i++) {
+            ((RtfRow) this.rows.get(i)).handleCellSpanning();
+            ((RtfRow) this.rows.get(i)).cleanRow();
+        }
+        this.headerRows = table.getLastHeaderRow();
+        this.cellsFitToPage = table.isCellsFitPage();
+        this.tableFitToPage = table.isTableFitsPage();
+        if(!Float.isNaN(table.getOffset())) {
+            this.offset = (int) (table.getOffset() * 2);
+        }
+    }
+
+    /**
+     * Imports the rows and settings from the Table into this
+     * RtfTable.
+     * 
+     * @param table The source PdfPTable
+     * @since 2.1.3
+     */
+    private void importTable(PdfPTable table) {
+        this.rows = new ArrayList();
+        this.tableWidthPercent = table.getWidthPercentage();
+//        this.tableWidthPercent = table.getWidth();
+        this.proportionalWidths = table.getAbsoluteWidths();
+//        this.proportionalWidths = table.getProportionalWidths();
+        this.cellPadding = (float) (table.spacingAfter() * TWIPS_FACTOR);
+//        this.cellPadding = (float) (table.getPadding() * TWIPS_FACTOR);
+        this.cellSpacing = (float) (table.spacingAfter() * TWIPS_FACTOR);
+//        this.cellSpacing = (float) (table.getSpacing() * TWIPS_FACTOR);
+//        this.borders = new RtfBorderGroup(this.document, RtfBorder.ROW_BORDER, table.getBorder(), table.getBorderWidth(), table.getBorderColor());
+//        this.borders = new RtfBorderGroup(this.document, RtfBorder.ROW_BORDER, table.getBorder(), table.getBorderWidth(), table.getBorderColor());
+        this.alignment = table.getHorizontalAlignment();
+//        this.alignment = table.getAlignment();
+        
+        int i = 0;
+        Iterator rowIterator = table.getRows().iterator();
+//        Iterator rowIterator = table.iterator();
+        while(rowIterator.hasNext()) {
+            this.rows.add(new RtfRow(this.document, this, (PdfPRow) rowIterator.next(), i));
+            i++;
+        }
+        for(i = 0; i < this.rows.size(); i++) {
+            ((RtfRow) this.rows.get(i)).handleCellSpanning();
+            ((RtfRow) this.rows.get(i)).cleanRow();
+        }
+        
+        this.headerRows = table.getHeaderRows();
+//        this.headerRows = table.getLastHeaderRow();
+        this.cellsFitToPage = table.getKeepTogether();
+//        this.cellsFitToPage = table.isCellsFitPage();
+        this.tableFitToPage = table.getKeepTogether();
+//        this.tableFitToPage = table.isTableFitsPage();
+//        if(!Float.isNaN(table.getOffset())) {
+//            this.offset = (int) (table.getOffset() * 2);
+//        }
+//        if(!Float.isNaN(table.getOffset())) {
+//            this.offset = (int) (table.getOffset() * 2);
+//        }
+    }
+    
+    /**
+     * Writes the content of this RtfTable
+     */    
+    public void writeContent(final OutputStream result) throws IOException
+    {
+        if(!inHeader) {
+            if(this.offset != -1) {
+                result.write(RtfFont.FONT_SIZE);
+                result.write(intToByteArray(this.offset));
+            }
+            result.write(RtfParagraph.PARAGRAPH);
+        }
+        
+        for(int i = 0; i < this.rows.size(); i++) {
+        	RtfElement re = (RtfElement)this.rows.get(i);
+            //.result.write(re.write());
+        	re.writeContent(result);
+        }
+        
+        result.write(RtfParagraph.PARAGRAPH_DEFAULTS);
+    }        
+    
+    /**
+     * Gets the alignment of this RtfTable
+     * 
+     * @return The alignment of this RtfTable.
+     */
+    protected int getAlignment() {
+        return alignment;
+    }
+    
+    /**
+     * Gets the borders of this RtfTable
+     * 
+     * @return The borders of this RtfTable.
+     */
+    protected RtfBorderGroup getBorders() {
+        return this.borders;
+    }
+    
+    /**
+     * Gets the cell padding of this RtfTable
+     * 
+     * @return The cell padding of this RtfTable.
+     */
+    protected float getCellPadding() {
+        return cellPadding;
+    }
+    
+    /**
+     * Gets the cell spacing of this RtfTable
+     * 
+     * @return The cell spacing of this RtfTable.
+     */
+    protected float getCellSpacing() {
+        return cellSpacing;
+    }
+    
+    /**
+     * Gets the proportional cell widths of this RtfTable
+     * 
+     * @return The proportional widths of this RtfTable.
+     */
+    protected float[] getProportionalWidths() {
+        return (float[]) proportionalWidths.clone();
+    }
+    
+    /**
+     * Gets the percentage of the page width this RtfTable covers 
+     * 
+     * @return The percentage of the page width.
+     */
+    protected float getTableWidthPercent() {
+        return tableWidthPercent;
+    }
+    
+    /**
+     * Gets the rows of this RtfTable
+     * 
+     * @return The rows of this RtfTable
+     */
+    protected ArrayList getRows() {
+        return this.rows;
+    }
+    
+    /**
+     * Gets the cellsFitToPage setting of this RtfTable.
+     * 
+     * @return The cellsFitToPage setting of this RtfTable.
+     */
+    protected boolean getCellsFitToPage() {
+        return this.cellsFitToPage;
+    }
+    
+    /**
+     * Gets the tableFitToPage setting of this RtfTable.
+     * 
+     * @return The tableFitToPage setting of this RtfTable.
+     */
+    protected boolean getTableFitToPage() {
+        return this.tableFitToPage;
+    }
+    
+    /**
+     * Gets the number of header rows of this RtfTable
+     * 
+     * @return The number of header rows
+     */
+    protected int getHeaderRows() {
+        return this.headerRows;
+    }
+}
Index: src/core/com/lowagie/text/rtf/graphic/RtfShapeProperty.java
===================================================================
--- src/core/com/lowagie/text/rtf/graphic/RtfShapeProperty.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/graphic/RtfShapeProperty.java	(revision 0)
@@ -0,0 +1,314 @@
+package com.lowagie.text.rtf.graphic;
+
+import java.awt.Color;
+import java.awt.Point;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import com.lowagie.text.DocWriter;
+import com.lowagie.text.DocumentException;
+import com.lowagie.text.ExceptionConverter;
+import com.lowagie.text.Image;
+import com.lowagie.text.rtf.RtfAddableElement;
+
+/**
+ * The RtfShapeProperty stores all shape properties that are
+ * not handled by the RtfShape and RtfShapePosition.<br /><br />
+ * 
+ * There is a huge selection of properties that can be set. For
+ * the most important properites there are constants for the
+ * property name, for all others you must find the correct
+ * property name in the RTF specification (version 1.6).<br /><br />
+ * 
+ * The following types of property values are supported:
+ * <ul>
+ *   <li>long</li>
+ *   <li>double</li>
+ *   <li>boolean</li>
+ *   <li>Color</li>
+ *   <li>int[]</li>
+ *   <li>Point[]</li>
+ * </ul>
+ * 
+ * @version $Id: RtfShapeProperty.java 3580 2008-08-06 15:52:00Z howard_s $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Thomas Bickel (tmb99@inode.at)
+ */
+public class RtfShapeProperty extends RtfAddableElement {
+    /**
+    * Property for defining an image.
+    */
+    public static final String PROPERTY_IMAGE = "pib";
+    /**
+     * Property for defining vertices in freeform shapes. Requires a
+     * Point array as the value.
+     */
+    public static final String PROPERTY_VERTICIES = "pVerticies";
+    /**
+     * Property for defining the minimum vertical coordinate that is
+     * visible. Requires a long value.
+     */
+    public static final String PROPERTY_GEO_TOP = "geoTop";
+    /**
+     * Property for defining the minimum horizontal coordinate that is
+     * visible. Requires a long value.
+     */
+    public static final String PROPERTY_GEO_LEFT = "geoLeft";
+    /**
+     * Property for defining the maximum horizontal coordinate that is
+     * visible. Requires a long value.
+     */
+    public static final String PROPERTY_GEO_RIGHT = "geoRight";
+    /**
+     * Property for defining the maximum vertical coordinate that is
+     * visible. Requires a long value.
+     */
+    public static final String PROPERTY_GEO_BOTTOM = "geoBottom";
+    /**
+     * Property for defining that the shape is in a table cell. Requires
+     * a boolean value.
+     */
+    public static final String PROPERTY_LAYOUT_IN_CELL = "fLayoutInCell";
+    /**
+     * Property for signaling a vertical flip of the shape. Requires a
+     * boolean value.
+     */
+    public static final String PROPERTY_FLIP_V = "fFlipV";
+    /**
+     * Property for signaling a horizontal flip of the shape. Requires a
+     * boolean value.
+     */
+    public static final String PROPERTY_FLIP_H = "fFlipH";
+    /**
+     * Property for defining the fill color of the shape. Requires a
+     * Color value.
+     */
+    public static final String PROPERTY_FILL_COLOR = "fillColor";
+    /**
+     * Property for defining the line color of the shape. Requires a
+     * Color value.
+     */
+    public static final String PROPERTY_LINE_COLOR = "lineColor";
+    /**
+     * Property for defining the first adjust handle for shapes. Used
+     * with the rounded rectangle. Requires a long value.
+     */
+    public static final String PROPERTY_ADJUST_VALUE = "adjustValue";
+
+    /**
+     * The stored value is a long.
+     */
+    private static final int PROPERTY_TYPE_LONG = 1;
+    /**
+     * The stored value is boolean.
+     */
+	private static final int PROPERTY_TYPE_BOOLEAN = 2;
+    /**
+     * The stored value is a double.
+     */
+	private static final int PROPERTY_TYPE_DOUBLE = 3;
+    /**
+     * The stored value is a Color.
+     */
+	private static final int PROPERTY_TYPE_COLOR = 4;
+    /**
+     * The stored value is either an int or a Point array.
+     */
+	private static final int PROPERTY_TYPE_ARRAY = 5;
+    /**
+    * The stored value is an Image.
+    */
+    private static final int PROPERTY_TYPE_IMAGE = 6;
+	
+    /**
+     * The value type.
+     */
+	private int type = 0;
+    /**
+     * The RtfShapeProperty name.
+     */
+	private String name = "";
+    /**
+     * The RtfShapeProperty value.
+     */
+	private Object value = null;
+	
+    /**
+     * Internally used to create the RtfShape.
+     * 
+     * @param name The property name to use.
+     * @param value The property value to use.
+     */
+	private RtfShapeProperty(String name, Object value) {
+		this.name = name;
+		this.value = value;
+	}
+	
+    /**
+     * Constructs a RtfShapeProperty with a long value.
+     * 
+     * @param name The property name to use.
+     * @param value The long value to use.
+     */
+	public RtfShapeProperty(String name, long value) {
+		this(name, new Long(value));
+		this.type = PROPERTY_TYPE_LONG;
+	}
+	
+    /**
+     * Constructs a RtfShapeProperty with a double value.
+     * 
+     * @param name The property name to use.
+     * @param value The double value to use.
+     */
+	public RtfShapeProperty(String name, double value) {
+		this(name, new Double(value));
+		this.type = PROPERTY_TYPE_DOUBLE;
+	}
+	
+    /**
+     * Constructs a RtfShapeProperty with a boolean value.
+     * 
+     * @param name The property name to use.
+     * @param value The boolean value to use.
+     */
+	public RtfShapeProperty(String name, boolean value) {
+		this(name, Boolean.valueOf(value));
+		this.type = PROPERTY_TYPE_BOOLEAN;
+	}
+	
+    /**
+     * Constructs a RtfShapeProperty with a Color value.
+     * 
+     * @param name The property name to use.
+     * @param value The Color value to use.
+     */
+	public RtfShapeProperty(String name, Color value) {
+		this(name, (Object) value);
+		this.type = PROPERTY_TYPE_COLOR;
+	}
+	
+    /**
+     * Constructs a RtfShapeProperty with an int array value.
+     * 
+     * @param name The property name to use.
+     * @param value The int array to use.
+     */
+	public RtfShapeProperty(String name, int[] value) {
+		this(name, (Object) value);
+		this.type = PROPERTY_TYPE_ARRAY;
+	}
+    
+    /**
+     * Constructs a RtfShapeProperty with a Point array value.
+     * 
+     * @param name The property name to use.
+     * @param value The Point array to use.
+     */
+    public RtfShapeProperty(String name, Point[] value) {
+        this(name, (Object) value);
+        this.type = PROPERTY_TYPE_ARRAY;
+    }
+	
+    /**
+    * Constructs a RtfShapeProperty with an Image value.
+    * 
+    * @param name The property name to use.
+    * @param value The Image to use.
+    */
+    public RtfShapeProperty(String name, Image value) {
+        this.name = name;
+        this.value = value;
+        this.type = PROPERTY_TYPE_IMAGE;
+    }
+
+    /**
+     * Gets the name of this RtfShapeProperty.
+     * 
+     * @return The name of this RtfShapeProperty.
+     */
+    public String getName() {
+        return this.name;
+    }
+    
+    /**
+     * Writes the property definition. How the property
+     * is written depends on the property type.
+     */
+    public void writeContent(final OutputStream result) throws IOException
+    {    	
+    	result.write(OPEN_GROUP);
+    	result.write(DocWriter.getISOBytes("\\sp"));
+    	result.write(OPEN_GROUP);
+    	result.write(DocWriter.getISOBytes("\\sn"));
+    	result.write(DELIMITER);
+    	result.write(DocWriter.getISOBytes(this.name));
+    	result.write(CLOSE_GROUP);
+    	result.write(OPEN_GROUP);
+    	result.write(DocWriter.getISOBytes("\\sv"));
+    	result.write(DELIMITER);
+    	switch(this.type) {
+    	case PROPERTY_TYPE_LONG: 
+    	case PROPERTY_TYPE_DOUBLE:
+    		result.write(DocWriter.getISOBytes(this.value.toString()));
+    		break;
+    	case PROPERTY_TYPE_BOOLEAN:
+    		if(((Boolean) this.value).booleanValue()) {
+    			result.write(DocWriter.getISOBytes("1"));
+    		} else {
+    			result.write(DocWriter.getISOBytes("0"));
+    		}
+    		break;
+    	case PROPERTY_TYPE_COLOR:
+            Color color = (Color) this.value;
+            result.write(intToByteArray(color.getRed() | (color.getGreen() << 8) | (color.getBlue() << 16)));
+    		break;
+    	case PROPERTY_TYPE_ARRAY:
+    	    if(this.value instanceof int[]) {
+    	        int[] values = (int[]) this.value;
+    	        result.write(DocWriter.getISOBytes("4;"));
+    	        result.write(intToByteArray(values.length));
+    	        result.write(COMMA_DELIMITER);
+    	        for(int i = 0; i < values.length; i++) {
+    	            result.write(intToByteArray(values[i]));
+    	            if(i < values.length - 1) {
+    	                result.write(COMMA_DELIMITER);
+    	            }
+    	        }
+    	    } else if(this.value instanceof Point[]) {
+    	        Point[] values = (Point[]) this.value;
+                result.write(DocWriter.getISOBytes("8;"));
+                result.write(intToByteArray(values.length));
+                result.write(COMMA_DELIMITER);
+                for(int i = 0; i < values.length; i++) {
+                    result.write(DocWriter.getISOBytes("("));
+                    result.write(intToByteArray(values[i].x));
+                    result.write(DocWriter.getISOBytes(","));
+                    result.write(intToByteArray(values[i].y));
+                    result.write(DocWriter.getISOBytes(")"));
+                    if(i < values.length - 1) {
+                        result.write(COMMA_DELIMITER);
+                    }
+                }
+            }
+    		break;
+        case PROPERTY_TYPE_IMAGE:
+            Image image = (Image)this.value;
+            RtfImage img = null;
+            try {
+                img = new RtfImage(this.doc, image);
+            }
+            catch (DocumentException de) {
+                throw new ExceptionConverter(de);
+            }
+            img.setTopLevelElement(true);
+            result.write(OPEN_GROUP);
+            img.writeContent(result);
+            result.write(CLOSE_GROUP);
+            break;
+    	}
+    	result.write(CLOSE_GROUP);
+    	result.write(CLOSE_GROUP);
+    }
+	
+}

Property changes on: src/core/com/lowagie/text/rtf/graphic/RtfShapeProperty.java
___________________________________________________________________
Added: svn:executable
   + *

Index: src/core/com/lowagie/text/rtf/direct/RtfDirectContent.java
===================================================================
--- src/core/com/lowagie/text/rtf/direct/RtfDirectContent.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/direct/RtfDirectContent.java	(revision 0)
@@ -0,0 +1,103 @@
+/**
+ * $Id: RtfDirectContent.java 3580 2008-08-06 15:52:00Z howard_s $
+ *
+ * Copyright 2006 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+package com.lowagie.text.rtf.direct;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import com.lowagie.text.DocWriter;
+import com.lowagie.text.rtf.RtfAddableElement;
+
+/**
+ * The RtfDirectContent makes it possible to directly add RTF code into
+ * an RTF document. This can be used to directly add RTF fragments that
+ * have been created with other RTF editors. One important aspect is that
+ * font and color numbers will not be modified. This means that the
+ * fonts and colors visible in the final document might not be equivalent
+ * with those set on the direct content.<br /><br />
+ * 
+ * For convenience the RtfDirectContent provides a DIRECT_SOFT_LINEBREAK
+ * constant that makes it possible to easily add soft line-breaks anywhere in
+ * the RTF document.
+ * 
+ * @version $Id: RtfDirectContent.java 3580 2008-08-06 15:52:00Z howard_s $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Thomas Bickel (tmb99@inode.at)
+ */
+public class RtfDirectContent extends RtfAddableElement {
+	/**
+	 * Add the DIRECT_SOFT_LINEBREAK to the Document to insert
+	 * a soft line-break at that position.
+	 */
+	public static final RtfDirectContent DIRECT_SOFT_LINEBREAK = new RtfDirectContent("\\line");
+	
+	/**
+	 * The direct content to add.
+	 */
+	private String directContent = "";
+	
+	/**
+	 * Constructs a new RtfDirectContent with the content to add.
+	 * 
+	 * @param directContent The content to add.
+	 */
+	public RtfDirectContent(String directContent)
+	{
+		this.directContent = directContent;
+	}
+	
+    /**
+     * Writes the element content to the given output stream.
+     */    
+    public void writeContent(final OutputStream out) throws IOException
+    {
+    	final byte[] contentBytes = DocWriter.getISOBytes(this.directContent);
+   		out.write(contentBytes);
+    }        
+}
Index: src/core/com/lowagie/text/rtf/text/RtfSection.java
===================================================================
--- src/core/com/lowagie/text/rtf/text/RtfSection.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/text/RtfSection.java	(revision 0)
@@ -0,0 +1,198 @@
+/*
+ * $Id: RtfSection.java 3373 2008-05-12 16:21:24Z xlv $
+ *
+ * Copyright 2001, 2002, 2003, 2004 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.rtf.text;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import com.lowagie.text.Chunk;
+import com.lowagie.text.DocumentException;
+import com.lowagie.text.Element;
+import com.lowagie.text.Section;
+import com.lowagie.text.rtf.RtfBasicElement;
+import com.lowagie.text.rtf.RtfElement;
+import com.lowagie.text.rtf.document.RtfDocument;
+import com.lowagie.text.rtf.field.RtfTOCEntry;
+
+
+/**
+ * The RtfSection wraps a Section element.
+ * INTERNAL CLASS
+ * 
+ * @version $Id: RtfSection.java 3373 2008-05-12 16:21:24Z xlv $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Thomas Bickel (tmb99@inode.at)
+ */
+public class RtfSection extends RtfElement {
+
+    /**
+     * The title paragraph of this RtfSection
+     */
+    protected RtfParagraph title = null;
+    /**
+     * The sub-items of this RtfSection
+     */
+    protected ArrayList items = null;
+    
+    /**
+     * Constructs a RtfSection for a given Section. If the autogenerateTOCEntries
+     * property of the RtfDocument is set and the title is not empty then a TOC entry
+     * is generated for the title.
+     *  
+     * @param doc The RtfDocument this RtfSection belongs to
+     * @param section The Section this RtfSection is based on
+     */
+    public RtfSection(RtfDocument doc, Section section) {
+        super(doc);
+        items = new ArrayList();
+        try {
+            if(section.getTitle() != null) {
+                this.title = (RtfParagraph) doc.getMapper().mapElement(section.getTitle())[0];
+            }
+            if(document.getAutogenerateTOCEntries()) {
+                StringBuffer titleText = new StringBuffer();
+                Iterator it = section.getTitle().iterator();
+                while(it.hasNext()) {
+                    Element element = (Element) it.next();
+                    if(element.type() == Element.CHUNK) {
+                        titleText.append(((Chunk) element).getContent());
+                    }
+                }
+                if(titleText.toString().trim().length() > 0) {
+                    RtfTOCEntry tocEntry = new RtfTOCEntry(titleText.toString());
+                    tocEntry.setRtfDocument(this.document);
+                    this.items.add(tocEntry);
+                }
+            }
+            Iterator iterator = section.iterator();
+            while(iterator.hasNext()) {
+                Element element = (Element) iterator.next();
+                RtfBasicElement[] rtfElements = doc.getMapper().mapElement(element);
+                for(int i = 0; i < rtfElements.length; i++) {
+                    if(rtfElements[i] != null) {
+                        items.add(rtfElements[i]);
+                    }
+                }
+            }
+            
+            updateIndentation(section.getIndentationLeft(), section.getIndentationRight(), section.getIndentation());
+        } catch(DocumentException de) {
+            de.printStackTrace();
+        }
+    }
+    
+    /**
+     * Write this RtfSection and its contents
+     */    
+    public void writeContent(final OutputStream result) throws IOException
+    {
+        result.write(RtfParagraph.PARAGRAPH);
+        if(this.title != null) {
+            this.title.writeContent(result);
+        }
+        for(int i = 0; i < items.size(); i++) {
+        	RtfBasicElement rbe = (RtfBasicElement) items.get(i);
+            rbe.writeContent(result);
+        }
+    }        
+
+    
+    /**
+     * Sets whether this RtfSection is in a table. Sets the correct inTable setting for all
+     * child elements.
+     * 
+     * @param inTable <code>True</code> if this RtfSection is in a table, <code>false</code> otherwise
+     */
+    public void setInTable(boolean inTable) {
+        super.setInTable(inTable);
+        for(int i = 0; i < this.items.size(); i++) {
+            ((RtfBasicElement) this.items.get(i)).setInTable(inTable);
+        }
+    }
+    
+    /**
+     * Sets whether this RtfSection is in a header. Sets the correct inTable setting for all
+     * child elements.
+     * 
+     * @param inHeader <code>True</code> if this RtfSection is in a header, <code>false</code> otherwise
+     */
+    public void setInHeader(boolean inHeader) {
+        super.setInHeader(inHeader);
+        for(int i = 0; i < this.items.size(); i++) {
+            ((RtfBasicElement) this.items.get(i)).setInHeader(inHeader);
+        }
+    }
+
+    /**
+     * Updates the left, right and content indentation of all RtfParagraph and RtfSection
+     * elements that this RtfSection contains.
+     * 
+     * @param indentLeft The left indentation to add.
+     * @param indentRight The right indentation to add.
+     * @param indentContent The content indentation to add.
+     */
+    private void updateIndentation(float indentLeft, float indentRight, float indentContent) {
+        if(this.title != null) {
+            this.title.setIndentLeft((int) (this.title.getIndentLeft() + indentLeft * RtfElement.TWIPS_FACTOR));
+            this.title.setIndentRight((int) (this.title.getIndentRight() + indentRight * RtfElement.TWIPS_FACTOR));
+        }
+        for(int i = 0; i < this.items.size(); i++) {
+            RtfBasicElement rtfElement = (RtfBasicElement) this.items.get(i);
+            if(rtfElement instanceof RtfSection) {
+                ((RtfSection) rtfElement).updateIndentation(indentLeft + indentContent, indentRight, 0);
+            } else if(rtfElement instanceof RtfParagraph) {
+                ((RtfParagraph) rtfElement).setIndentLeft((int) (((RtfParagraph) rtfElement).getIndentLeft() + (indentLeft + indentContent) * RtfElement.TWIPS_FACTOR));
+                ((RtfParagraph) rtfElement).setIndentRight((int) (((RtfParagraph) rtfElement).getIndentRight() + indentRight * RtfElement.TWIPS_FACTOR));
+            }
+        }
+    }
+}
Index: src/core/com/lowagie/text/rtf/document/output/RtfByteArrayBuffer.java
===================================================================
--- src/core/com/lowagie/text/rtf/document/output/RtfByteArrayBuffer.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/document/output/RtfByteArrayBuffer.java	(revision 0)
@@ -0,0 +1,307 @@
+/*
+ * Copyright 2007 Thomas Bickel
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.rtf.document.output;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * A RtfByteArrayBuffer works much like {@link ByteArrayOutputStream} but is cheaper and faster in most cases
+ * (exception: large writes when reusing buffers).
+ * 
+ * @version $Id: RtfByteArrayBuffer.java 3433 2008-05-24 19:32:11Z xlv $
+ * @author Thomas Bickel (tmb99@inode.at)
+ */
+public final class RtfByteArrayBuffer extends OutputStream
+{
+	private final java.util.List arrays = new java.util.ArrayList();
+	private byte[] buffer;
+	private int pos = 0;
+	private int size = 0;
+	
+	/**
+	 * Constructs a new buffer with a default initial size of 128 bytes.
+	 */
+	public RtfByteArrayBuffer()
+	{    		
+		this(256);
+	}
+	/**
+	 * Creates a new buffer with the given initial size.
+	 * 
+	 * @param bufferSize desired initial size in bytes
+	 */
+	public RtfByteArrayBuffer(final int bufferSize)
+	{
+		if((bufferSize <= 0) || (bufferSize > 1<<30)) throw new IllegalArgumentException("bufferSize "+bufferSize);
+		
+		int n = 1<<5;
+		while(n < bufferSize) {
+			n <<= 1;
+		}
+		buffer = new byte[n];
+	}
+	
+	public String toString()
+	{
+		return("RtfByteArrayBuffer: size="+size()+" #arrays="+arrays.size()+" pos="+pos);
+	}
+	
+	/**
+	 * Resets this buffer.
+	 */
+	public void reset()
+	{
+		arrays.clear();
+		pos = 0;
+		size = 0;
+	}
+	
+	/**
+	 * Returns the number of bytes that have been written to this buffer so far.
+	 * 
+     * @return number of bytes written to this buffer
+	 */
+	public long size()
+	{
+		return size;
+	}
+	
+	private void flushBuffer()
+	{
+		flushBuffer(1);
+	}
+	private void flushBuffer(final int reqSize)
+	{
+		if(reqSize < 0) throw new IllegalArgumentException();
+		
+		if(pos == 0) return;
+
+		if(pos == buffer.length) {
+			//add old buffer, alloc new (possibly larger) buffer
+			arrays.add(buffer);
+			int newSize = buffer.length;
+			buffer = null;
+			final int MAX = Math.max(1, size>>24) << 16;
+			while(newSize < MAX) {
+				newSize <<= 1;
+				if(newSize >= reqSize) break;
+			}
+			buffer = new byte[newSize];
+		} else {
+			//copy buffer contents to newly allocated buffer
+			final byte[] c = new byte[pos];
+			System.arraycopy(buffer, 0, c, 0, pos);
+			arrays.add(c);    			
+		}
+		pos = 0;    		
+	}
+	
+	/**
+	 * Copies the given byte to the internal buffer.
+	 * 
+	 * @param b
+	 */
+	public void write(final int b)
+	{
+		buffer[pos] = (byte)b;
+		size++;
+		if(++pos == buffer.length) flushBuffer();
+	}    	
+	/**
+	 * Copies the given array to the internal buffer.
+	 * 
+	 * @param src
+	 */
+	public void write(final byte[] src)
+	{
+		if(src == null) throw new NullPointerException();
+
+		if(src.length < buffer.length - pos) {
+			System.arraycopy(src, 0, buffer, pos, src.length);
+			pos += src.length;
+			size += src.length;
+			return;
+		}
+		writeLoop(src, 0, src.length);
+	}
+	/**
+	 * Copies len bytes starting at position off from the array src to the internal buffer.
+	 * 
+	 * @param src
+	 * @param off
+	 * @param len
+	 */
+	public void write(final byte[] src, int off, int len)
+	{
+		if(src == null) throw new NullPointerException();
+		if((off < 0) || (off > src.length) || (len < 0) || ((off + len) > src.length) || ((off + len) < 0)) throw new IndexOutOfBoundsException();
+
+		writeLoop(src, off, len);		
+	}
+	private void writeLoop(final byte[] src, int off, int len)
+	{
+		while(len > 0) {
+			final int room = buffer.length - pos;
+			final int n = len > room ? room : len;
+			System.arraycopy(src, off, buffer, pos, n);
+			len -= n;
+			off += n;
+			pos += n;
+			size += n;
+			if(pos == buffer.length) flushBuffer(len);
+		}		
+	}
+	
+	/**
+	 * Writes all bytes available in the given inputstream to this buffer. 
+	 * 
+	 * @param in
+     * @return number of bytes written
+	 * @throws IOException
+	 */
+	public long write(final InputStream in) throws IOException
+	{
+		if(in == null) throw new NullPointerException();
+		
+		final long sizeStart = size;
+		while(true) {
+			final int n = in.read(buffer, pos, buffer.length - pos);
+			if(n < 0) break;
+			pos += n;
+			size += n;
+			if(pos == buffer.length) flushBuffer();
+		}
+		return(size - sizeStart);
+	}
+	
+	/**
+	 * Appends the given array to this buffer without copying (if possible). 
+	 * 
+	 * @param a
+	 */
+	public void append(final byte[] a)
+	{
+		if(a == null) throw new NullPointerException();
+		if(a.length == 0) return;
+		
+		if(a.length <= 8) {
+			write(a, 0, a.length);		
+		} else
+		if((a.length <= 16) && (pos > 0) && ((buffer.length - pos) > a.length)) {
+			write(a, 0, a.length);
+		} else {
+			flushBuffer();
+			arrays.add(a);
+			size += a.length;
+		}
+	}
+	/**
+	 * Appends all arrays to this buffer without copying (if possible).
+	 * 
+	 * @param a
+	 */
+	public void append(final byte[][] a)
+	{
+		if(a == null) throw new NullPointerException();
+
+		for(int k = 0; k < a.length; k++) {
+			append(a[k]);
+		}
+	}
+	
+	/**
+	 * Returns the internal list of byte array buffers without copying the buffer contents. 
+	 * 
+     * @return number of bytes written
+	 */
+	public byte[][] toByteArrayArray()
+	{
+		flushBuffer();
+		return(byte[][])arrays.toArray(new byte[arrays.size()][]);
+	}
+	
+	/**
+	 * Allocates a new array and copies all data that has been written to this buffer to the newly allocated array.
+	 * 
+     * @return a new byte array
+	 */
+	public byte[] toByteArray()
+	{
+		final byte[] r = new byte[size];
+		int off = 0;
+		final int n = arrays.size();
+		for(int k = 0; k < n; k++) {
+			byte[] src = (byte[])arrays.get(k);
+			System.arraycopy(src, 0, r, off, src.length);
+			off += src.length;
+		}
+		if(pos > 0) System.arraycopy(buffer, 0, r, off, pos);
+		return r;
+	}
+
+	/**
+	 * Writes all data that has been written to this buffer to the given output stream.
+	 * 
+	 * @param out
+	 * @throws IOException
+	 */
+	public void writeTo(final OutputStream out) throws IOException
+	{
+		if(out == null) throw new NullPointerException();
+		
+		final int n = arrays.size();
+		for(int k = 0; k < n; k++) {
+			byte[] src = (byte[])arrays.get(k);
+			out.write(src);
+		}
+		if(pos > 0) out.write(buffer, 0, pos);
+	}
+}
Index: src/core/com/lowagie/text/rtf/parser/RtfImportMgr.java
===================================================================
--- src/core/com/lowagie/text/rtf/parser/RtfImportMgr.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/parser/RtfImportMgr.java	(revision 0)
@@ -0,0 +1,261 @@
+/*
+ * $Id: RtfImportMgr.java 3456 2008-05-26 15:26:57Z howard_s $
+ *
+ * Copyright 2007 by Howard Shank (hgshank@yahoo.com)
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+package com.lowagie.text.rtf.parser;
+
+
+import java.awt.Color;
+import java.util.HashMap;
+
+import com.lowagie.text.Document;
+import com.lowagie.text.List;
+import com.lowagie.text.rtf.document.RtfDocument;
+import com.lowagie.text.rtf.list.RtfList;
+import com.lowagie.text.rtf.style.RtfColor;
+import com.lowagie.text.rtf.style.RtfFont;
+
+/**
+ * The RtfImportHeader stores the document header information from
+ * an RTF document that is being imported. Currently font and
+ * color settings are stored. The RtfImportHeader maintains a mapping
+ * from font and color numbers from the imported RTF document to
+ * the RTF document that is the target of the import. This guarantees
+ * that the merged document has the correct font and color settings.
+ * It also handles other list based items that need mapping, for example
+ * stylesheets and lists.
+ * 
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Howard Shank (hgshank@yahoo.com)
+ * @since 2.1.0
+ */
+public class RtfImportMgr {
+    //TODO: Add list, stylesheet, info, etc. mappings
+    /**
+     * The HashMap storing the font number mappings.
+     */
+    private HashMap importFontMapping = null;
+    /**
+     * The HashMap storing the color number mappings.
+     */
+    private HashMap importColorMapping = null;
+    /**
+     * The HashMap storing the Stylesheet List number mappings.
+     */
+    private HashMap importStylesheetListMapping = null;
+    /**
+     * The HashMap storing the List number mappings.
+     */
+    private HashMap importListMapping = null;
+    /**
+     * The RtfDocument to get font and color numbers from.
+     */
+    private RtfDocument rtfDoc = null;
+    /**
+     * The Document.
+     * Used for conversions, but not imports.
+     */
+    private Document doc = null;
+
+
+    /**
+     * Constructs a new RtfImportHeader.
+     * 
+     * @param rtfDoc The RtfDocument to get font and color numbers from.
+     */
+    public RtfImportMgr(RtfDocument rtfDoc, Document doc) {
+        this.rtfDoc = rtfDoc;
+        this.doc = doc;
+        this.importFontMapping = new HashMap();
+        this.importColorMapping = new HashMap();
+        this.importStylesheetListMapping = new HashMap();
+        this.importListMapping = new HashMap();
+    }
+
+    /**
+     * Imports a font. The font name is looked up in the RtfDocumentHeader and
+     * then the mapping from original font number to actual font number is added.
+     * 
+     * @param fontNr The original font number.
+     * @param fontName The font name to look up.
+     */
+    public boolean importFont(String fontNr, String fontName) {
+        RtfFont rtfFont = new RtfFont(fontName);
+        rtfFont.setRtfDocument(this.rtfDoc);
+        this.importFontMapping.put(fontNr, Integer.toString(this.rtfDoc.getDocumentHeader().getFontNumber(rtfFont)));
+        return true;
+    }
+    /**
+     * Imports a font. The font name is looked up in the RtfDocumentHeader and
+     * then the mapping from original font number to actual font number is added.
+     * 
+     * @param fontNr The original font number.
+     * @param fontName The font name to look up.
+     * @param charset The character set to use for the font.
+     */
+    public boolean importFont(String fontNr, String fontName, int charset) {
+        RtfFont rtfFont = new RtfFont(fontName);
+        if(charset>= 0)
+            rtfFont.setCharset(charset);
+            rtfFont.setRtfDocument(this.rtfDoc);
+            this.importFontMapping.put(fontNr, Integer.toString(this.rtfDoc.getDocumentHeader().getFontNumber(rtfFont)));
+            return true;
+    }
+    /**
+     * Imports a font. The font name is looked up in the RtfDocumentHeader and
+     * then the mapping from original font number to actual font number is added.
+     * 
+     * @param fontNr The original font number.
+     * @param fontName The font name to look up.
+     * @param charset The character set to use for the font.
+     */
+    public boolean importFont(String fontNr, String fontName, String fontFamily, int charset) {
+        RtfFont rtfFont = new RtfFont(fontName);
+
+        if(charset>= 0)
+            rtfFont.setCharset(charset);
+        if(fontFamily != null && fontFamily.length() > 0)
+            rtfFont.setFamily(fontFamily);
+        rtfFont.setRtfDocument(this.rtfDoc);
+        this.importFontMapping.put(fontNr, Integer.toString(this.rtfDoc.getDocumentHeader().getFontNumber(rtfFont)));
+        return true;
+    }
+    /**
+     * Performs the mapping from the original font number to the actual
+     * font number in the resulting RTF document. If the font number was not
+     * seen during import (thus no mapping) then 0 is returned, guaranteeing
+     * that the font number is always valid.
+     * 
+     * @param fontNr The font number to map.
+     * @return The mapped font number.
+     */
+    public String mapFontNr(String fontNr) {
+        if(this.importFontMapping.containsKey(fontNr)) {
+            return (String) this.importFontMapping.get(fontNr);
+        } else {
+            return "0";
+        }
+    }
+
+    /**
+     * Imports a color value. The color number for the color defined
+     * by its red, green and blue values is determined and then the
+     * resulting mapping is added.
+     * 
+     * @param colorNr The original color number.
+     * @param color The color to import.
+     */
+    public void importColor(String colorNr, Color color) {
+        RtfColor rtfColor = new RtfColor(this.rtfDoc, color);
+        this.importColorMapping.put(colorNr, Integer.toString(rtfColor.getColorNumber()));
+    }
+
+    /**
+     * Performs the mapping from the original font number to the actual font
+     * number used in the RTF document. If the color number was not
+     * seen during import (thus no mapping) then 0 is returned, guaranteeing
+     * that the color number is always valid.
+     * 
+     * @param colorNr The color number to map.
+     * @return The mapped color number
+     */
+    public String mapColorNr(String colorNr) {
+        if(this.importColorMapping.containsKey(colorNr)) {
+            return (String) this.importColorMapping.get(colorNr);
+        } else {
+            return "0";
+        }
+    }
+
+    /**
+     * Imports a List value. The List number for the List defined
+     * is determined and then the resulting mapping is added.
+     */
+    public void importList(String origListNr, String newListNr) {
+        this.importListMapping.put(origListNr, newListNr);
+    }
+
+    /**
+     * Performs the mapping from the original list number to the actual
+     * list number in the resulting RTF document. If the list number was not
+     * seen during import (thus no mapping) then null is returned. There is no
+     * guarantee of a valid list number.
+     */
+    public String mapListNr(String listNr) {
+        if(this.importListMapping.containsKey(listNr)) {
+            return (String) this.importListMapping.get(listNr);
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Imports a stylesheet list value. The stylesheet number for the stylesheet defined
+     * is determined and then the resulting mapping is added.
+     */
+    public boolean importStylesheetList(String listNr, List listIn) {
+        RtfList rtfList = new RtfList(this.rtfDoc, listIn);
+        rtfList.setRtfDocument(this.rtfDoc);
+        // TODO HGS - Finish implementation of import
+        //this.importStylesheetListMapping.put(listNr, Integer.toString(this.rtfDoc.getDocumentHeader().getRtfParagraphStyle(styleName)(rtfList)));
+        return true;
+    }
+    /**
+     * Performs the mapping from the original stylesheet number to the actual
+     * stylesheet number in the resulting RTF document. If the stylesheet number was not
+     * seen during import (thus no mapping) then 0 is returned, guaranteeing
+     * that the stylesheet number is always valid.
+     */
+    public String mapStylesheetListNr(String listNr) {
+        if(this.importStylesheetListMapping.containsKey(listNr)) {
+            return (String) this.importStylesheetListMapping.get(listNr);
+        } else {
+            return "0";
+        }
+    }
+
+}
Index: src/core/com/lowagie/text/rtf/document/output/RtfMemoryCache.java
===================================================================
--- src/core/com/lowagie/text/rtf/document/output/RtfMemoryCache.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/document/output/RtfMemoryCache.java	(revision 0)
@@ -0,0 +1,92 @@
+/*
+ * $Id: RtfMemoryCache.java 3373 2008-05-12 16:21:24Z xlv $
+ *
+ * Copyright 2005 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.rtf.document.output;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * The RtfMemoryCache is an RtfDataCache that keeps the whole rtf document
+ * data in memory. Fast but memory intensive.
+ * 
+ * @version $Id: RtfMemoryCache.java 3373 2008-05-12 16:21:24Z xlv $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Thomas Bickel (tmb99@inode.at)
+ */
+public class RtfMemoryCache implements RtfDataCache {
+
+    /**
+     * The buffer for the rtf document data.
+     */
+    private ByteArrayOutputStream data = null;
+    
+    /**
+     * Constructs a RtfMemoryCache.
+     */
+    public RtfMemoryCache() {
+        this.data = new ByteArrayOutputStream();
+    }
+    
+    /**
+     * Gets the ByteArrayOutputStream.
+     */
+    public OutputStream getOutputStream() {
+        return this.data;
+    }
+
+    /**
+     * Writes the content of the ByteArrayOutputStream into the OutputStream.
+     */
+    public void writeTo(OutputStream target) throws IOException {
+        this.data.writeTo(target);
+    }
+
+}
Index: src/core/com/lowagie/text/rtf/style/RtfColorList.java
===================================================================
--- src/core/com/lowagie/text/rtf/style/RtfColorList.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/style/RtfColorList.java	(revision 0)
@@ -0,0 +1,139 @@
+/*
+ * $Id: RtfColorList.java 3580 2008-08-06 15:52:00Z howard_s $
+ *
+ * Copyright 2001, 2002, 2003, 2004 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.rtf.style;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+
+import com.lowagie.text.DocWriter;
+import com.lowagie.text.rtf.RtfElement;
+import com.lowagie.text.rtf.RtfExtendedElement;
+import com.lowagie.text.rtf.document.RtfDocument;
+
+
+/**
+ * The RtfColorList stores all colors that appear in the document. Black
+ * and White are always added
+ * 
+ * @version $Id: RtfColorList.java 3580 2008-08-06 15:52:00Z howard_s $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Thomas Bickel (tmb99@inode.at)
+ */
+public class RtfColorList extends RtfElement implements RtfExtendedElement {
+
+    /**
+     * Constant for the beginning of the color table
+     */
+    private static final byte[] COLOR_TABLE = DocWriter.getISOBytes("\\colortbl");
+    
+    /**
+     * ArrayList containing all colors of this RtfColorList
+     */
+    ArrayList colorList = new ArrayList();
+    
+    /**
+     * Constructs a new RtfColorList for the RtfDocument. Will add the default
+     * black and white colors.
+     * 
+     * @param doc The RtfDocument this RtfColorList belongs to
+     */
+    public RtfColorList(RtfDocument doc) {
+        super(doc);
+        colorList.add(new RtfColor(doc, 0, 0, 0, 0));
+        colorList.add(new RtfColor(doc, 255, 255, 255, 1));
+    }
+    
+    /**
+     * Returns the index of the given RtfColor in the color list. If the RtfColor
+     * is not in the list of colors, then it is added.
+     * 
+     * @param color The RtfColor for which to get the index
+     * @return The index of the RtfColor
+     */
+    public int getColorNumber(RtfColor color) {
+        int colorIndex = -1;
+        for(int i = 0; i < colorList.size(); i++) {
+            if(colorList.get(i).equals(color)) {
+                colorIndex = i;
+            }
+        }
+        if(colorIndex == -1) {
+            colorIndex = colorList.size();
+            colorList.add(color);
+        }
+        return colorIndex;
+    }
+    
+    /**
+     * unused
+     */
+    public void writeContent(final OutputStream out) throws IOException
+    {    	
+    }
+    
+    /**
+     * Write the definition part of the color list. Calls the writeDefinition
+     * methods of the RtfColors in the color list. 
+     */
+    public void writeDefinition(final OutputStream result) throws IOException
+    {
+        result.write(OPEN_GROUP);
+        result.write(COLOR_TABLE);
+        for(int i = 0; i < colorList.size(); i++) {
+            RtfColor color = (RtfColor) colorList.get(i);
+            color.writeDefinition(result);
+        }
+        result.write(CLOSE_GROUP);
+        this.document.outputDebugLinebreak(result);    	
+    }
+    
+
+}
Index: src/core/com/lowagie/text/rtf/document/output/RtfDataCache.java
===================================================================
--- src/core/com/lowagie/text/rtf/document/output/RtfDataCache.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/document/output/RtfDataCache.java	(revision 0)
@@ -0,0 +1,93 @@
+/*
+ * $Id: RtfDataCache.java 3373 2008-05-12 16:21:24Z xlv $
+ *
+ * Copyright 2005 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.rtf.document.output;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+
+/**
+ * The RtfDataCache interface must be implemented by classes wishing to
+ * act as caches for the rtf document data.
+ * 
+ * @version $Id: RtfDataCache.java 3373 2008-05-12 16:21:24Z xlv $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Thomas Bickel (tmb99@inode.at)
+ */
+public interface RtfDataCache 
+{
+    /**
+     * Constant for caching efficiently into memory.
+     */
+    public static final int CACHE_MEMORY_EFFICIENT = 3;
+    /**
+     * Constant for caching into memory.
+     */
+    public static final int CACHE_MEMORY = 2;
+    /**
+     * Constant for caching to the disk.
+     */
+    public static final int CACHE_DISK = 1;
+    
+    /**
+     * Get the OutputStream that the RtfDocument can write to.
+     * 
+     * @return The OutputStream the RtfDocument can use.
+     */
+    public OutputStream getOutputStream();
+    
+    /**
+     * Write the content of the cache into the OutputStream.
+     * 
+     * @param target The OutputStream to write the content into.
+     * @throws IOException If an error occurs reading/writing.
+     */
+    public void writeTo(OutputStream target) throws IOException;
+}
Index: src/core/com/lowagie/text/rtf/text/RtfChunk.java
===================================================================
--- src/core/com/lowagie/text/rtf/text/RtfChunk.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/text/RtfChunk.java	(revision 0)
@@ -0,0 +1,195 @@
+/*
+ * $Id: RtfChunk.java 3580 2008-08-06 15:52:00Z howard_s $
+ *
+ * Copyright 2001, 2002, 2003, 2004 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.rtf.text;
+
+import java.awt.Color;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import com.lowagie.text.Chunk;
+import com.lowagie.text.DocWriter;
+import com.lowagie.text.rtf.RtfElement;
+import com.lowagie.text.rtf.document.RtfDocument;
+import com.lowagie.text.rtf.style.RtfColor;
+import com.lowagie.text.rtf.style.RtfFont;
+
+
+/**
+ * The RtfChunk contains one piece of text. The smallest text element available
+ * in iText.
+ * 
+ * @version $Id: RtfChunk.java 3580 2008-08-06 15:52:00Z howard_s $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Thomas Bickel (tmb99@inode.at)
+ */
+public class RtfChunk extends RtfElement {
+
+    /**
+     * Constant for the subscript flag
+     */
+    private static final byte[] FONT_SUBSCRIPT = DocWriter.getISOBytes("\\sub");
+    /**
+     * Constant for the superscript flag
+     */
+    private static final byte[] FONT_SUPERSCRIPT = DocWriter.getISOBytes("\\super");
+    /**
+     * Constant for the end of sub / superscript flag
+     */
+    private static final byte[] FONT_END_SUPER_SUBSCRIPT = DocWriter.getISOBytes("\\nosupersub");
+    /**
+     * Constant for background color.
+     */
+    private static final byte[] BACKGROUND_COLOR = DocWriter.getISOBytes("\\chcbpat");
+
+    /**
+     * The font of this RtfChunk
+     */
+    private RtfFont font = null;
+    /**
+     * The actual content of this RtfChunk
+     */
+    private String content = "";
+    /**
+     * Whether to use soft line breaks instead of hard ones.
+     */
+    private boolean softLineBreaks = false;
+    /**
+     * The super / subscript of this RtfChunk
+     */
+    private float superSubScript = 0;
+    /**
+     * An optional background color.
+     */
+    private RtfColor background = null;
+
+    /**
+     * Constructs a RtfChunk based on the content of a Chunk
+     * 
+     * @param doc The RtfDocument that this Chunk belongs to
+     * @param chunk The Chunk that this RtfChunk is based on
+     */
+    public RtfChunk(RtfDocument doc, Chunk chunk) {
+        super(doc);
+        
+        if(chunk == null) {
+            return;
+        }
+        
+        if(chunk.getAttributes() != null && chunk.getAttributes().get(Chunk.SUBSUPSCRIPT) != null) {
+            this.superSubScript = ((Float)chunk.getAttributes().get(Chunk.SUBSUPSCRIPT)).floatValue();
+        }
+        if(chunk.getAttributes() != null && chunk.getAttributes().get(Chunk.BACKGROUND) != null) {
+            this.background = new RtfColor(this.document, (Color) ((Object[]) chunk.getAttributes().get(Chunk.BACKGROUND))[0]);
+        }
+        font = new RtfFont(doc, chunk.getFont());
+        content = chunk.getContent();
+    }
+    
+    /**
+     * Writes the content of this RtfChunk. First the font information
+     * is written, then the content, and then more font information
+     */ 
+    public void writeContent(final OutputStream result) throws IOException
+    {
+        if(this.background != null) {
+            result.write(OPEN_GROUP);
+        }
+        
+        this.font.writeBegin(result);
+        if(superSubScript < 0) {
+            result.write(FONT_SUBSCRIPT);
+        } else if(superSubScript > 0) {
+            result.write(FONT_SUPERSCRIPT);
+        }
+        if(this.background != null) {
+            result.write(BACKGROUND_COLOR);
+            result.write(intToByteArray(this.background.getColorNumber()));
+        }
+        result.write(DELIMITER);
+        document.filterSpecialChar(result, content, false, softLineBreaks || this.document.getDocumentSettings().isAlwaysGenerateSoftLinebreaks());
+        
+        if(superSubScript != 0) {
+            result.write(FONT_END_SUPER_SUBSCRIPT);
+        }
+        this.font.writeEnd(result);
+        
+        if(this.background != null) {
+            result.write(CLOSE_GROUP);
+        }    	
+    }
+    
+    /**
+     * Sets the RtfDocument this RtfChunk belongs to.
+     * 
+     * @param doc The RtfDocument to use
+     */
+    public void setRtfDocument(RtfDocument doc) {
+        super.setRtfDocument(doc);
+        this.font.setRtfDocument(this.document);
+    }
+    
+    /**
+     * Sets whether to use soft line breaks instead of default hard ones.
+     * 
+     * @param softLineBreaks whether to use soft line breaks instead of default hard ones.
+     */
+    public void setSoftLineBreaks(boolean softLineBreaks) {
+        this.softLineBreaks = softLineBreaks;
+    }
+    
+    /**
+     * Gets whether to use soft line breaks instead of default hard ones.
+     * 
+     * @return whether to use soft line breaks instead of default hard ones.
+     */
+    public boolean getSoftLineBreaks() {
+        return this.softLineBreaks;
+    }
+}
Index: src/core/com/lowagie/text/rtf/parser/ctrlwords/RtfCtrlWordHandler.java
===================================================================
--- src/core/com/lowagie/text/rtf/parser/ctrlwords/RtfCtrlWordHandler.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/parser/ctrlwords/RtfCtrlWordHandler.java	(revision 0)
@@ -0,0 +1,360 @@
+/* $Id: RtfCtrlWordHandler.java 3427 2008-05-24 18:32:31Z xlv $
+ *
+ * Copyright 2007 by Howard Shank (hgshank@yahoo.com)
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+package com.lowagie.text.rtf.parser.ctrlwords; 
+
+import com.lowagie.text.rtf.parser.RtfParser;
+import com.lowagie.text.rtf.parser.destinations.RtfDestination;
+import com.lowagie.text.rtf.parser.destinations.RtfDestinationMgr;
+
+/**
+ * <code>RtfCtrlWordBase</code> is the base class for all
+ * control word handlers to extend from.
+ * 
+ * @author Howard Shank (hgshank@yahoo.com)
+ * @since 2.0.8
+ */
+public class RtfCtrlWordHandler implements Cloneable {
+	/**
+	 * Debug flag - internal use
+	 * @since 2.0.8
+	 */
+	private static final boolean debug = false;
+
+	/**
+	 * Local variable referencing the parser object. 
+	 * @since 2.0.8
+	 */
+	protected RtfParser rtfParser = null;
+	/**
+	 * The control word for this class.
+	 * @since 2.0.8
+	 */
+	protected String ctrlWord = "";
+	/**
+	 * The default value for this control word.
+	 * Not all control words use a default parameter value.
+	 * @since 2.0.8
+	 */
+	protected int defaultParameterValue = 0;
+	/**
+	 * Does this control word use the default value?
+	 * @since 2.0.8
+	 */
+	protected boolean passDefaultParameterValue = false;
+	/**
+	 * Control Word type. Destination, toggle, value, etc.
+	 * @since 2.0.8
+	 */
+	protected int ctrlWordType = RtfCtrlWordType.UNIDENTIFIED;
+	/**
+	 * Class, property, etc.
+	 * @since 2.0.8
+	 */
+	protected String specialHandler = "";
+	/**
+	 * What version of the RTF spec the control word was introduced.
+	 * @since 2.0.8
+	 */
+	protected float rtfVersionSupported = -1.0f;	// -1.0 unknown. Each class should override this as implemented.
+	/**
+	 * The control word as parsed by the parser.
+	 * @since 2.0.8
+	 */
+	protected RtfCtrlWordData ctrlWordData = null;
+	/**
+	 * String containing the value of "{" or "" (blank) depending on if this is the
+	 * first control word in a group.
+	 * @since 2.0.8
+	 */
+	protected String groupPrefix = "";
+	/**
+	 * The prefix for all control words.
+	 * @since 2.0.8
+	 */
+	protected String ctrlWordPrefix = "\\";
+	/**
+	 * The prefix for all control words.
+	 * @since 2.0.8
+	 */
+	protected String ctrlWordSuffix = " ";
+	/**
+	 * Hidden default constructor. Must use constructor with parameters.
+	 * @see com.lowagie.text.rtf.parser.ctrlwords.RtfCtrlWordHandler#RtfCtrlWordHandler(RtfParser rtfParser, String ctrlWord, int defaultParameterValue, boolean passDefaultParameterValue, int ctrlWordType, String prefix, String suffix, String specialHandler)
+	 * @since 2.0.8
+	 */
+	private RtfCtrlWordHandler(){};
+	
+	/**
+	 * Constructor:
+	 *
+	 * @param rtfParser
+	 * 		The parser for this control word.
+	 * @param ctrlWord
+	 * 		The string value of this control word.
+	 * @param defaultParameterValue
+	 * 		The default value of this control word. Not all control words have values.
+	 * @param passDefaultParameterValue
+	 * 		Flag indicating if this control word should use the default value.
+	 * @param ctrlWordType
+	 * 		Indicator of the type of control word this is. DESTINATION|DESTINATION_EX|VALUE|FLAG|TOGGLE|SYMBOL
+	 * @param prefix
+	 * 		String to prefix the ctrl word with. "\" or "\*\" are the 2 used values.
+	 * @param suffix
+	 * 		String to add as suffix to the ctrl word. " " and "" are the 2 used values.
+	 * @param specialHandler
+	 * 		If TOGGLE then the property name as String (propertyGroup.propertyName format ex. "character.bold")
+	 * 		If FLAG then the property name as String (propertyGroup.propertyName format ex. "character.bold")
+	 * 		If VALUE then the property name as String (propertyGroup.propertyName format ex. "character.bold")
+	 * 		If SYMBOL then the character to use for substitution as String
+	 * 		If DESTINATION|DESTINATION_EX then the RtfDestination class name as String
+	 * 
+	 * @since 2.0.8
+	 */
+	public RtfCtrlWordHandler(RtfParser rtfParser, String ctrlWord, int defaultParameterValue, boolean passDefaultParameterValue, 
+			int ctrlWordType, String prefix, String suffix, String specialHandler) {
+		super();
+		this.rtfParser = rtfParser;
+		this.ctrlWord = ctrlWord;
+		this.defaultParameterValue = defaultParameterValue;
+		this.passDefaultParameterValue = passDefaultParameterValue;
+		this.ctrlWordType = ctrlWordType;
+		this.ctrlWordPrefix = prefix;
+		this.ctrlWordSuffix = suffix;
+		this.specialHandler = specialHandler;
+
+		if(this.ctrlWordType == RtfCtrlWordType.DESTINATION || this.ctrlWordType == RtfCtrlWordType.DESTINATION_EX){
+			if(this.specialHandler == null) {
+				this.specialHandler = "RtfDestinationNull";
+			}
+			String arg1 = ""; // stylesheet value - S, CS, TS
+			RtfDestinationMgr.addDestination(this.ctrlWord, new Object[] { this.specialHandler, arg1 });			
+		} else {
+			if(this.ctrlWordType == RtfCtrlWordType.SYMBOL){
+				
+			} else {
+				if(this.specialHandler == null) {
+					this.specialHandler = this.ctrlWord;	// if null, make the property the name of the ctrl word
+				} else {
+					if(this.specialHandler.length() > 1 && this.specialHandler.endsWith(".")) {
+						this.specialHandler += this.ctrlWord;	// if string length>1 and ends with a period, it's a group. Add ctrlWord
+					}
+				}
+			}
+		}
+	}
+	
+	/**
+	 * The primary control word handler method.
+	 * Called by the parser once it has a control word and parameter if applicable.
+	 * 
+	 * @param ctrlWordDataIn
+	 * 		The control word and associated parameter if applicable.
+	 * @return
+	 * 		<code>true</code> or <code>false</code> if the control word was handled.
+	 * @since 2.0.8
+	 */
+	public final boolean handleControlword(RtfCtrlWordData ctrlWordDataIn){
+		boolean result = false;
+		this.ctrlWordData = ctrlWordDataIn;
+		RtfDestination dest = null;
+		boolean handled = false;
+		
+		this.ctrlWordData.prefix  = this.ctrlWordPrefix;
+		this.ctrlWordData.suffix  = this.ctrlWordSuffix;
+		this.ctrlWordData.newGroup = this.rtfParser.getState().newGroup;
+		this.ctrlWordData.ctrlWordType = this.ctrlWordType;
+		this.ctrlWordData.specialHandler = this.specialHandler;
+		
+		if(!this.ctrlWordData.hasParam && this.passDefaultParameterValue) {
+			this.ctrlWordData.hasParam = true;
+			this.ctrlWordData.param = Integer.toString(this.defaultParameterValue);
+		}
+
+		if(debug) {
+			printDebug("handleKeyword: [" + this.ctrlWordData.ctrlWord + "] param=" + ctrlWordDataIn.param);
+			RtfParser.outputDebug(this.rtfParser.getRtfDocument(), this.rtfParser.getLevel()+1, "RtfCtrlWordHandler debug Start: " + this.ctrlWordData.ctrlWord + " ");
+		}
+		if(this.ctrlWordData.ctrlWord.equals("*")) {
+			return true;
+		}
+		
+		if(!beforeControlWord()) {
+			return true;
+		}
+		
+		switch(this.ctrlWordType) {
+		case RtfCtrlWordType.FLAG:
+		case RtfCtrlWordType.TOGGLE:
+		case RtfCtrlWordType.VALUE:
+			dest = this.rtfParser.getCurrentDestination();
+			if(dest != null) {
+				handled = dest.handleControlWord(this.ctrlWordData);
+			}
+			break;
+		
+		case RtfCtrlWordType.SYMBOL:
+			dest = this.rtfParser.getCurrentDestination();
+			if(dest != null) {
+				String data = null;
+				// if doing an import, then put the control word in the output stream through the character handler
+				if(this.rtfParser.isImport()) {
+					data = this.ctrlWordPrefix + this.ctrlWordData.ctrlWord + this.ctrlWordSuffix;
+				}
+				if(this.rtfParser.isConvert()) {
+					data = this.specialHandler;
+				}
+				
+				// If there is a substitute character, process the character.
+				// If no substitute character, then provide special handling in the destination for the ctrl word. 
+				if(data != null) {
+					for(int idx=0; idx< data.length(); idx++) {
+						handled = dest.handleCharacter(data.charAt(idx));
+					}
+				} else {
+					handled = dest.handleControlWord(this.ctrlWordData);
+				}
+			}
+			break;
+
+		case RtfCtrlWordType.DESTINATION_EX:
+		case RtfCtrlWordType.DESTINATION:
+			// set the destination
+			int x=0;
+			if("shppict".equals(this.ctrlWord) || "nonshppict".equals(this.ctrlWord)) {
+				x++;
+			}
+			handled = this.rtfParser.setCurrentDestination(this.ctrlWord);
+			// let destination handle the ctrl word now.
+			dest = this.rtfParser.getCurrentDestination();
+			if(dest != null) {
+				if(dest.getNewTokeniserState() == RtfParser.TOKENISER_IGNORE_RESULT) {
+					handled = dest.handleControlWord(this.ctrlWordData);
+				}
+				else {
+					this.rtfParser.setTokeniserState(dest.getNewTokeniserState());
+				}
+			}
+
+			break;
+		}
+
+		afterControlWord();
+		
+		if(debug) {
+			RtfParser.outputDebug(this.rtfParser.getRtfDocument(), this.rtfParser.getLevel()+1, "RtfCtrlWordHandler debug End: " + this.ctrlWordData.ctrlWord + " ");
+		}
+
+		return result;
+	}
+	
+	/**
+	 * Pre-processing before the control word.
+	 * 
+	 * If return value is true, no further processing will be performed on
+	 * this control word.
+	 * 
+	 * @return <code>false</code> = stop processing, <code>true</code> = continue processing 
+	 * @since 2.0.8
+	 */
+	//Primary purpose is for \* control word and event handling.
+	protected boolean beforeControlWord() {
+		if(debug) printDebug("beforeControlWord");
+		// TODO: This is where events would be triggered
+		return true;
+	}
+	/**
+	 * Handle the control word.
+	 * 
+	 * @return <code>true</code> if control word was handled, <code>false</code> if it was not handled.
+	 * @since 2.0.8
+	 */
+	protected boolean onControlWord() {
+		if(debug) printDebug("onCtrlWord");
+		// TODO: This is where events would be triggered
+		return false;
+	}
+	/**
+	 * Post-processing after the control word.
+	 * 
+	 * @return <code>false</code> = stop processing, <code>true</code> = continue processing
+	 * @since 2.0.8
+	 */
+	protected boolean afterControlWord() {
+		if(debug) printDebug("afterControlWord");
+		// TODO: This is where events would be triggered
+		return true;
+	}
+	
+//	public String ctrlWordString() {
+//		//String out = ctrlWordPrefix + this.ctrlWord;
+//		String out = "";
+//		if(this.bExtendedDestination) {
+//			out += "\\*";
+//		}
+//		out = ctrlWordPrefix + this.ctrlWordData.ctrlWord;
+//		if(this.ctrlWordData.hasParam) {
+//			if(this.ctrlWordData.isNeg) out += "-";
+//			out += this.ctrlWordData.param;
+//		} else {
+//			if(this.passDefaultParameterValue == true) {
+//				out += Integer.toString(this.defaultParameterValue);
+//			} 
+//		}
+//		out += this.ctrlWordSuffix;
+//		return out;
+//	}
+	
+	/**
+	 * Debug function to print class/method
+	 * @param txt The <code>String</code> to output.
+	 * @since 2.0.8
+	 */
+	private final void printDebug(final String txt) {
+		 System.out.println(this.getClass().getName() + " : " + txt);
+	}
+}
Index: src/core/com/lowagie/text/rtf/parser/destinations/RtfDestinationDocument.java
===================================================================
--- src/core/com/lowagie/text/rtf/parser/destinations/RtfDestinationDocument.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/parser/destinations/RtfDestinationDocument.java	(revision 0)
@@ -0,0 +1,614 @@
+/*
+ * $Id: RtfDestinationDocument.java 3456 2008-05-26 15:26:57Z howard_s $
+ *
+ * Copyright 2007 by Howard Shank (hgshank@yahoo.com)
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+package com.lowagie.text.rtf.parser.destinations;
+
+import java.awt.Color;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+
+import com.lowagie.text.Chunk;
+import com.lowagie.text.Document;
+import com.lowagie.text.DocumentException;
+import com.lowagie.text.Font;
+import com.lowagie.text.FontFactory;
+import com.lowagie.text.Paragraph;
+import com.lowagie.text.rtf.direct.RtfDirectContent;
+import com.lowagie.text.rtf.document.*;
+import com.lowagie.text.rtf.parser.RtfParser;
+import com.lowagie.text.rtf.parser.ctrlwords.RtfCtrlWordData;
+import com.lowagie.text.rtf.parser.ctrlwords.RtfCtrlWordType;
+import com.lowagie.text.rtf.parser.properties.RtfProperty;
+import com.lowagie.text.rtf.parser.properties.RtfPropertyListener;
+/**
+ * <code>RtfDestinationDocument</code> handles data destined for the document destination
+ * 
+ * @author Howard Shank (hgshank@yahoo.com)
+ * @since 2.1.0
+ */
+public final class RtfDestinationDocument extends RtfDestination implements RtfPropertyListener {
+
+
+	/**
+	 * The RtfDocument object.
+	 * 
+	 * @see com.lowagie.text.rtf.document.RtfDocument
+	 */
+	private RtfDocument rtfDoc = null;
+	
+	/**
+	 * The iText Document object.
+	 * 
+	 * @see com.lowagie.text.Document
+	 */
+	private Document doc = null;
+	
+	private StringBuffer buffer = null;
+	/**
+	 * Indicates the parser action. Import or Conversion.
+	 * 
+	 * @see com.lowagie.text.rtf.parser.RtfParser#TYPE_UNIDENTIFIED
+	 * @see com.lowagie.text.rtf.parser.RtfParser#TYPE_CONVERT
+	 * @see com.lowagie.text.rtf.parser.RtfParser#TYPE_IMPORT_FRAGMENT
+	 * @see com.lowagie.text.rtf.parser.RtfParser#TYPE_IMPORT_FULL
+	 */
+	private int conversionType = 0;
+	
+	
+	/**
+	 * Indicates the current table level being processed
+	 */
+	private int tableLevel = 0;
+	
+	private static final List IMPORT_IGNORED_CTRLWORDS = Arrays.asList(new String[]{
+		"rtf",
+		"ansicpg",
+		"deff",
+		"ansi",
+		"mac",
+		"pca",
+		"pc",
+		"stshfdbch",
+		"stshfloch",
+		"stshfhich",
+		"stshfbi",
+		"deflang",
+		"deflangfe",
+		"adeflang",
+		"adeflangfe"});
+
+	private static final List CONVERT_IGNORED_CTRLWORDS = Arrays.asList(new String[]{"rtf"});
+
+	private Paragraph iTextParagraph = null;
+	
+	public RtfDestinationDocument() {
+		super(null);
+	}
+	/**
+	 * Constructs a new <code>RtfDestinationDocument</code> using
+	 * the parameters to initialize the object.
+	 * @param parser an RtfParser.
+	 */
+	public RtfDestinationDocument(RtfParser parser) {
+		super(parser);
+		this.rtfDoc = parser.getRtfDocument();
+		this.doc = parser.getDocument();
+		this.conversionType = parser.getConversionType();
+		setToDefaults();
+		if(this.rtfParser.isConvert()) {
+			this.rtfParser.getState().properties.addRtfPropertyListener(this);
+		}
+	}
+	
+	
+	/* (non-Javadoc)
+	 * @see java.lang.Object#finalize()
+	 */
+	protected void finalize() throws Throwable {
+		// TODO Auto-generated method stub
+		if(this.rtfParser.isConvert()) {
+			this.rtfParser.getState().properties.removeRtfPropertyListener(this);
+		}
+		super.finalize();
+	}
+
+	public void setParser(RtfParser parser) {
+		this.rtfParser = parser;
+		this.rtfDoc = parser.getRtfDocument();
+		this.doc = parser.getDocument();
+		this.conversionType = parser.getConversionType();
+		setToDefaults();
+		if(this.rtfParser.isConvert()) {
+			this.rtfParser.getState().properties.addRtfPropertyListener(this);
+		}
+	}
+	
+
+	/* (non-Javadoc)
+	 * @see com.lowagie.text.rtf.direct.RtfDestination#closeDestination()
+	 */
+	public boolean closeDestination() {
+		if(this.rtfParser.isImport()) {
+			if(this.buffer.length()>0) {
+				writeBuffer();
+			}
+		}
+		
+		this.rtfParser.getState().properties.removeRtfPropertyListener(this);
+
+		return true;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.lowagie.text.rtf.direct.RtfDestination#handleGroupStart()
+	 */
+	public boolean handleOpenGroup() {
+		this.onOpenGroup();	// event handler
+		
+		if(this.rtfParser.isImport()) {
+		}
+		if(this.rtfParser.isConvert()) {
+			if(this.iTextParagraph == null) this.iTextParagraph = new Paragraph();
+		}
+		return true;
+	}
+	/* (non-Javadoc)
+	 * @see com.lowagie.text.rtf.parser.destinations.RtfDestination#handleOpenNewGroup()
+	 */
+	public boolean handleOpeningSubGroup() {
+		if(this.rtfParser.isImport()) {
+			if(this.buffer.length()>0) {
+				writeBuffer();
+			}
+		}
+		return true;
+	}
+	/* (non-Javadoc)
+	 * @see com.lowagie.text.rtf.direct.RtfDestination#handleGroupEnd()
+	 */
+	public boolean handleCloseGroup() {
+		this.onCloseGroup();	// event handler
+		
+		if(this.rtfParser.isImport()) {
+			if(this.buffer.length()>0) {
+				writeBuffer();
+			}
+			writeText("}");
+		}
+		if(this.rtfParser.isConvert()) {
+			if(this.buffer.length() > 0 && this.iTextParagraph == null) {
+				this.iTextParagraph = new Paragraph();
+			}
+			if(this.buffer.length() > 0 ) {
+				Chunk chunk = new Chunk();
+				chunk.append(this.buffer.toString());
+				this.iTextParagraph.add(chunk);
+			}
+			if(this.iTextParagraph != null) {
+				addParagraphToDocument();
+			}
+		}
+		return true;
+	}
+	/* (non-Javadoc)
+	 * @see com.lowagie.text.rtf.direct.RtfDestination#handleCharacter(int)
+	 */
+	public boolean handleCharacter(int ch) {
+		boolean result = true;
+		this.onCharacter(ch);	// event handler
+		
+		if(this.rtfParser.isImport()) {
+			if(buffer.length() > 254) {
+				this.writeBuffer();
+			}
+			buffer.append((char)ch);
+		}
+		if(this.rtfParser.isConvert()) {
+			buffer.append((char)ch);
+		}
+		return result;
+	}
+
+	
+	public boolean handleControlWord(RtfCtrlWordData ctrlWordData) {
+		boolean result = false;
+		this.onCtrlWord(ctrlWordData);	// event handler
+		
+		if(this.rtfParser.isImport()) {
+			// map font information
+			if(ctrlWordData.ctrlWord.equals("f")) { ctrlWordData.param =  this.rtfParser.getImportManager().mapFontNr(ctrlWordData.param);}
+			
+			// map color information
+			//colors
+			if(ctrlWordData.ctrlWord.equals("cb")) { ctrlWordData.param = this.rtfParser.getImportManager().mapColorNr(ctrlWordData.param);}
+			if(ctrlWordData.ctrlWord.equals("cf")) { ctrlWordData.param = this.rtfParser.getImportManager().mapColorNr(ctrlWordData.param);}
+			//cells
+			if(ctrlWordData.ctrlWord.equals("clcbpat")) { ctrlWordData.param = this.rtfParser.getImportManager().mapColorNr(ctrlWordData.param);}
+			if(ctrlWordData.ctrlWord.equals("clcbpatraw")) { ctrlWordData.param = this.rtfParser.getImportManager().mapColorNr(ctrlWordData.param);}
+			if(ctrlWordData.ctrlWord.equals("clcfpat")) { ctrlWordData.param = this.rtfParser.getImportManager().mapColorNr(ctrlWordData.param);}
+			if(ctrlWordData.ctrlWord.equals("clcfpatraw")) { ctrlWordData.param = this.rtfParser.getImportManager().mapColorNr(ctrlWordData.param);}
+			//table rows
+			if(ctrlWordData.ctrlWord.equals("trcfpat")) { ctrlWordData.param = this.rtfParser.getImportManager().mapColorNr(ctrlWordData.param);}
+			if(ctrlWordData.ctrlWord.equals("trcbpat")) { ctrlWordData.param = this.rtfParser.getImportManager().mapColorNr(ctrlWordData.param);}
+			//paragraph border
+			if(ctrlWordData.ctrlWord.equals("brdrcf")) { ctrlWordData.param = this.rtfParser.getImportManager().mapColorNr(ctrlWordData.param);}
+			// map lists
+			if(ctrlWordData.ctrlWord.equals("ls")) { ctrlWordData.param = this.rtfParser.getImportManager().mapListNr(ctrlWordData.param);}
+		}
+		
+
+		
+		if(this.rtfParser.isConvert()) {
+			if(ctrlWordData.ctrlWord.equals("par")) { addParagraphToDocument(); }
+			// Set Font
+			if(ctrlWordData.ctrlWord.equals("f")) {}
+			
+			// color information
+			//colors
+			if(ctrlWordData.ctrlWord.equals("cb")) {}
+			if(ctrlWordData.ctrlWord.equals("cf")) {}
+			//cells
+			if(ctrlWordData.ctrlWord.equals("clcbpat")) {}
+			if(ctrlWordData.ctrlWord.equals("clcbpatraw")) {}
+			if(ctrlWordData.ctrlWord.equals("clcfpat")) {}
+			if(ctrlWordData.ctrlWord.equals("clcfpatraw")) {}
+			//table rows
+			if(ctrlWordData.ctrlWord.equals("trcfpat")) {}
+			if(ctrlWordData.ctrlWord.equals("trcbpat")) {}
+			//paragraph border
+			if(ctrlWordData.ctrlWord.equals("brdrcf")) {}
+			
+			/* TABLES */
+			if(ctrlWordData.ctrlWord.equals("trowd")) /*Beginning of row*/ { tableLevel++;}
+			if(ctrlWordData.ctrlWord.equals("cell")) /*End of Cell Denotes the end of a table cell*/ {
+//				String ctl = ctrlWordData.ctrlWord;
+//				System.out.print("cell found");
+			}
+			if(ctrlWordData.ctrlWord.equals("row")) /*End of row*/ { tableLevel++;}
+			if(ctrlWordData.ctrlWord.equals("lastrow")) /*Last row of the table*/ {}
+			if(ctrlWordData.ctrlWord.equals("row")) /*End of row*/ { tableLevel++;}
+			if(ctrlWordData.ctrlWord.equals("irow")) /*param  is the row index of this row.*/ {}
+			if(ctrlWordData.ctrlWord.equals("irowband")) /*param is the row index of the row, adjusted to account for header rows. A header row has a value of -1.*/ {}
+			if(ctrlWordData.ctrlWord.equals("tcelld")) /*Sets table cell defaults*/ {}
+			if(ctrlWordData.ctrlWord.equals("nestcell")) /*Denotes the end of a nested cell.*/ {}
+			if(ctrlWordData.ctrlWord.equals("nestrow")) /*Denotes the end of a nested row*/ {}
+			if(ctrlWordData.ctrlWord.equals("nesttableprops")) /*Defines the properties of a nested table. This is a destination control word*/ {}
+			if(ctrlWordData.ctrlWord.equals("nonesttables")) /*Contains text for readers that do not understand nested tables. This destination should be ignored by readers that support nested tables.*/ {}
+			if(ctrlWordData.ctrlWord.equals("trgaph")) /*Half the space between the cells of a table row in twips.*/ {}
+			if(ctrlWordData.ctrlWord.equals("cellx")) /*param Defines the right boundary of a table cell, including its half of the space between cells.*/ {}
+			if(ctrlWordData.ctrlWord.equals("clmgf")) /*The first cell in a range of table cells to be merged.*/ {}
+			if(ctrlWordData.ctrlWord.equals("clmrg")) /*Contents of the table cell are merged with those of the preceding cell*/ {}
+			if(ctrlWordData.ctrlWord.equals("clvmgf")) /*The first cell in a range of table cells to be vertically merged.*/ {}
+			if(ctrlWordData.ctrlWord.equals("clvmrg")) /*Contents of the table cell are vertically merged with those of the preceding cell*/ {}
+			/* TABLE: table row revision tracking */
+			if(ctrlWordData.ctrlWord.equals("trauth")) /*With revision tracking enabled, this control word identifies the author of changes to a table row's properties. N refers to a value in the revision table*/ {}
+			if(ctrlWordData.ctrlWord.equals("trdate")) /*With revision tracking enabled, this control word identifies the date of a revision*/ {}
+			/* TABLE: Autoformatting flags */
+			if(ctrlWordData.ctrlWord.equals("tbllkborder")) /*Flag sets table autoformat to format borders*/ {}
+			if(ctrlWordData.ctrlWord.equals("tbllkshading")) /*Flag sets table autoformat to affect shading.*/ {}
+			if(ctrlWordData.ctrlWord.equals("tbllkfont")) /*Flag sets table autoformat to affect font*/ {}
+			if(ctrlWordData.ctrlWord.equals("tbllkcolor")) /*Flag sets table autoformat to affect color*/ {}
+			if(ctrlWordData.ctrlWord.equals("tbllkbestfit")) /*Flag sets table autoformat to apply best fit*/ {}
+			if(ctrlWordData.ctrlWord.equals("tbllkhdrrows")) /*Flag sets table autoformat to format the first (header) row*/ {}
+			if(ctrlWordData.ctrlWord.equals("tbllklastrow")) /*Flag sets table autoformat to format the last row.*/ {}
+			if(ctrlWordData.ctrlWord.equals("tbllkhdrcols")) /*Flag sets table autoformat to format the first (header) column*/ {}
+			if(ctrlWordData.ctrlWord.equals("tbllklastcol")) /*Flag sets table autoformat to format the last column*/ {}
+			if(ctrlWordData.ctrlWord.equals("tbllknorowband")) /*Specifies row banding conditional formatting shall not be applied*/ {}
+			if(ctrlWordData.ctrlWord.equals("tbllknocolband")) /*Specifies column banding conditional formatting shall not be applied.*/ {}
+			/* TABLE: Row Formatting */
+			if(ctrlWordData.ctrlWord.equals("taprtl")) /*Table direction is right to left*/ {}
+			if(ctrlWordData.ctrlWord.equals("trautofit")) /*param = AutoFit:
+0	No AutoFit (default).
+1	AutoFit is on for the row. Overridden by \clwWidthN and \trwWidthN in any table row.
+*/ {}
+			if(ctrlWordData.ctrlWord.equals("trhdr")) /*Table row header. This row should appear at the top of every page on which the current table appears*/ {}
+			if(ctrlWordData.ctrlWord.equals("trkeep")) /*Keep table row together. This row cannot be split by a page break. This property is assumed to be off unless the control word is present*/ {}
+			if(ctrlWordData.ctrlWord.equals("trkeepfollow")) /*Keep row in the same page as the following row.*/ {}
+			if(ctrlWordData.ctrlWord.equals("trleft")) /*Position in twips of the leftmost edge of the table with respect to the left edge of its column.*/ {}
+			if(ctrlWordData.ctrlWord.equals("trqc")) /*Centers a table row with respect to its containing column.*/ {}
+			if(ctrlWordData.ctrlWord.equals("trql")) /*Left-justifies a table row with respect to its containing column.*/ {}
+			if(ctrlWordData.ctrlWord.equals("trqr")) /*Right-justifies a table row with respect to its containing column*/ {}
+			if(ctrlWordData.ctrlWord.equals("trrh")) /*Height of a table row in twips. When 0, the height is sufficient for all the text in the line; when positive, the height is guaranteed to be at least the specified height; when negative, the absolute value of the height is used, regardless of the height of the text in the line*/ {}
+			if(ctrlWordData.ctrlWord.equals("trpaddb")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("trpaddl")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("trpaddr")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("trpaddt")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("trpaddfb")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("trpaddfl")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("trpaddfr")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("trpaddft")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("trspdl")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("trspdt")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("trspdb")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("trspdr")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("trspdfl")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("trspdft")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("trspdfb")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("trspdfr")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("trwWidth")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("trftsWidth")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("trwWidthB")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("trftsWidthB")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("trftsWidthB")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("trwWidthA")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("trftsWidthA")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("tblind")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("tblindtype")) /**/ {}
+			/*TABLE: Row shading and Background COlors*/
+			if(ctrlWordData.ctrlWord.equals("trcbpat")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("trcfpat")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("trpat")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("trshdng")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("trbgbdiag")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("trbgcross")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("trbgdcross")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("trbgdkbdiag")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("trbgdkcross")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("trbgdkdcross")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("trbgdkfdiag")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("trbgdkhor")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("trbgdkvert")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("trbgfdiag")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("trbghoriz")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("trbgvert")) /**/ {}
+			/* TABLE: Cell Formatting*/
+			if(ctrlWordData.ctrlWord.equals("clFitText")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("clNoWrap")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("clpadl")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("clpadt")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("clpadb")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("clpadr")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("clpadfl")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("clpadft")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("clpadfb")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("clpadfr")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("clwWidth")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("clftsWidth")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("clhidemark")) /**/ {}
+			/* TABLE: Compared Table Cells */
+			if(ctrlWordData.ctrlWord.equals("clins")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("cldel")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("clmrgd")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("clmrgdr")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("clsplit")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("clsplitr")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("clinsauth")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("clinsdttm")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("cldelauth")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("cldeldttm")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("clmrgdauth")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("clmrgddttm")) /**/ {}
+			/*TABLE: Position Wrapped Tables (The following properties must be the same for all rows in the table.)*/
+			if(ctrlWordData.ctrlWord.equals("tdfrmtxtLeft")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("tdfrmtxtRight")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("tdfrmtxtTop")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("tdfrmtxtBottom")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("tabsnoovrlp")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("tphcol")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("tphmrg")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("tphpg")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("tposnegx")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("tposnegy")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("tposx")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("tposxc")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("tposxi")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("tposxl")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("tposxo")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("tposxr")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("tposy")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("tposyb")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("tposyc")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("tposyil")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("tposyin")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("tposyout")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("tposyt")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("tpvmrg")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("tpvpara")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("tpvpg")) /**/ {}
+			/* TABLE: Bidirectional Controls */
+			if(ctrlWordData.ctrlWord.equals("rtlrow")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("ltrrow")) /**/ {}
+			/* TABLE: Row Borders */
+			if(ctrlWordData.ctrlWord.equals("trbrdrt")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("trbrdrl")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("trbrdrb")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("trbrdrr")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("trbrdrh")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("trbrdrv")) /**/ {}
+			/* TABLE: Cell Borders */
+			if(ctrlWordData.ctrlWord.equals("brdrnil")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("clbrdrb")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("clbrdrt")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("clbrdrl")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("clbrdrr")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("cldglu")) /**/ {}
+			if(ctrlWordData.ctrlWord.equals("cldgll")) /**/ {}
+		}
+		if(ctrlWordData.ctrlWordType == RtfCtrlWordType.TOGGLE) {
+			this.rtfParser.getState().properties.toggleProperty(ctrlWordData);//ctrlWordData.specialHandler);
+		}
+		
+		if(ctrlWordData.ctrlWordType == RtfCtrlWordType.FLAG || 
+				ctrlWordData.ctrlWordType == RtfCtrlWordType.VALUE) {
+			this.rtfParser.getState().properties.setProperty(ctrlWordData);//ctrlWordData.specialHandler, ctrlWordData.param);
+		}
+		
+		switch(conversionType) {
+		case RtfParser.TYPE_IMPORT_FULL:
+			if(!IMPORT_IGNORED_CTRLWORDS.contains(ctrlWordData.ctrlWord)) {
+				writeBuffer();
+				writeText(ctrlWordData.toString());
+			}
+			result = true;
+			break;		
+		case RtfParser.TYPE_IMPORT_FRAGMENT:
+			if(!IMPORT_IGNORED_CTRLWORDS.contains(ctrlWordData.ctrlWord)) {
+				writeBuffer();
+				writeText(ctrlWordData.toString());
+			}
+			result = true;
+			break;
+		case RtfParser.TYPE_CONVERT:
+			if(!IMPORT_IGNORED_CTRLWORDS.contains(ctrlWordData.ctrlWord)) {
+			}
+			result = true;
+			break;
+		default:	// error because is should be an import or convert
+			result = false;
+			break;
+		}
+		
+		
+		
+		
+		return result;
+	}
+	/**
+	 * Write the accumulated buffer to the destination.
+	 * Used for direct content
+	 */
+	private void writeBuffer() {
+		writeText(this.buffer.toString());
+		setToDefaults();
+	}
+	/**
+	 * Write the string value to the destination.
+	 * Used for direct content
+	 * @param value
+	 */
+	private void writeText(String value) {
+		if(this.rtfParser.isNewGroup()) {
+			this.rtfDoc.add(new RtfDirectContent("{"));
+			this.rtfParser.setNewGroup(false);
+		}
+		if(value.length() > 0) {
+			this.rtfDoc.add(new RtfDirectContent(value));
+		}
+	}
+	/* (non-Javadoc)
+	 * @see com.lowagie.text.rtf.direct.RtfDestination#setDefaults()
+	 */
+	public void setToDefaults() {
+		this.buffer = new StringBuffer(255);
+	}
+	/* (non-Javadoc)
+	 * @see com.lowagie.text.rtf.parser.properties.RtfPropertyListener#afterChange(java.lang.String)
+	 */
+	public void afterPropertyChange(String propertyName) {
+		if(propertyName.startsWith(RtfProperty.CHARACTER)) {
+		} else {
+			if(propertyName.startsWith(RtfProperty.PARAGRAPH)) {
+			} else {
+				if(propertyName.startsWith(RtfProperty.SECTION)) {
+				} else {
+					if(propertyName.startsWith(RtfProperty.DOCUMENT)) {
+
+					}
+				}
+			}
+		}		
+	}
+	
+	/* (non-Javadoc)
+	 * @see com.lowagie.text.rtf.parser.properties.RtfPropertyListener#beforeChange(java.lang.String)
+	 */
+	public void beforePropertyChange(String propertyName) {
+		// do we have any text to do anything with?
+		// if not, then just return without action.
+		if(this.buffer.length() == 0) return;
+		
+		if(propertyName.startsWith(RtfProperty.CHARACTER)) {
+			// this is a character change,
+			// add a new chunk to the current paragraph using current character settings.
+			Chunk chunk = new Chunk();
+			chunk.append(this.buffer.toString());
+			this.buffer = new StringBuffer(255);
+			HashMap charProperties = this.rtfParser.getState().properties.getProperties(RtfProperty.CHARACTER);
+			String defFont = (String)charProperties.get(RtfProperty.CHARACTER_FONT);
+			if(defFont == null) defFont = "0";
+			RtfDestinationFontTable fontTable = (RtfDestinationFontTable)this.rtfParser.getDestination("fonttbl");
+			Font currFont = fontTable.getFont(defFont);
+			int fs = Font.NORMAL;
+			if(charProperties.containsKey(RtfProperty.CHARACTER_BOLD)) fs |= Font.BOLD; 
+			if(charProperties.containsKey(RtfProperty.CHARACTER_ITALIC)) fs |= Font.ITALIC;
+			if(charProperties.containsKey(RtfProperty.CHARACTER_UNDERLINE)) fs |= Font.UNDERLINE;
+			Font useFont = FontFactory.getFont(currFont.getFamilyname(), 12, fs, new Color(0,0,0));
+			
+			
+			chunk.setFont(useFont);
+			if(iTextParagraph == null) this.iTextParagraph = new Paragraph();
+			this.iTextParagraph.add(chunk);
+
+		} else {
+			if(propertyName.startsWith(RtfProperty.PARAGRAPH)) {
+				// this is a paragraph change. what do we do?
+			} else {
+				if(propertyName.startsWith(RtfProperty.SECTION)) {
+					
+				} else {
+					if(propertyName.startsWith(RtfProperty.DOCUMENT)) {
+
+					}
+				}
+			}
+		}		
+	}
+	
+	private void addParagraphToDocument() {
+		if(this.iTextParagraph != null) {
+			try {
+				this.rtfParser.getDocument().add(this.iTextParagraph);
+			} catch (DocumentException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+			this.iTextParagraph = null;
+		}	
+	}
+}
Index: src/core/com/lowagie/text/rtf/style/RtfStyleTypes.java
===================================================================
--- src/core/com/lowagie/text/rtf/style/RtfStyleTypes.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/style/RtfStyleTypes.java	(revision 0)
@@ -0,0 +1,79 @@
+/*
+ * $Id: RtfStyleTypes.java 3373 2008-05-12 16:21:24Z xlv $
+ *
+ * Copyright 2007 by Howard Shank (hgshank@yahoo.com)
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+package com.lowagie.text.rtf.style;
+
+/**
+ * <code>RtfStyleTypes</code> contains the different types of Stylesheet entries
+ * that exist in RTF.
+ * 
+ * @author Howard Shank (hgshank@yahoo.com)
+ * @since 2.0.8
+ */
+public final class RtfStyleTypes {
+	/**
+	 * Indicates paragraph style.
+	 */
+	public final static int PARAGRAPH = 0;
+	/**
+	 * Indicates character style.
+	 */
+	public final static int CHARACTER = 0;
+	/**
+	 * Indicates section style.
+	 */
+	public final static int SECTION = 2;
+	/**
+	 * Indicates Table style.
+	 */
+	public final static int TABLE = 3;
+	/**
+	 * Indicates table definition style.
+	 */
+	public final static int TABLE_STYLE_DEFINITION = 4;
+}
Index: src/core/com/lowagie/text/rtf/parser/destinations/RtfDestinationShppict.java
===================================================================
--- src/core/com/lowagie/text/rtf/parser/destinations/RtfDestinationShppict.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/parser/destinations/RtfDestinationShppict.java	(revision 0)
@@ -0,0 +1,700 @@
+/*
+ * $Id: RtfDestinationShppict.java 3453 2008-05-26 03:02:41Z xlv $
+ *
+ * Copyright 2007, 2008 by Howard Shank (hgshank@yahoo.com)
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.rtf.parser.destinations;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.net.MalformedURLException;
+
+import com.lowagie.text.BadElementException;
+import com.lowagie.text.Document;
+import com.lowagie.text.DocumentException;
+import com.lowagie.text.Image;
+import com.lowagie.text.rtf.direct.RtfDirectContent;
+import com.lowagie.text.rtf.parser.RtfParser;
+import com.lowagie.text.rtf.parser.ctrlwords.RtfCtrlWordData;
+
+/**
+ * <code>RtfDestinationShppict</code> handles data destined for picture destinations
+ * 
+ * @author Howard Shank (hgshank@yahoo.com)
+ * @since 2.0.8
+ */
+public class RtfDestinationShppict extends RtfDestination {
+	private StringBuffer hexChars = new StringBuffer(0);
+
+	private StringBuffer buffer = new StringBuffer();
+
+	/* picttype */
+	private int pictureType = Image.ORIGINAL_NONE;
+
+	//	public static final int ORIGINAL_NONE = 0;
+	//	public static final int ORIGINAL_GIF = 3;
+	//	public static final int ORIGINAL_TIFF = 5;
+	//  public static final int ORIGINAL_PS = 7;
+
+	// emfblip - EMF (enhanced metafile) - NOT HANDLED
+	// pngblip int ORIGINAL_PNG = 2;
+	// jpegblip Image.ORIGINAL_JPEG = 1; ORIGINAL_JPEG2000 = 8;
+
+	// shppict - Destination
+	// nonshpict - Destination - SKIP THIS
+	// macpict - Mac QuickDraw- NOT HANDLED
+	// pmmetafileN - OS/2 Metafile - NOT HANDLED
+	// N * Meaning
+	// 0x0004 PU_ARBITRARY
+	// 0x0008 PU_PELS
+	// 0x000C PU_LOMETRIC
+	// 0x0010 PU_HIMETRIC
+	// 0x0014 PU_LOENGLISH
+	// 0x0018 PU_HIENGLISH
+	// 0x001C PU_TWIPS
+	private int pmmetafile = 0;
+
+	// wmetafileN Image.RIGINAL_WMF = 6;
+	// N * Type
+	// 1 = MM_TEXT
+	// 2 = M_LOMETRIC
+	// 3 = MM_HIMETRIC
+	// 4 = MM_LOENGLISH
+	// 5 = MM_HIENGLISH
+	// 6 = MM_TWIPS
+	// 7 = MM_ISOTROPIC
+	// 8 = MM_ANISOTROPIC
+	// dibitmapN - DIB - Convert to BMP?
+	// wbitmapN Image.ORIGINAL_BMP = 4;
+
+	/* bitapinfo */
+	// wbmbitspixelN - number of bits per pixel - 1 monochrome, 4 16 color, 8 256 color, 24 RGB - Default 1
+	private Integer bitsPerPixel = new Integer(1);
+
+	// wbmplanesN - number of color planes - must be 1
+	private Integer planes = new Integer(1);
+
+	// wbmwidthbytesN - number of bytes in each raster line
+	private Integer widthBytes = null;
+
+	/* pictsize */
+	// picwN Ext field if the picture is a Windows metafile; picture width in pixels if the picture is a bitmap or
+	// from quickdraw
+	private Long width = null;
+
+	// pichN
+	private Long height = null;
+
+	// picwgoalN
+	private Long desiredWidth = null;
+
+	// picgoalN
+	private Long desiredHeight = null;
+
+	// picscalexN
+	private Integer scaleX = new Integer(100);
+
+	// picscaleyN
+	private Integer scaleY = new Integer(100);
+
+	// picscaled - macpict setting
+	private Boolean scaled = null;
+
+	// picprop
+	private Boolean inlinePicture = Boolean.FALSE;
+
+	// defshp
+	private Boolean wordArt = Boolean.FALSE;
+
+	// piccroptN
+	private Integer cropTop = new Integer(0);
+
+	// piccropbN
+	private Integer cropBottom = new Integer(0);
+
+	// piccroplN
+	private Integer cropLeft = new Integer(0);
+
+	// piccroprN
+	private Integer cropRight = new Integer(0);
+
+	/* metafileinfo */
+	// picbmp
+	private boolean bitmap = false;
+
+	//picbppN - Valid 1,4,8,24
+	private int bbp = 1;
+
+	/* data */
+	// binN
+	// 0 = HEX, 1 = BINARY
+	public static final int FORMAT_HEXADECIMAL = 0;
+
+	public static final int FORMAT_BINARY = 1;
+
+	private int dataFormat = FORMAT_HEXADECIMAL;
+
+	private long binaryLength = 0;
+
+	// blipupiN
+	private Integer unitsPerInch = null;
+
+	// bliptagN
+	private String tag = "";
+
+	private static final int NORMAL = 0;
+
+	private static final int BLIPUID = 1;
+
+	private int state = NORMAL;
+
+	/**
+	 * Constant for converting pixels to twips
+	 */
+	private static final int PIXEL_TWIPS_FACTOR = 15;
+
+	// Image data for import and conversion functions.
+	private ByteArrayOutputStream dataOS = null;
+
+	public RtfDestinationShppict() {
+		super(null);
+	}
+
+	/**
+	 * Constructs a new RtfDestinationShppict.
+	 */
+	public RtfDestinationShppict(RtfParser parser) {
+		super(parser);
+	}
+
+	/* (non-Javadoc)
+	 * @see com.lowagie.text.rtf.direct.RtfDestination#closeDestination()
+	 */
+	public boolean closeDestination() {
+		if (this.rtfParser.isImport()) {
+			if (this.buffer.length() > 0) {
+				writeBuffer();
+			}
+		}
+		return true;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.lowagie.text.rtf.direct.RtfDestination#handleGroupEnd()
+	 */
+	public boolean handleCloseGroup() {
+		this.onCloseGroup(); // event handler
+
+		if (this.rtfParser.isImport()) {
+			if (this.buffer.length() > 0) {
+				writeBuffer();
+			}
+			if (dataOS != null) {
+				addImage();
+				dataOS = null;
+			}
+			this.writeText("}");
+			return true;
+		}
+		if (this.rtfParser.isConvert()) {
+			if (dataOS != null) {
+				addImage();
+				dataOS = null;
+			}
+		}
+		return true;
+	}
+
+	private boolean addImage() {
+		Image img = null;
+
+		try {
+			img = Image.getInstance(dataOS.toByteArray());
+			//data=null;
+		} catch (BadElementException e) {
+			e.printStackTrace();
+		} catch (MalformedURLException e) {
+			e.printStackTrace();
+		} catch (IOException e) {
+			// log there was in unsupported image found. Continue to import/convert the document.
+			e.printStackTrace();
+		}
+
+		if (img != null) {
+
+			// DEBUG: Write test file to see what is in Image object.
+			//				FileOutputStream out =null;
+			//				try {
+			//					out = new FileOutputStream("c:\\testOrig.png");
+			//					out.write(dataOS.toByteArray());
+			//					out.close();
+			//					out = new FileOutputStream("c:\\testNew.png");
+			//					out.write(img.getOriginalData());
+			//					out.close();
+			//				} catch (FileNotFoundException e1) {
+			//					e1.printStackTrace();
+			//				} catch (IOException e1) {
+			//					e1.printStackTrace();
+			//				}
+
+			// set the image attributes
+
+			img.scaleAbsolute(this.desiredWidth.floatValue()
+					/ PIXEL_TWIPS_FACTOR, this.desiredHeight.floatValue()
+					/ PIXEL_TWIPS_FACTOR);
+			img.scaleAbsolute(this.width.floatValue() / PIXEL_TWIPS_FACTOR,
+					this.height.floatValue() / PIXEL_TWIPS_FACTOR);
+			img.scalePercent(this.scaleX.floatValue(), this.scaleY.floatValue());
+			//				img.setBorder(value);
+
+			try {
+				if (this.rtfParser.isImport()) {
+					Document doc = this.rtfParser.getDocument();
+					doc.add(img);
+//					RtfDocument rtfDoc = this.rtfParser.getRtfDocument();
+//					RtfImage rtfImage = new RtfImage(rtfDoc, img);
+//					rtfDoc.add(rtfImage);
+				}
+				if (this.rtfParser.isConvert()) {
+					this.rtfParser.getDocument().add(img);
+				}
+			} catch (DocumentException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+		}
+
+		dataFormat = FORMAT_HEXADECIMAL;
+		return true;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.lowagie.text.rtf.direct.RtfDestination#handleGroupStart()
+	 */
+	public boolean handleOpenGroup() {
+		this.onOpenGroup(); // event handler
+
+		if (this.rtfParser.isImport()) {
+		}
+		if (this.rtfParser.isConvert()) {
+		}
+		return true;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.lowagie.text.rtf.parser.destinations.RtfDestination#handleOpenNewGroup()
+	 */
+	public boolean handleOpeningSubGroup() {
+		if (this.rtfParser.isImport()) {
+			if (this.buffer.length() > 0) {
+				writeBuffer();
+			}
+		}
+		return true;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.lowagie.text.rtf.direct.RtfDestination#handleCharacter(int)
+	 */
+	public boolean handleCharacter(int ch) {
+
+		if (this.rtfParser.isImport()) {
+			if (buffer.length() > 254)
+				writeBuffer();
+		}
+		//if(data == null) data = new ByteBuffer();
+		if (dataOS == null) {
+			dataOS = new ByteArrayOutputStream();
+		}
+		switch (dataFormat) {
+		case FORMAT_HEXADECIMAL:
+			hexChars.append((char) ch);
+			if (hexChars.length() == 2) {
+				try {
+					dataOS.write((char) Integer.parseInt(hexChars.toString(),
+							16));
+				} catch (NumberFormatException e) {
+					e.printStackTrace();
+				}
+				hexChars = new StringBuffer();
+			}
+			break;
+		case FORMAT_BINARY:
+			if (dataOS == null) {
+				dataOS = new ByteArrayOutputStream();
+			}
+			// HGS - FIX ME IF PROBLEM!
+			dataOS.write((char) (ch));
+			// PNG signature should be.
+			//			   (decimal)              137  80  78  71  13  10  26  10
+			//			   (hexadecimal)           89  50  4e  47  0d  0a  1a  0a
+			//			   (ASCII C notation)    \211   P   N   G  \r  \n \032 \n
+
+			binaryLength--;
+			if (binaryLength == 0) {
+				dataFormat = FORMAT_HEXADECIMAL;
+			}
+			break;
+		}
+
+		return true;
+	}
+
+	public boolean handleControlWord(RtfCtrlWordData ctrlWordData) {
+		boolean result = false;
+		boolean skipCtrlWord = false;
+		if (this.rtfParser.isImport()) {
+			skipCtrlWord = true;
+			if (ctrlWordData.ctrlWord.equals("shppict")) {
+				result = true;
+			} else if (ctrlWordData.ctrlWord.equals("nonshppict")) /* never gets here because this is a destination set to null */{
+				skipCtrlWord = true;
+				this.rtfParser.setTokeniserStateSkipGroup();
+				result = true;
+			} else if (ctrlWordData.ctrlWord.equals("blipuid")) {
+				skipCtrlWord = true;
+				this.rtfParser.setTokeniserStateSkipGroup();
+				result = true;
+			} else if (ctrlWordData.ctrlWord.equals("picprop")) {
+				skipCtrlWord = true;
+				this.rtfParser.setTokeniserStateSkipGroup();
+				result = true;
+			} else if (ctrlWordData.ctrlWord.equals("pict")) {
+				result = true;
+			} else if (ctrlWordData.ctrlWord.equals("emfblip")) {
+				result = true;
+				pictureType = Image.ORIGINAL_NONE;
+			} else if (ctrlWordData.ctrlWord.equals("pngblip")) {
+				result = true;
+				pictureType = Image.ORIGINAL_PNG;
+			} else if (ctrlWordData.ctrlWord.equals("jepgblip")) {
+				result = true;
+				pictureType = Image.ORIGINAL_JPEG;
+			} else if (ctrlWordData.ctrlWord.equals("macpict")) {
+				result = true;
+				pictureType = Image.ORIGINAL_NONE;
+			} else if (ctrlWordData.ctrlWord.equals("pmmetafile")) {
+				result = true;
+				pictureType = Image.ORIGINAL_NONE;
+			} else if (ctrlWordData.ctrlWord.equals("wmetafile")) {
+				result = true;
+				pictureType = Image.ORIGINAL_WMF;
+			} else if (ctrlWordData.ctrlWord.equals("dibitmap")) {
+				result = true;
+				pictureType = Image.ORIGINAL_NONE;
+			} else if (ctrlWordData.ctrlWord.equals("wbitmap")) {
+				result = true;
+				pictureType = Image.ORIGINAL_BMP;
+			}
+			/* bitmap information */
+			else if (ctrlWordData.ctrlWord.equals("wbmbitspixel")) {
+				result = true;
+			} else if (ctrlWordData.ctrlWord.equals("wbmplanes")) {
+				result = true;
+			} else if (ctrlWordData.ctrlWord.equals("wbmwidthbytes")) {
+				result = true;
+			} else
+			/* picture size, scaling and cropping */
+			if (ctrlWordData.ctrlWord.equals("picw")) {
+				this.width = ctrlWordData.toLong();
+				result = true;
+			} else if (ctrlWordData.ctrlWord.equals("pich")) {
+				this.height = ctrlWordData.toLong();
+				result = true;
+			} else if (ctrlWordData.ctrlWord.equals("picwgoal")) {
+				this.desiredWidth = ctrlWordData.toLong();
+				result = true;
+			} else if (ctrlWordData.ctrlWord.equals("pichgoal")) {
+				this.desiredHeight = ctrlWordData.toLong();
+				result = true;
+			} else if (ctrlWordData.ctrlWord.equals("picscalex")) {
+				this.scaleX = ctrlWordData.toInteger();
+				result = true;
+			} else if (ctrlWordData.ctrlWord.equals("picscaley")) {
+				this.scaleY = ctrlWordData.toInteger();
+				result = true;
+			} else if (ctrlWordData.ctrlWord.equals("picscaled")) {
+				result = true;
+			} else if (ctrlWordData.ctrlWord.equals("picprop")) {
+				skipCtrlWord = true;
+				this.rtfParser.setTokeniserStateSkipGroup();
+				result = true;
+			} else if (ctrlWordData.ctrlWord.equals("defshp")) {
+				result = true;
+			} else if (ctrlWordData.ctrlWord.equals("piccropt")) {
+				this.cropTop = ctrlWordData.toInteger();
+				result = true;
+			} else if (ctrlWordData.ctrlWord.equals("piccropb")) {
+				this.cropBottom = ctrlWordData.toInteger();
+				result = true;
+			} else if (ctrlWordData.ctrlWord.equals("piccropl")) {
+				this.cropLeft = ctrlWordData.toInteger();
+				result = true;
+			} else if (ctrlWordData.ctrlWord.equals("piccropr")) {
+				this.cropRight = ctrlWordData.toInteger();
+				result = true;
+			} else
+			/* metafile information */
+			if (ctrlWordData.ctrlWord.equals("picbmp")) {
+				result = true;
+			} else if (ctrlWordData.ctrlWord.equals("picbpp")) {
+				result = true;
+			} else
+			/* picture data */
+			if (ctrlWordData.ctrlWord.equals("bin")) {
+				this.dataFormat = FORMAT_BINARY;
+				// set length to param
+				this.binaryLength = ctrlWordData.longValue();
+				this.rtfParser.setTokeniserStateBinary(binaryLength);
+				result = true;
+			} else if (ctrlWordData.ctrlWord.equals("blipupi")) {
+				result = true;
+			} else if (ctrlWordData.ctrlWord.equals("blipuid")) {
+				skipCtrlWord = true;
+				this.rtfParser.setTokeniserStateSkipGroup();
+				result = true;
+			} else if (ctrlWordData.ctrlWord.equals("bliptag")) {
+				result = true;
+			}
+		}
+
+		if (this.rtfParser.isConvert()) {
+			if (ctrlWordData.ctrlWord.equals("shppict")) {
+				result = true;
+			}
+			if (ctrlWordData.ctrlWord.equals("nonshppict")) {
+				skipCtrlWord = true;
+				this.rtfParser.setTokeniserStateSkipGroup();
+				result = true;
+			}
+			if (ctrlWordData.ctrlWord.equals("blipuid")) {
+				result = true;
+				this.rtfParser.setTokeniserStateSkipGroup();
+				result = true;
+			}
+			if (ctrlWordData.ctrlWord.equals("pict")) {
+				result = true;
+			}
+			if (ctrlWordData.ctrlWord.equals("emfblip")) {
+				result = true;
+			}
+			if (ctrlWordData.ctrlWord.equals("pngblip")) {
+				result = true;
+			}
+			if (ctrlWordData.ctrlWord.equals("jepgblip")) {
+				result = true;
+			}
+			if (ctrlWordData.ctrlWord.equals("macpict")) {
+				result = true;
+			}
+			if (ctrlWordData.ctrlWord.equals("pmmetafile")) {
+				result = true;
+			}
+			if (ctrlWordData.ctrlWord.equals("wmetafile")) {
+				skipCtrlWord = true;
+				this.rtfParser.setTokeniserStateSkipGroup();
+				result = true;
+			}
+			if (ctrlWordData.ctrlWord.equals("dibitmap")) {
+				result = true;
+			}
+			if (ctrlWordData.ctrlWord.equals("wbitmap")) {
+				result = true;
+			}
+			/* bitmap information */
+			if (ctrlWordData.ctrlWord.equals("wbmbitspixel")) {
+				result = true;
+			}
+			if (ctrlWordData.ctrlWord.equals("wbmplanes")) {
+				result = true;
+			}
+			if (ctrlWordData.ctrlWord.equals("wbmwidthbytes")) {
+				result = true;
+			}
+			/* picture size, scaling and cropping */
+			if (ctrlWordData.ctrlWord.equals("picw")) {
+				this.width = ctrlWordData.toLong();
+				result = true;
+			}
+			if (ctrlWordData.ctrlWord.equals("pich")) {
+				this.height = ctrlWordData.toLong();
+				result = true;
+			}
+			if (ctrlWordData.ctrlWord.equals("picwgoal")) {
+				this.desiredWidth = ctrlWordData.toLong();
+				result = true;
+			}
+			if (ctrlWordData.ctrlWord.equals("pichgoal")) {
+				this.desiredHeight = ctrlWordData.toLong();
+				result = true;
+			}
+			if (ctrlWordData.ctrlWord.equals("picscalex")) {
+				this.scaleX = ctrlWordData.toInteger();
+				result = true;
+			}
+			if (ctrlWordData.ctrlWord.equals("picscaley")) {
+				this.scaleY = ctrlWordData.toInteger();
+				result = true;
+			}
+			if (ctrlWordData.ctrlWord.equals("picscaled")) {
+				result = true;
+			}
+			if (ctrlWordData.ctrlWord.equals("picprop")) {
+				skipCtrlWord = true;
+				this.rtfParser.setTokeniserStateSkipGroup();
+				result = true;
+			}
+			if (ctrlWordData.ctrlWord.equals("defshp")) {
+				result = true;
+			}
+			if (ctrlWordData.ctrlWord.equals("piccropt")) {
+				this.cropTop = ctrlWordData.toInteger();
+				result = true;
+			}
+			if (ctrlWordData.ctrlWord.equals("piccropb")) {
+				this.cropBottom = ctrlWordData.toInteger();
+				result = true;
+			}
+			if (ctrlWordData.ctrlWord.equals("piccropl")) {
+				this.cropLeft = ctrlWordData.toInteger();
+				result = true;
+			}
+			if (ctrlWordData.ctrlWord.equals("piccropr")) {
+				this.cropRight = ctrlWordData.toInteger();
+				result = true;
+			}
+			/* metafile information */
+			if (ctrlWordData.ctrlWord.equals("picbmp")) {
+				result = true;
+			}
+			if (ctrlWordData.ctrlWord.equals("picbpp")) {
+				result = true;
+			}
+			/* picture data */
+			if (ctrlWordData.ctrlWord.equals("bin")) {
+				dataFormat = FORMAT_BINARY;
+				result = true;
+			}
+			if (ctrlWordData.ctrlWord.equals("blipupi")) {
+				result = true;
+			}
+			if (ctrlWordData.ctrlWord.equals("blipuid")) {
+				skipCtrlWord = true;
+				this.rtfParser.setTokeniserStateSkipGroup();
+				result = true;
+			}
+			if (ctrlWordData.ctrlWord.equals("bliptag")) {
+				result = true;
+			}
+		}
+		if (!skipCtrlWord) {
+			switch (this.rtfParser.getConversionType()) {
+			case RtfParser.TYPE_IMPORT_FULL:
+				writeBuffer();
+				writeText(ctrlWordData.toString());
+				result = true;
+				break;
+			case RtfParser.TYPE_IMPORT_FRAGMENT:
+				writeBuffer();
+				writeText(ctrlWordData.toString());
+				result = true;
+				break;
+			case RtfParser.TYPE_CONVERT:
+				result = true;
+				break;
+			default: // error because is should be an import or convert
+				result = false;
+				break;
+			}
+		}
+		return result;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.lowagie.text.rtf.direct.RtfDestination#setDefaults()
+	 */
+	public void setToDefaults() {
+
+		this.buffer = new StringBuffer();
+		//this.data = null;
+		this.width = null;
+		this.height = null;
+		this.desiredWidth = null;
+		this.desiredHeight = null;
+		this.scaleX = new Integer(100);
+		this.scaleY = new Integer(100);
+		this.scaled = null;
+		this.inlinePicture = Boolean.FALSE;
+		this.wordArt = Boolean.FALSE;
+		this.cropTop = new Integer(0);
+		this.cropBottom = new Integer(0);
+		this.cropLeft = new Integer(0);
+		this.cropRight = new Integer(0);
+		this.bitmap = false;
+		this.bbp = 1;
+		this.dataFormat = FORMAT_HEXADECIMAL;
+		this.binaryLength = 0;
+		this.unitsPerInch = null;
+		this.tag = "";
+	}
+
+	private void writeBuffer() {
+		writeText(this.buffer.toString());
+		//setToDefaults();
+	}
+
+	private void writeText(String value) {
+		if (this.rtfParser.getState().newGroup) {
+			this.rtfParser.getRtfDocument().add(new RtfDirectContent("{"));
+			this.rtfParser.getState().newGroup = false;
+		}
+		if (value.length() > 0) {
+			this.rtfParser.getRtfDocument().add(new RtfDirectContent(value));
+		}
+	}
+
+}
Index: src/core/com/lowagie/text/rtf/parser/destinations/RtfDestinationListener.java
===================================================================
--- src/core/com/lowagie/text/rtf/parser/destinations/RtfDestinationListener.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/parser/destinations/RtfDestinationListener.java	(revision 0)
@@ -0,0 +1,99 @@
+/* 
+ * $Id: RtfDestinationListener.java 3373 2008-05-12 16:21:24Z xlv $
+ *
+ * Copyright 2007 by Howard Shank (hgshank@yahoo.com)
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+package com.lowagie.text.rtf.parser.destinations;
+
+import java.util.EventListener;
+
+import com.lowagie.text.rtf.parser.ctrlwords.RtfCtrlWordData;
+
+/**
+ * <code>RtfDestinationListener</code> interface for handling events.
+ * 
+ * @author Howard Shank (hgshank@yahoo.com)
+ * 
+ *  @since 2.0.8
+ */
+public interface RtfDestinationListener extends EventListener {
+	/**
+	 * 
+	 */
+	public RtfCtrlWordData beforeCtrlWord(RtfCtrlWordData ctrlWordData);
+	/**
+	 * 
+	 */
+	public RtfCtrlWordData onCtrlWord(RtfCtrlWordData ctrlWordData);
+	/**
+	 * 
+	 */
+	public RtfCtrlWordData afterCtrlWord(RtfCtrlWordData ctrlWordData);
+	/**
+	 * 
+	 */
+	public int beforeCharacter(int ch);
+	/**
+	 * 
+	 */
+	public int onCharacter(int ch);
+	/**
+	 * 
+	 */
+	public int afterCharacter(int ch);
+	/**
+	 * 
+	 * @return true if all went well
+	 */
+	public boolean onOpenGroup();
+	/**
+	 * 
+	 * @return true if all went well
+	 */
+	public boolean onCloseGroup();
+	
+
+}
Index: src/core/com/lowagie/text/markup/MarkupTags.java
===================================================================
--- src/core/com/lowagie/text/markup/MarkupTags.java	(revision 0)
+++ src/core/com/lowagie/text/markup/MarkupTags.java	(revision 0)
@@ -0,0 +1,266 @@
+/*
+ * $Id: MarkupTags.java 1790 2005-06-17 13:39:13Z blowagie $
+ * $Name$
+ *
+ * Copyright 2001, 2002 by Bruno Lowagie.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.markup;
+
+/**
+ * A class that contains all the possible tagnames and their attributes.
+ */
+
+public class MarkupTags {
+	
+	// iText specific
+	
+	/** the key for any tag */
+	public static final String ITEXT_TAG = "tag";
+
+	// HTML tags
+
+	/** the markup for the body part of a file */
+	public static final String HTML_TAG_BODY = "body";
+	
+	/** The DIV tag. */
+	public static final String HTML_TAG_DIV = "div";
+
+	/** This is a possible HTML-tag. */
+	public static final String HTML_TAG_LINK = "link";
+
+	/** The SPAN tag. */
+	public static final String HTML_TAG_SPAN = "span";
+
+	// HTML attributes
+
+	/** the height attribute. */
+	public static final String HTML_ATTR_HEIGHT = "height";
+
+	/** the hyperlink reference attribute. */
+	public static final String HTML_ATTR_HREF = "href";
+
+	/** This is a possible HTML attribute for the LINK tag. */
+	public static final String HTML_ATTR_REL = "rel";
+
+	/** This is used for inline css style information */
+	public static final String HTML_ATTR_STYLE = "style";
+
+	/** This is a possible HTML attribute for the LINK tag. */
+	public static final String HTML_ATTR_TYPE = "type";
+
+	/** This is a possible HTML attribute. */
+	public static final String HTML_ATTR_STYLESHEET = "stylesheet";
+
+	/** the width attribute. */
+	public static final String HTML_ATTR_WIDTH = "width";
+
+	/** attribute for specifying externally defined CSS class */
+	public static final String HTML_ATTR_CSS_CLASS = "class";
+
+	/** The ID attribute. */
+	public static final String HTML_ATTR_CSS_ID = "id";
+
+	// HTML values
+	
+	/** This is a possible value for the language attribute (SCRIPT tag). */
+	public static final String HTML_VALUE_JAVASCRIPT = "text/javascript";
+	
+	/** This is a possible HTML attribute for the LINK tag. */
+	public static final String HTML_VALUE_CSS = "text/css";
+
+	// CSS keys
+
+	/** the CSS tag for background color */
+	public static final String CSS_KEY_BGCOLOR = "background-color";
+
+	/** the CSS tag for text color */
+	public static final String CSS_KEY_COLOR = "color";
+
+	/** CSS key that indicate the way something has to be displayed */
+	public static final String CSS_KEY_DISPLAY = "display";
+
+	/** the CSS tag for the font family */
+	public static final String CSS_KEY_FONTFAMILY = "font-family";
+
+	/** the CSS tag for the font size */
+	public static final String CSS_KEY_FONTSIZE = "font-size";
+
+	/** the CSS tag for the font style */
+	public static final String CSS_KEY_FONTSTYLE = "font-style";
+
+	/** the CSS tag for the font weight */
+	public static final String CSS_KEY_FONTWEIGHT = "font-weight";
+
+	/** the CSS tag for text decorations */
+	public static final String CSS_KEY_LINEHEIGHT = "line-height";
+
+	/** the CSS tag for the margin of an object */
+	public static final String CSS_KEY_MARGIN = "margin";
+
+	/** the CSS tag for the margin of an object */
+	public static final String CSS_KEY_MARGINLEFT = "margin-left";
+
+	/** the CSS tag for the margin of an object */
+	public static final String CSS_KEY_MARGINRIGHT = "margin-right";
+
+	/** the CSS tag for the margin of an object */
+	public static final String CSS_KEY_MARGINTOP = "margin-top";
+
+	/** the CSS tag for the margin of an object */
+	public static final String CSS_KEY_MARGINBOTTOM = "margin-bottom";
+
+	/** the CSS tag for the margin of an object */
+	public static final String CSS_KEY_PADDING = "padding";
+
+	/** the CSS tag for the margin of an object */
+	public static final String CSS_KEY_PADDINGLEFT = "padding-left";
+
+	/** the CSS tag for the margin of an object */
+	public static final String CSS_KEY_PADDINGRIGHT = "padding-right";
+
+	/** the CSS tag for the margin of an object */
+	public static final String CSS_KEY_PADDINGTOP = "padding-top";
+
+	/** the CSS tag for the margin of an object */
+	public static final String CSS_KEY_PADDINGBOTTOM = "padding-bottom";
+
+	/** the CSS tag for the margin of an object */
+	public static final String CSS_KEY_BORDERCOLOR = "border-color";
+
+	/** the CSS tag for the margin of an object */
+	public static final String CSS_KEY_BORDERWIDTH = "border-width";
+
+	/** the CSS tag for the margin of an object */
+	public static final String CSS_KEY_BORDERWIDTHLEFT = "border-left-width";
+
+	/** the CSS tag for the margin of an object */
+	public static final String CSS_KEY_BORDERWIDTHRIGHT = "border-right-width";
+
+	/** the CSS tag for the margin of an object */
+	public static final String CSS_KEY_BORDERWIDTHTOP = "border-top-width";
+
+	/** the CSS tag for the margin of an object */
+	public static final String CSS_KEY_BORDERWIDTHBOTTOM = "border-bottom-width";
+
+	/** the CSS tag for adding a page break when the document is printed */
+	public static final String CSS_KEY_PAGE_BREAK_AFTER = "page-break-after";
+
+	/** the CSS tag for adding a page break when the document is printed */
+	public static final String CSS_KEY_PAGE_BREAK_BEFORE = "page-break-before";
+
+	/** the CSS tag for the horizontal alignment of an object */
+	public static final String CSS_KEY_TEXTALIGN = "text-align";
+
+	/** the CSS tag for text decorations */
+	public static final String CSS_KEY_TEXTDECORATION = "text-decoration";
+
+	/** the CSS tag for text decorations */
+	public static final String CSS_KEY_VERTICALALIGN = "vertical-align";
+
+	/** the CSS tag for the visibility of objects */
+	public static final String CSS_KEY_VISIBILITY = "visibility";
+
+	// CSS values
+
+	/** value for the CSS tag for adding a page break when the document is printed */
+	public static final String CSS_VALUE_ALWAYS = "always";
+
+	/** A possible value for the DISPLAY key */
+	public static final String CSS_VALUE_BLOCK = "block";
+
+	/** a CSS value for text font weight */
+	public static final String CSS_VALUE_BOLD = "bold";
+
+	/** the value if you want to hide objects. */
+	public static final String CSS_VALUE_HIDDEN = "hidden";
+
+	/** A possible value for the DISPLAY key */
+	public static final String CSS_VALUE_INLINE = "inline";
+	
+	/** a CSS value for text font style */
+	public static final String CSS_VALUE_ITALIC = "italic";
+
+	/** a CSS value for text decoration */
+	public static final String CSS_VALUE_LINETHROUGH = "line-through";
+
+	/** A possible value for the DISPLAY key */
+	public static final String CSS_VALUE_LISTITEM = "list-item";
+	
+	/** a CSS value */
+	public static final String CSS_VALUE_NONE = "none";
+
+	/** a CSS value */
+	public static final String CSS_VALUE_NORMAL = "normal";
+
+	/** a CSS value for text font style */
+	public static final String CSS_VALUE_OBLIQUE = "oblique";
+
+	/** A possible value for the DISPLAY key */
+	public static final String CSS_VALUE_TABLE = "table";
+
+	/** A possible value for the DISPLAY key */
+	public static final String CSS_VALUE_TABLEROW = "table-row";
+
+	/** A possible value for the DISPLAY key */
+	public static final String CSS_VALUE_TABLECELL = "table-cell";
+
+	/** the CSS value for a horizontal alignment of an object */
+	public static final String CSS_VALUE_TEXTALIGNLEFT = "left";
+
+	/** the CSS value for a horizontal alignment of an object */
+	public static final String CSS_VALUE_TEXTALIGNRIGHT = "right";
+
+	/** the CSS value for a horizontal alignment of an object */
+	public static final String CSS_VALUE_TEXTALIGNCENTER = "center";
+
+	/** the CSS value for a horizontal alignment of an object */
+	public static final String CSS_VALUE_TEXTALIGNJUSTIFY = "justify";
+
+	/** a CSS value for text decoration */
+	public static final String CSS_VALUE_UNDERLINE = "underline";
+
+}
\ No newline at end of file
Index: src/core/com/lowagie/text/rtf/text/RtfChapter.java
===================================================================
--- src/core/com/lowagie/text/rtf/text/RtfChapter.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/text/RtfChapter.java	(revision 0)
@@ -0,0 +1,101 @@
+/*
+ * $Id: RtfChapter.java 3580 2008-08-06 15:52:00Z howard_s $
+ *
+ * Copyright 2001, 2002 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.rtf.text;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import com.lowagie.text.Chapter;
+import com.lowagie.text.DocWriter;
+import com.lowagie.text.rtf.RtfBasicElement;
+import com.lowagie.text.rtf.document.RtfDocument;
+
+
+/**
+ * The RtfChapter wraps a Chapter element.
+ * INTERNAL CLASS
+ * 
+ * @version $Id: RtfChapter.java 3580 2008-08-06 15:52:00Z howard_s $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Thomas Bickel (tmb99@inode.at)
+ */
+public class RtfChapter extends RtfSection {
+
+    /**
+     * Constructs a RtfChapter for a given Chapter
+     * 
+     * @param doc The RtfDocument this RtfChapter belongs to
+     * @param chapter The Chapter this RtfChapter is based on
+     */
+    public RtfChapter(RtfDocument doc, Chapter chapter) {
+        super(doc, chapter);
+    }
+
+    /**
+     * Writes the RtfChapter and its contents
+     */    
+    public void writeContent(final OutputStream result) throws IOException
+    {
+        if(this.document.getLastElementWritten() != null && !(this.document.getLastElementWritten() instanceof RtfChapter)) {
+            result.write(DocWriter.getISOBytes("\\page"));
+        }
+        result.write(DocWriter.getISOBytes("\\sectd"));
+        document.getDocumentHeader().writeSectionDefinition(result);
+        if(this.title != null) {
+            this.title.writeContent(result);
+        }
+        for(int i = 0; i < items.size(); i++) {
+        	RtfBasicElement rbe = (RtfBasicElement)items.get(i);
+        	rbe.writeContent(result);
+        }
+        result.write(DocWriter.getISOBytes("\\sect"));
+    }        
+    
+}
Index: src/core/com/lowagie/text/rtf/parser/ctrlwords/RtfCtrlWordListener.java
===================================================================
--- src/core/com/lowagie/text/rtf/parser/ctrlwords/RtfCtrlWordListener.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/parser/ctrlwords/RtfCtrlWordListener.java	(revision 0)
@@ -0,0 +1,76 @@
+/* 
+ * $Id: RtfCtrlWordListener.java 3373 2008-05-12 16:21:24Z xlv $
+ *
+ * Copyright 2007 by Howard Shank (hgshank@yahoo.com)
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+package com.lowagie.text.rtf.parser.ctrlwords;
+
+import java.util.EventListener;
+
+/**
+ * <code>RtfCtrlWordListener</code> interface for handling events.
+ * 
+ * @author Howard Shank (hgshank@yahoo.com)
+ * 
+ *  @since 2.0.8
+ */
+public interface RtfCtrlWordListener extends EventListener {
+	/**
+	 * 
+	 * @return null or modified copy of the ctrlWordData object
+	 */
+	public RtfCtrlWordData beforeCtrlWord(RtfCtrlWordData ctrlWordData);
+	/**
+	 * 
+	 * @return null or modified copy of the ctrlWordData object
+	 */
+	public RtfCtrlWordData onCtrlWord(RtfCtrlWordData ctrlWordData);
+	/**
+	 * 
+	 * @return null or modified copy of the ctrlWordData object
+	 */
+	public RtfCtrlWordData afterCtrlWord(RtfCtrlWordData ctrlWordData);
+}
Index: src/core/com/lowagie/text/rtf/parser/enumerations/RtfColorThemes.java
===================================================================
--- src/core/com/lowagie/text/rtf/parser/enumerations/RtfColorThemes.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/parser/enumerations/RtfColorThemes.java	(revision 0)
@@ -0,0 +1,28 @@
+package com.lowagie.text.rtf.parser.enumerations;
+
+/**
+ * Specifies the color theme values for use in Color Tables.
+ * 
+ * @author Howard Shank (hgshank@yahoo.com)
+ * @since 2.0.8
+ */
+public final class RtfColorThemes {
+	public static final int THEME_UNDEFINED = -1;
+	public static final int THEME_MAINDARKONE = 0;
+	public static final int THEME_MAINDARKTWO = 1;
+	public static final int THEME_MAINLIGHTONE = 2;
+	public static final int THEME_MAINLIGHTTWO = 3;
+	public static final int THEME_ACCENTONE = 4;
+	public static final int THEME_ACCENTTWO = 5;
+	public static final int THEME_ACCENTTHREE = 6;
+	public static final int THEME_ACCENTFOUR = 7;
+	public static final int THEME_ACCENTFIVE = 8;
+	public static final int THEME_ACCENTSIX = 9;
+	public static final int THEME_HYPERLINK = 10;
+	public static final int THEME_FOLLOWEDHYPERLINK = 11;
+	public static final int THEME_BACKGROUNDONE = 12;
+	public static final int THEME_TEXTONE = 13;
+	public static final int THEME_BACKGROUNDTWO = 14;
+	public static final int THEME_TEXTTWO = 15;
+	public static final int THEME_MAX = 15;
+}
Index: src/core/com/lowagie/text/rtf/parser/ctrlwords/RtfCtrlWordMgr.java
===================================================================
--- src/core/com/lowagie/text/rtf/parser/ctrlwords/RtfCtrlWordMgr.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/parser/ctrlwords/RtfCtrlWordMgr.java	(revision 0)
@@ -0,0 +1,211 @@
+/* 
+ * $Id: RtfCtrlWordMgr.java 3373 2008-05-12 16:21:24Z xlv $
+ *
+ * Copyright 2007 by Howard Shank (hgshank@yahoo.com)
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.rtf.parser.ctrlwords;
+
+import java.io.PushbackInputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import com.lowagie.text.rtf.parser.RtfParser;
+
+/**
+ * <code>RtfCtrlWordMgr</code> handles the dispatching of control words from
+ * the table of known control words.
+ * 
+ * @author Howard Shank (hgshank@yahoo.com)
+ * @since 2.0.8
+ */
+public final class RtfCtrlWordMgr {
+	public static final boolean debug = false;
+	public static final boolean debugFound = false;
+	public static final boolean debugNotFound = true;
+	private PushbackInputStream reader = null;
+	private RtfParser rtfParser = null;
+	private RtfCtrlWordMap ctrlWordMap = null;
+	
+	/** The <code>RtfCtrlWordListener</code>. */
+    private ArrayList listeners = new ArrayList();
+
+//	// TIMING DEBUG INFO
+//	private long endTime = 0;
+//	private Date endDate = null;		
+//	private long endFree = 0;
+//	private DecimalFormat df = new DecimalFormat("#,##0");
+//	private Date startDate = new Date();
+//	private long startTime = System.currentTimeMillis();
+//	private long startFree = Runtime.getRuntime().freeMemory();
+	
+	/**
+	 * Constructor
+	 * @param rtfParser The parser object this manager works with.
+	 * @param reader the PushbackReader from the tokeniser.
+	 */
+	public RtfCtrlWordMgr(RtfParser rtfParser, PushbackInputStream reader) {
+		this.rtfParser = rtfParser;	// set the parser
+		this.reader = reader;	// set the reader value
+		ctrlWordMap = new RtfCtrlWordMap(rtfParser);
+		
+//		// TIMING DEBUG INFO
+//		endFree = Runtime.getRuntime().freeMemory();
+//		endTime = System.currentTimeMillis();
+//		endDate = new Date();
+//		System.out.println("RtfCtrlWordMgr start date: " + startDate.toLocaleString());
+//		System.out.println("RtfCtrlWordMgr end date  : " + endDate.toLocaleString());
+//		System.out.println("  Elapsed time    : " + Long.toString(endTime - startTime) + " milliseconds.");
+//		System.out.println("Begin Constructor RtfCtrlWordMgr , free mem is " + df.format(startFree / 1024) + "k");
+//		System.out.println("End Constructor RtfCtrlWordMgr , free mem is " + df.format(endFree / 1024) + "k");
+//        System.out.println("RtfCtrlWordMgr used approximately " + df.format((startFree - endFree) / 1024) + "k");
+	}
+	
+	/**
+	 * Internal to control word manager class.
+	 * 
+	 * @param ctrlWordData The <code>RtfCtrlWordData</code> object with control word and param
+	 * @param groupLevel The current document group parsing level
+	 * @return errOK if ok, otherwise an error code.
+	 */
+	public int handleKeyword(RtfCtrlWordData ctrlWordData, int groupLevel) {
+		//TODO: May be used for event handling.
+		int result = RtfParser.errOK;
+		
+		// Call before handler event here
+		beforeCtrlWord(ctrlWordData);
+		
+		result = dispatchKeyword(ctrlWordData, groupLevel);
+		
+		// call after handler event here
+		afterCtrlWord(ctrlWordData);
+		
+		return result;
+	}
+	
+	/**
+	 * Dispatch the token to the correct control word handling object.
+	 *  
+	 * @param ctrlWordData The <code>RtfCtrlWordData</code> object with control word and param
+	 * @param groupLevel The current document group parsing level
+	 * @return errOK if ok, otherwise an error code.
+	 */
+	private int dispatchKeyword(RtfCtrlWordData ctrlWordData, int groupLevel) {
+		int result = RtfParser.errOK;
+		if(ctrlWordData != null) {
+			RtfCtrlWordHandler ctrlWord = ctrlWordMap.getCtrlWordHandler(ctrlWordData.ctrlWord);
+			if(ctrlWord != null) {
+				ctrlWord.handleControlword(ctrlWordData);
+				if(debug && debugFound) {
+					System.out.println("Keyword found:" +
+						" New:" + ctrlWordData.ctrlWord + 
+						" Param:" + ctrlWordData.param + 
+						" bParam=" + ctrlWordData.hasParam);
+				}
+			} else {
+				result = RtfParser.errCtrlWordNotFound;
+				//result = RtfParser2.errAssertion;
+				if(debug && debugNotFound) {
+					System.out.println("Keyword unknown:" + 
+						" New:" + ctrlWordData.ctrlWord + 
+						" Param:" + ctrlWordData.param + 
+						" bParam=" + ctrlWordData.hasParam);
+				}
+			}	
+		}
+		return result;
+	}
+	
+
+    // listener methods
+
+	/**
+	 * Adds a <CODE>RtfCtrlWordListener</CODE> to the <CODE>RtfCtrlWordMgr</CODE>.
+	 *
+	 * @param listener
+	 *            the new RtfCtrlWordListener.
+	 */
+	public void addRtfCtrlWordListener(RtfCtrlWordListener listener) {
+		listeners.add(listener);
+	}
+
+	/**
+	 * Removes a <CODE>RtfCtrlWordListener</CODE> from the <CODE>RtfCtrlWordMgr</CODE>.
+	 *
+	 * @param listener
+	 *            the RtfCtrlWordListener that has to be removed.
+	 */
+	public void removeRtfCtrlWordListener(RtfCtrlWordListener listener) {
+		listeners.remove(listener);
+	}
+	
+	private boolean beforeCtrlWord(RtfCtrlWordData ctrlWordData) {
+		RtfCtrlWordListener listener;
+		for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
+            listener = (RtfCtrlWordListener) iterator.next();
+            listener.beforeCtrlWord(ctrlWordData);
+        }
+		return true;
+	}
+	
+	private boolean onCtrlWord(RtfCtrlWordData ctrlWordData) {
+		RtfCtrlWordListener listener;
+		for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
+            listener = (RtfCtrlWordListener) iterator.next();
+            listener.onCtrlWord(ctrlWordData);
+        }
+		return true;
+	}
+	
+	private boolean afterCtrlWord(RtfCtrlWordData ctrlWordData) {
+		RtfCtrlWordListener listener;
+		for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
+            listener = (RtfCtrlWordListener) iterator.next();
+            listener.afterCtrlWord(ctrlWordData);
+        }
+		return true;
+	}
+}
Index: src/core/com/lowagie/text/rtf/RtfWriter2.java
===================================================================
--- src/core/com/lowagie/text/rtf/RtfWriter2.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/RtfWriter2.java	(revision 0)
@@ -0,0 +1,386 @@
+/*
+ * $Id: RtfWriter2.java 3583 2008-08-12 00:00:09Z xlv $
+ *
+ * Copyright 2001, 2002, 2003, 2004 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.rtf;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.EventListener;
+
+import com.lowagie.text.DocWriter;
+import com.lowagie.text.Document;
+import com.lowagie.text.DocumentException;
+import com.lowagie.text.Element;
+import com.lowagie.text.HeaderFooter;
+import com.lowagie.text.Rectangle;
+import com.lowagie.text.rtf.document.RtfDocument;
+import com.lowagie.text.rtf.document.RtfDocumentSettings;
+import com.lowagie.text.rtf.parser.RtfImportMappings;
+import com.lowagie.text.rtf.parser.RtfParser;
+import com.lowagie.text.rtf.text.RtfNewPage;
+
+/**
+ * The RtfWriter allows the creation of rtf documents via the iText system
+ *
+ * Version: $Id: RtfWriter2.java 3583 2008-08-12 00:00:09Z xlv $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ */
+public class RtfWriter2 extends DocWriter {
+    /**
+     * The RtfDocument this RtfWriter is creating
+     */
+    private RtfDocument rtfDoc = null;
+    
+    /**
+     * Constructs a new RtfWriter that listens to the specified Document and
+     * writes its output to the OutputStream.
+     * 
+     * @param doc The Document that this RtfWriter listens to
+     * @param os The OutputStream to write to
+     */
+    protected RtfWriter2(Document doc, OutputStream os) {
+        super(doc, os);
+        doc.addDocListener(this);
+        rtfDoc = new RtfDocument();
+    }
+
+    /**
+     * Static method to generate RtfWriters
+     * 
+     * @param doc The Document that this RtfWriter listens to
+     * @param os The OutputStream to write to
+     * @return The new RtfWriter
+     */
+    public static RtfWriter2 getInstance(Document doc, OutputStream os) {
+        return new RtfWriter2(doc, os);
+    }
+
+    /**
+     * Sets the header to use
+     * 
+     * @param hf The HeaderFooter to use
+     */
+    public void setHeader(HeaderFooter hf) {
+        this.rtfDoc.getDocumentHeader().setHeader(hf);
+    }
+    
+    /**
+     * Resets the header
+     */
+    public void resetHeader() {
+        this.rtfDoc.getDocumentHeader().setHeader(null);
+    }
+    
+    /**
+     * Sets the footer to use
+     * 
+     * @param hf The HeaderFooter to use
+     */
+    public void setFooter(HeaderFooter hf) {
+        this.rtfDoc.getDocumentHeader().setFooter(hf);
+    }
+    
+    /**
+     * Resets the footer
+     */
+    public void resetFooter() {
+        this.rtfDoc.getDocumentHeader().setFooter(null);
+    }
+
+    /**
+     * This method is not supported in the RtfWriter
+     * @param i Unused
+     */
+    public void setPageCount(int i) {}
+    
+    /**
+     * This method is not supported in the RtfWriter
+     */
+    public void resetPageCount() {}
+
+    /**
+     * This method is not supported in the RtfWriter
+     */
+    public void clearTextWrap() {}
+
+    /**
+     * Opens the RtfDocument
+     */
+    public void open() {
+    	super.open();
+        this.rtfDoc.open();
+    }
+    
+    /**
+     * Closes the RtfDocument. This causes the document to be written
+     * to the specified OutputStream
+     */
+    public void close() {
+        if (open) {
+            rtfDoc.writeDocument(os);
+            super.close();
+            this.rtfDoc = new RtfDocument();
+        }
+    }
+
+    /**
+     * Adds an Element to the Document
+     *
+     * @param element The element to be added
+     * @return <code>false</code>
+     * @throws DocumentException
+     */
+    public boolean add(Element element) throws DocumentException {
+        if (pause) {
+            return false;
+        }
+        RtfBasicElement[] rtfElements = rtfDoc.getMapper().mapElement(element);
+        if(rtfElements.length != 0) {
+            for(int i = 0; i < rtfElements.length; i++) {
+                if(rtfElements[i] != null) {
+                    rtfDoc.add(rtfElements[i]);
+                }
+            }
+            return true;
+        } else {
+            return false;
+        }
+    }
+    
+    /**
+     * Adds a page break
+     *
+     * @return <code>false</code>
+     */
+    public boolean newPage() {
+        rtfDoc.add(new RtfNewPage(rtfDoc));
+        return true;
+    }
+
+    /**
+     * Sets the page margins
+     *
+     * @param left The left margin
+     * @param right The right margin
+     * @param top The top margin
+     * @param bottom The bottom margin
+     * @return <code>false</code>
+     */
+    public boolean setMargins(float left, float right, float top, float bottom) {
+        rtfDoc.getDocumentHeader().getPageSetting().setMarginLeft((int) (left * RtfElement.TWIPS_FACTOR));
+        rtfDoc.getDocumentHeader().getPageSetting().setMarginRight((int) (right * RtfElement.TWIPS_FACTOR));
+        rtfDoc.getDocumentHeader().getPageSetting().setMarginTop((int) (top * RtfElement.TWIPS_FACTOR));
+        rtfDoc.getDocumentHeader().getPageSetting().setMarginBottom((int) (bottom * RtfElement.TWIPS_FACTOR));
+        return true;
+    }
+    
+    /**
+     * Sets the size of the page
+     *
+     * @param rect A Rectangle representing the page
+     * @return <code>false</code>
+     */
+    public boolean setPageSize(Rectangle rect) {
+        rtfDoc.getDocumentHeader().getPageSetting().setPageSize(rect);
+        return true;
+    }
+    
+    /**
+     * Whether to automagically generate table of contents entries when
+     * adding Chapters or Sections.
+     * 
+     * @param autogenerate Whether to automatically generate TOC entries
+     */
+    public void setAutogenerateTOCEntries(boolean autogenerate) {
+        this.rtfDoc.setAutogenerateTOCEntries(autogenerate);
+    }
+    
+    /**
+     * Gets the RtfDocumentSettings that specify how the rtf document is generated.
+     * 
+     * @return The current RtfDocumentSettings.
+     */
+    public RtfDocumentSettings getDocumentSettings() {
+        return this.rtfDoc.getDocumentSettings();
+    }
+    
+    /**
+     * Adds the complete RTF document to the current RTF document being generated.
+     * It will parse the font and color tables and correct the font and color references
+     * so that the imported RTF document retains its formattings.
+     * 
+     * @param documentSource The Reader to read the RTF document from.
+     * @throws IOException On errors reading the RTF document.
+     * @throws DocumentException On errors adding to this RTF document.
+     * @since 2.1.0
+     */
+    public void importRtfDocument(FileInputStream documentSource) throws IOException, DocumentException {
+        importRtfDocument(documentSource, null);
+    }
+ 
+    /**
+     * Adds the complete RTF document to the current RTF document being generated.
+     * It will parse the font and color tables and correct the font and color references
+     * so that the imported RTF document retains its formattings.
+     * Uses new RtfParser object.
+     * 
+     * (author: Howard Shank)
+     * 
+     * @param documentSource The InputStream to read the RTF document from.
+	 * @param events The array of event listeners. May be null
+     * @throws IOException
+     * @throws DocumentException
+     * 
+     * @see RtfParser
+     * @see RtfParser#importRtfDocument(InputStream, RtfDocument)
+     * @since 2.0.8
+     */
+    public void importRtfDocument(InputStream documentSource, EventListener[] events ) throws IOException, DocumentException {
+        if(!this.open) {
+            throw new DocumentException("The document must be open to import RTF documents.");
+        }
+    	RtfParser rtfImport = new RtfParser(this.document);
+    	if(events != null) {
+    		for(int idx=0;idx<events.length;idx++) {
+        		rtfImport.addListener(events[idx]);
+    		}
+    	}
+    	rtfImport.importRtfDocument(documentSource, this.rtfDoc);
+    }
+    
+    /**
+     * Adds a fragment of an RTF document to the current RTF document being generated.
+     * Since this fragment doesn't contain font or color tables, all fonts and colors
+     * are mapped to the default font and color. If the font and color mappings are
+     * known, they can be specified via the mappings parameter.
+     * 
+     * @param documentSource The InputStream to read the RTF fragment from.
+     * @param mappings The RtfImportMappings that contain font and color mappings to apply to the fragment.
+     * @throws IOException On errors reading the RTF fragment.
+     * @throws DocumentException On errors adding to this RTF fragment.
+     * @since 2.1.0
+     */
+    public void importRtfFragment(InputStream documentSource, RtfImportMappings mappings) throws IOException, DocumentException {
+        importRtfFragment(documentSource, mappings, null);
+    }
+    
+    /**
+     * Adds a fragment of an RTF document to the current RTF document being generated.
+     * Since this fragment doesn't contain font or color tables, all fonts and colors
+     * are mapped to the default font and color. If the font and color mappings are
+     * known, they can be specified via the mappings parameter.
+     * Uses new RtfParser object.
+     * 
+     * (author: Howard Shank)
+     * 
+     * @param documentSource The InputStream to read the RTF fragment from.
+     * @param mappings The RtfImportMappings that contain font and color mappings to apply to the fragment.
+	 * @param events The array of event listeners. May be null
+     * @throws IOException On errors reading the RTF fragment.
+     * @throws DocumentException On errors adding to this RTF fragment.
+     * 
+     * @see RtfImportMappings
+     * @see RtfParser
+     * @see RtfParser#importRtfFragment(InputStream, RtfDocument, RtfImportMappings)
+     * @since 2.0.8
+     */
+    public void importRtfFragment(InputStream documentSource, RtfImportMappings mappings, EventListener[] events ) throws IOException, DocumentException {
+        if(!this.open) {
+            throw new DocumentException("The document must be open to import RTF fragments.");
+        }
+    	RtfParser rtfImport = new RtfParser(this.document);
+    	if(events != null) {
+    		for(int idx=0;idx<events.length;idx++) {
+        		rtfImport.addListener(events[idx]);
+    		}
+    	}
+    	rtfImport.importRtfFragment(documentSource, this.rtfDoc, mappings);
+    }
+    
+    
+    /**
+     * Adds the complete RTF document to the current RTF element being generated.
+     * It will parse the font and color tables and correct the font and color references
+     * so that the imported RTF document retains its formattings.
+     * 
+     * @param elem The Element the RTF document is to be imported into.
+     * @param documentSource The Reader to read the RTF document from.
+     * @throws IOException On errors reading the RTF document.
+     * @throws DocumentException On errors adding to this RTF document.
+     * @since 2.1.4
+     */
+    public void importRtfDocumentIntoElement(Element elem, FileInputStream documentSource) throws IOException, DocumentException {
+    	importRtfDocumentIntoElement(elem, documentSource, null);
+    }
+    
+    /**
+     * Adds the complete RTF document to the current RTF element being generated.
+     * It will parse the font and color tables and correct the font and color references
+     * so that the imported RTF document retains its formattings.
+     * 
+     * @param elem The Element the RTF document is to be imported into.
+     * @param documentSource The Reader to read the RTF document from.
+     * @param events The event array for listeners.
+     * @throws IOException On errors reading the RTF document.
+     * @throws DocumentException On errors adding to this RTF document.
+     * @since 2.1.4
+     */
+    public void importRtfDocumentIntoElement(Element elem, FileInputStream documentSource, EventListener[] events) throws IOException, DocumentException {
+
+    	RtfParser rtfImport = new RtfParser(this.document);
+    	if(events != null) {
+    		for(int idx=0;idx<events.length;idx++) {
+        		rtfImport.addListener(events[idx]);
+    		}
+    	}
+    	rtfImport.importRtfDocumentIntoElement(elem, documentSource, rtfDoc);
+    }
+}
Index: src/core/com/lowagie/text/rtf/style/RtfFontList.java
===================================================================
--- src/core/com/lowagie/text/rtf/style/RtfFontList.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/style/RtfFontList.java	(revision 0)
@@ -0,0 +1,152 @@
+/*
+ * $Id: RtfFontList.java 3580 2008-08-06 15:52:00Z howard_s $
+ *
+ * Copyright 2001, 2002, 2003, 2004 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.rtf.style;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+
+import com.lowagie.text.DocWriter;
+import com.lowagie.text.rtf.RtfElement;
+import com.lowagie.text.rtf.RtfExtendedElement;
+import com.lowagie.text.rtf.document.RtfDocument;
+
+/**
+ * The RtfFontList stores the list of fonts used in the rtf document. It also
+ * has methods for writing this list to the document
+ *
+ * Version: $Id: RtfFontList.java 3580 2008-08-06 15:52:00Z howard_s $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Thomas Bickel (tmb99@inode.at)
+ */
+public class RtfFontList extends RtfElement implements RtfExtendedElement {
+    
+    /**
+     * Constant for the default font
+     */
+    private static final byte[] DEFAULT_FONT = DocWriter.getISOBytes("\\deff");
+    /**
+     * Constant for the font table
+     */
+    private static final byte[] FONT_TABLE = DocWriter.getISOBytes("\\fonttbl");
+    /**
+     * Constant for the font number
+     */
+    public static final byte[] FONT_NUMBER = DocWriter.getISOBytes("\\f");
+    
+    /**
+     * The list of fonts
+     */
+    private ArrayList fontList = new ArrayList();
+
+    /**
+     * Creates a RtfFontList
+     *
+     * @param doc The RtfDocument this RtfFontList belongs to
+     */
+    public RtfFontList(RtfDocument doc) {
+        super(doc);
+        fontList.add(new RtfFont(document, 0));
+    }
+
+    /**
+     * unused
+     */
+    public void writeContent(OutputStream out) throws IOException
+    {	
+    }
+    
+    /**
+     * Gets the index of the font in the list of fonts. If the font does not
+     * exist in the list, it is added.
+     *
+     * @param font The font to get the id for
+     * @return The index of the font
+     */
+    public int getFontNumber(RtfFont font) {
+        if(font instanceof RtfParagraphStyle) {
+            font = new RtfFont(this.document, font);
+        }
+        int fontIndex = -1;
+        for(int i = 0; i < fontList.size(); i++) {
+            if(fontList.get(i).equals(font)) {
+                fontIndex = i;
+            }
+        }
+        if(fontIndex == -1) {
+            fontIndex = fontList.size();
+            fontList.add(font);
+        }
+        return fontIndex;
+    }
+
+    /**
+     * Writes the definition of the font list
+     */
+    public void writeDefinition(final OutputStream result) throws IOException 
+    {
+        result.write(DEFAULT_FONT);
+        result.write(intToByteArray(0));
+        result.write(OPEN_GROUP);
+        result.write(FONT_TABLE);
+        for(int i = 0; i < fontList.size(); i++) {
+            result.write(OPEN_GROUP);
+            result.write(FONT_NUMBER);
+            result.write(intToByteArray(i));
+            RtfFont rf = (RtfFont) fontList.get(i);
+            rf.writeDefinition(result);
+            result.write(COMMA_DELIMITER);
+            result.write(CLOSE_GROUP);
+        }
+        result.write(CLOSE_GROUP);
+        this.document.outputDebugLinebreak(result);    	
+    }
+    
+}
Index: src/core/com/lowagie/text/rtf/table/RtfBorderGroup.java
===================================================================
--- src/core/com/lowagie/text/rtf/table/RtfBorderGroup.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/table/RtfBorderGroup.java	(revision 0)
@@ -0,0 +1,224 @@
+/*
+ * $Id: RtfBorderGroup.java 3427 2008-05-24 18:32:31Z xlv $
+ *
+ * Copyright 2001, 2002, 2003, 2004 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.rtf.table;
+
+import java.awt.Color;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map;
+
+import com.lowagie.text.Rectangle;
+import com.lowagie.text.rtf.RtfElement;
+import com.lowagie.text.rtf.document.RtfDocument;
+
+
+/**
+ * The RtfBorderGroup represents a collection of RtfBorders to use in a RtfCell
+ * or RtfTable.
+ * 
+ * @version $Id: RtfBorderGroup.java 3427 2008-05-24 18:32:31Z xlv $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Thomas Bickel (tmb99@inode.at)
+ */
+public class RtfBorderGroup extends RtfElement {
+    /**
+     * The type of borders this RtfBorderGroup contains.
+     * RtfBorder.ROW_BORDER or RtfBorder.CELL_BORDER
+     */
+    private int borderType = RtfBorder.ROW_BORDER;
+    /**
+     * The borders in this RtfBorderGroup
+     */
+    private Hashtable borders = null;
+
+    /**
+     * Constructs an empty RtfBorderGroup.
+     */
+    public RtfBorderGroup() {
+        super(null);
+        this.borders = new Hashtable();
+    }
+    
+    /**
+     * Constructs a RtfBorderGroup with on border style for multiple borders.
+     * 
+     * @param bordersToAdd The borders to add (Rectangle.LEFT, Rectangle.RIGHT, Rectangle.TOP, Rectangle.BOTTOM, Rectangle.BOX)
+     * @param borderStyle The style of border to add (from RtfBorder)
+     * @param borderWidth The border width to use
+     * @param borderColor The border color to use
+     */
+    public RtfBorderGroup(int bordersToAdd, int borderStyle, float borderWidth, Color borderColor) {
+        super(null);
+        this.borders = new Hashtable();
+        addBorder(bordersToAdd, borderStyle, borderWidth, borderColor);
+    }
+    
+    /**
+     * Constructs a RtfBorderGroup based on another RtfBorderGroup.
+     * 
+     * @param doc The RtfDocument this RtfBorderGroup belongs to
+     * @param borderType The type of borders this RtfBorderGroup contains
+     * @param borderGroup The RtfBorderGroup to use as a base
+     */
+    protected RtfBorderGroup(RtfDocument doc, int borderType, RtfBorderGroup borderGroup) {
+        super(doc);
+        this.borders = new Hashtable();
+        this.borderType = borderType;
+        if(borderGroup != null) {
+            Iterator it = borderGroup.getBorders().entrySet().iterator();
+            while(it.hasNext()) {
+                Map.Entry entry = (Map.Entry) it.next();
+                this.borders.put(entry.getKey(), new RtfBorder(this.document, this.borderType, (RtfBorder) entry.getValue()));
+            }
+        }
+    }
+    
+    /**
+     * Constructs a RtfBorderGroup with certain borders
+     * 
+     * @param doc The RtfDocument this RtfBorderGroup belongs to
+     * @param borderType The type of borders this RtfBorderGroup contains
+     * @param bordersToUse The borders to add (Rectangle.LEFT, Rectangle.RIGHT, Rectangle.TOP, Rectangle.BOTTOM, Rectangle.BOX)
+     * @param borderWidth The border width to use
+     * @param borderColor The border color to use
+     */
+    protected RtfBorderGroup(RtfDocument doc, int borderType, int bordersToUse, float borderWidth, Color borderColor) {
+        super(doc);
+        this.borderType = borderType;
+        this.borders = new Hashtable();
+        addBorder(bordersToUse, RtfBorder.BORDER_SINGLE, borderWidth, borderColor);
+    }
+    
+    /**
+     * Sets a border in the Hashtable of borders
+     * 
+     * @param borderPosition The position of this RtfBorder
+     * @param borderStyle The type of borders this RtfBorderGroup contains
+     * @param borderWidth The border width to use
+     * @param borderColor The border color to use
+     */
+    private void setBorder(int borderPosition, int borderStyle, float borderWidth, Color borderColor) {
+        RtfBorder border = new RtfBorder(this.document, this.borderType, borderPosition, borderStyle, borderWidth, borderColor);
+        this.borders.put(new Integer(borderPosition), border);
+    }
+    
+    /**
+     * Adds borders to the RtfBorderGroup
+     * 
+     * @param bordersToAdd The borders to add (Rectangle.LEFT, Rectangle.RIGHT, Rectangle.TOP, Rectangle.BOTTOM, Rectangle.BOX)
+     * @param borderStyle The style of border to add (from RtfBorder)
+     * @param borderWidth The border width to use
+     * @param borderColor The border color to use
+     */
+    public void addBorder(int bordersToAdd, int borderStyle, float borderWidth, Color borderColor) {
+        if((bordersToAdd & Rectangle.LEFT) == Rectangle.LEFT) {
+            setBorder(RtfBorder.LEFT_BORDER, borderStyle, borderWidth, borderColor);
+        }
+        if((bordersToAdd & Rectangle.TOP) == Rectangle.TOP) {
+            setBorder(RtfBorder.TOP_BORDER, borderStyle, borderWidth, borderColor);
+        }
+        if((bordersToAdd & Rectangle.RIGHT) == Rectangle.RIGHT) {
+            setBorder(RtfBorder.RIGHT_BORDER, borderStyle, borderWidth, borderColor);
+        }
+        if((bordersToAdd & Rectangle.BOTTOM) == Rectangle.BOTTOM) {
+            setBorder(RtfBorder.BOTTOM_BORDER, borderStyle, borderWidth, borderColor);
+        }
+        if((bordersToAdd & Rectangle.BOX) == Rectangle.BOX && this.borderType == RtfBorder.ROW_BORDER) {
+            setBorder(RtfBorder.VERTICAL_BORDER, borderStyle, borderWidth, borderColor);
+            setBorder(RtfBorder.HORIZONTAL_BORDER, borderStyle, borderWidth, borderColor);
+        }
+    }
+    
+    /**
+     * Removes borders from the list of borders
+     * 
+     * @param bordersToRemove The borders to remove (from Rectangle)
+     */
+    public void removeBorder(int bordersToRemove) {
+        if((bordersToRemove & Rectangle.LEFT) == Rectangle.LEFT) {
+            this.borders.remove(new Integer(RtfBorder.LEFT_BORDER));
+        }
+        if((bordersToRemove & Rectangle.TOP) == Rectangle.TOP) {
+            this.borders.remove(new Integer(RtfBorder.TOP_BORDER));
+        }
+        if((bordersToRemove & Rectangle.RIGHT) == Rectangle.RIGHT) {
+            this.borders.remove(new Integer(RtfBorder.RIGHT_BORDER));
+        }
+        if((bordersToRemove & Rectangle.BOTTOM) == Rectangle.BOTTOM) {
+            this.borders.remove(new Integer(RtfBorder.BOTTOM_BORDER));
+        }
+        if((bordersToRemove & Rectangle.BOX) == Rectangle.BOX && this.borderType == RtfBorder.ROW_BORDER) {
+            this.borders.remove(new Integer(RtfBorder.VERTICAL_BORDER));
+            this.borders.remove(new Integer(RtfBorder.HORIZONTAL_BORDER));
+        }
+    }
+    
+    /**
+     * Writes the borders of this RtfBorderGroup
+     */    
+    public void writeContent(final OutputStream result) throws IOException
+    {
+        Iterator it = this.borders.values().iterator();
+        while(it.hasNext()) {
+            ((RtfBorder) it.next()).writeContent(result);
+        }
+    }        
+    
+    /**
+     * Gets the RtfBorders of this RtfBorderGroup
+     * 
+     * @return The RtfBorders of this RtfBorderGroup
+     */
+    protected Hashtable getBorders() {
+        return this.borders;
+    }
+}
Index: src/core/com/lowagie/text/rtf/parser/destinations/RtfDestination.java
===================================================================
--- src/core/com/lowagie/text/rtf/parser/destinations/RtfDestination.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/parser/destinations/RtfDestination.java	(revision 0)
@@ -0,0 +1,264 @@
+/*
+ * $Id: RtfDestination.java 3373 2008-05-12 16:21:24Z xlv $
+ *
+ * Copyright 2007 by Howard Shank (hgshank@yahoo.com)
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+package com.lowagie.text.rtf.parser.destinations;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import com.lowagie.text.rtf.parser.RtfParser;
+import com.lowagie.text.rtf.parser.ctrlwords.RtfCtrlWordData;
+
+ /**
+  * <code>RtfDestination</code> is the base class for destinations according
+  * to the RTF Specification. All destinations must extend from this class.
+  * 
+  * @author Howard Shank (hgshank@yahoo.com
+  * 
+  * @since 2.0.8
+  */
+public abstract class RtfDestination {
+	/** Parser object */
+	protected RtfParser rtfParser = null;
+	
+	/** Is data in destination modified? */
+	protected boolean modified = false;
+
+	/** The last control word handled by this destination */
+	protected RtfCtrlWordData lastCtrlWord = null;;
+	
+	/** The <code>RtfDestinationListener</code>. */
+    private static ArrayList listeners = new ArrayList();
+    
+	/**
+	 * Constructor.
+	 */
+	public RtfDestination() {
+		rtfParser = null;
+	}
+	/**
+	 * Constructor
+	 * @param parser <code>RtfParser</code> object.
+	 */
+	public RtfDestination(RtfParser parser) {
+		this.rtfParser = parser;
+	}
+	/**
+	 * Set the parser to use with the RtfDestination object.
+	 * 
+	 * @param parser The RtfParser object.
+	 */
+	public void setParser(RtfParser parser) {
+		if(this.rtfParser != null && this.rtfParser.equals(parser)) return;
+		this.rtfParser = parser;
+	}
+	/**
+	 * Clean up when destination is closed.
+	 * @return true if handled, false if not handled
+	 */
+	public abstract boolean closeDestination();
+	/**
+	 * Handle a new subgroup contained within this group
+	 * @return true if handled, false if not handled
+	 */
+	public abstract boolean handleOpeningSubGroup();
+	/**
+	 * Clean up when group is closed.
+	 * @return true if handled, false if not handled
+	 */
+	public abstract boolean handleCloseGroup();
+
+	/**
+	 * Setup when group is opened.
+	 * @return true if handled, false if not handled
+	 */
+	public abstract boolean handleOpenGroup();
+	/**
+	 * Handle text for this destination
+	 * @return true if handled, false if not handled
+	 */
+	public abstract boolean handleCharacter(int ch);
+	/**
+	 * Handle control word for this destination
+	 * @param ctrlWordData The control word and parameter information object
+	 * @return true if handled, false if not handled
+	 */
+	public abstract boolean handleControlWord(RtfCtrlWordData ctrlWordData);
+	/**
+	 * Method to set this object to the default values. Must be implemented in child class.
+	 */
+	public abstract void setToDefaults();
+
+	/**
+	 * Method to indicate if data in this destination has changed.
+	 * @return true if modified, false if not modified.
+	 */
+	public boolean isModified() {
+		return modified;
+	}
+
+	// listener methods
+
+	/**
+	 * Adds a <CODE>RtfDestinationListener</CODE> to the <CODE>RtfDestinationMgr</CODE>.
+	 *
+	 * @param listener
+	 *            the new RtfDestinationListener.
+	 */
+	public boolean addListener(RtfDestinationListener listener) {
+		return listeners.add(listener);
+	}
+
+	/**
+	 * Removes a <CODE>RtfDestinationListener</CODE> from the <CODE>RtfDestinationMgr</CODE>.
+	 *
+	 * @param listener
+	 *            the RtfCtrlWordListener that has to be removed.
+	 */
+	public boolean removeListener(RtfDestinationListener listener) {
+		return listeners.remove(listener);
+	}
+	
+	protected RtfCtrlWordData beforeCtrlWord(RtfCtrlWordData ctrlWordData) {
+		RtfDestinationListener listener;
+		for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
+            listener = (RtfDestinationListener) iterator.next();
+            listener.beforeCtrlWord(ctrlWordData);
+        }
+		return null;
+	}
+	/**
+	 * 
+	 */
+	protected  RtfCtrlWordData onCtrlWord(RtfCtrlWordData ctrlWordData){
+		RtfDestinationListener listener;
+		for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
+            listener = (RtfDestinationListener) iterator.next();
+            listener.onCtrlWord(ctrlWordData);
+        }
+		return null;
+	}
+
+	/**
+	 * 
+	 */
+	protected  RtfCtrlWordData afterCtrlWord(RtfCtrlWordData ctrlWordData){
+		RtfDestinationListener listener;
+		for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
+            listener = (RtfDestinationListener) iterator.next();
+            listener.afterCtrlWord(ctrlWordData);
+        }
+		return null;
+	}
+
+	/**
+	 * 
+	 */
+	protected  int beforeCharacter(int ch){
+		RtfDestinationListener listener;
+		for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
+            listener = (RtfDestinationListener) iterator.next();
+            listener.beforeCharacter(ch);
+        }
+		return 0;
+	}
+
+	/**
+	 * 
+	 */
+	protected  int onCharacter(int ch){
+		RtfDestinationListener listener;
+		for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
+            listener = (RtfDestinationListener) iterator.next();
+            listener.onCharacter(ch);
+        }
+		return 0;
+	}
+
+	/**
+	 * 
+	 */
+	protected  int afterCharacter(int ch){
+		RtfDestinationListener listener;
+		for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
+            listener = (RtfDestinationListener) iterator.next();
+            listener.afterCharacter(ch);
+        }
+		return 0;
+	}
+
+	/**
+	 * 
+	 * @return true if all goes well
+	 */
+	protected  boolean onOpenGroup(){
+		RtfDestinationListener listener;
+		for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
+            listener = (RtfDestinationListener) iterator.next();
+            listener.onOpenGroup();
+        }
+		return true;
+	}
+
+	/**
+	 * 
+	 * @return true if all goes well
+	 */
+	protected  boolean onCloseGroup(){
+		RtfDestinationListener listener;
+		for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
+            listener = (RtfDestinationListener) iterator.next();
+            listener.onCloseGroup();
+        }
+		return true;
+	}
+	
+	public int getNewTokeniserState() {
+		return RtfParser.TOKENISER_IGNORE_RESULT;
+	}
+}
Index: src/core/com/lowagie/text/rtf/document/output/RtfEfficientMemoryCache.java
===================================================================
--- src/core/com/lowagie/text/rtf/document/output/RtfEfficientMemoryCache.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/document/output/RtfEfficientMemoryCache.java	(revision 0)
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2007 by Thomas Bickel
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.rtf.document.output;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * The RtfEfficientMemoryCache is an RtfDataCache that keeps the whole rtf document
+ * data in memory.
+ * More efficient than {@link RtfMemoryCache}.
+ * 
+ * @version $Id: RtfEfficientMemoryCache.java 3255 2008-04-14 18:33:30Z xlv $
+ * @author Thomas Bickel (tmb99@inode.at)
+ */
+public class RtfEfficientMemoryCache implements RtfDataCache 
+{
+    /**
+     * The buffer for the rtf document data.
+     */
+    private final RtfByteArrayBuffer bab;
+    
+    /**
+     * Constructs a RtfMemoryCache.
+     */
+    public RtfEfficientMemoryCache()
+    {
+        bab = new RtfByteArrayBuffer();
+    }
+    
+    /**
+     * Gets the OutputStream.
+     */
+    public OutputStream getOutputStream()
+    {
+        return bab;
+    }
+
+    /**
+     * Writes the content of the buffer into the OutputStream.
+     */
+    public void writeTo(OutputStream target) throws IOException 
+    {
+        bab.writeTo(target);
+    }
+
+}
Index: src/core/com/lowagie/text/rtf/parser/exceptions/RtfParserException.java
===================================================================
--- src/core/com/lowagie/text/rtf/parser/exceptions/RtfParserException.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/parser/exceptions/RtfParserException.java	(revision 0)
@@ -0,0 +1,175 @@
+/*
+ * $Id: RtfParserException.java 3373 2008-05-12 16:21:24Z xlv $
+ *
+ * Copyright 2007 by Howard Shank (hgshank@yahoo.com)
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+package com.lowagie.text.rtf.parser.exceptions;
+
+/*
+ * Signals that an error has occurred in a <CODE>RtfParser</CODE>.
+ */
+/**
+ * <code>RtfParserException</code> is the exception object thrown by
+ * the parser
+ * 
+ * @author Howard Shank (hgshank@yahoo.com)
+ * @since 2.0.8
+ */
+public class RtfParserException extends Exception {
+	private static final long serialVersionUID = 2857489935812968235L;
+	/**
+	 * Contained inner exception object.
+	 */
+	private Exception ex;
+
+    /**
+     * Creates a RtfParserException object.
+     * @param ex an exception that has to be turned into a RtfParserException
+     */
+    public RtfParserException(Exception ex) {
+        this.ex = ex;
+    }
+    
+    // constructors
+    
+    /**
+     * Constructs a <CODE>RtfParserException</CODE> whithout a message.
+     */
+    public RtfParserException() {
+        super();
+    }
+    
+    /**
+     * Constructs a <code>RtfParserException</code> with a message.
+     *
+     * @param		message			a message describing the exception
+     */
+    public RtfParserException(String message) {
+        super(message);
+    }
+
+    /**
+     * We print the message of the checked exception 
+     * @return the error message
+     */
+    public String getMessage() {
+        if (ex == null)
+            return super.getMessage();
+        else
+            return ex.getMessage();
+    }
+
+    /**
+     * and make sure we also produce a localized version 
+     * @return a localized message
+     */
+    public String getLocalizedMessage() {
+        if (ex == null)
+            return super.getLocalizedMessage();
+        else
+            return ex.getLocalizedMessage();
+    }
+
+    /**
+     * The toString() is changed to be prefixed with ExceptionConverter 
+     * @return the String version of the exception
+     */
+    public String toString() {
+        if (ex == null)
+            return super.toString();
+        else
+            return split(getClass().getName()) + ": " + ex;
+    }
+
+    /** we have to override this as well */
+    public void printStackTrace() {
+        printStackTrace(System.err);
+    }
+
+    /**
+     * here we prefix, with s.print(), not s.println(), the stack
+     * trace with "ExceptionConverter:" 
+     * @param s a printstream object
+     */
+    public void printStackTrace(java.io.PrintStream s) {
+        if (ex == null)
+            super.printStackTrace(s);
+        else {
+            synchronized (s) {
+                s.print(split(getClass().getName()) + ": ");
+                ex.printStackTrace(s);
+            }
+        }
+    }
+
+    /**
+     * Again, we prefix the stack trace with "ExceptionConverter:" 
+     * @param s A PrintWriter object
+     */
+    public void printStackTrace(java.io.PrintWriter s) {
+        if (ex == null)
+            super.printStackTrace(s);
+        else {
+            synchronized (s) {
+                s.print(split(getClass().getName()) + ": ");
+                ex.printStackTrace(s);
+            }
+        }
+    }
+
+    /**
+     * Removes everything in a String that comes before a '.'
+     * @param s the original string
+     * @return the part that comes after the dot
+     */
+    private static String split(String s) {
+        int i = s.lastIndexOf('.');
+        if (i < 0)
+            return s;
+        else
+            return s.substring(i + 1);
+    }
+}
Index: src/core/com/lowagie/text/rtf/parser/destinations/RtfDestinationInfo.java
===================================================================
--- src/core/com/lowagie/text/rtf/parser/destinations/RtfDestinationInfo.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/parser/destinations/RtfDestinationInfo.java	(revision 0)
@@ -0,0 +1,175 @@
+/*
+ * $Id: RtfDestinationInfo.java 3373 2008-05-12 16:21:24Z xlv $
+ *
+ * Copyright 2007 by Howard Shank (hgshank@yahoo.com)
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+ 
+package com.lowagie.text.rtf.parser.destinations;
+
+import com.lowagie.text.Document;
+import com.lowagie.text.Meta;
+import com.lowagie.text.rtf.document.RtfDocument;
+import com.lowagie.text.rtf.document.RtfInfoElement;
+import com.lowagie.text.rtf.parser.RtfParser;
+import com.lowagie.text.rtf.parser.ctrlwords.RtfCtrlWordData;
+
+/**
+ * <code>RtfDestinationInfo</code> handles data destined for the info destination
+ * 
+ * @author Howard Shank (hgshank@yahoo.com)
+ * @since 2.0.8
+ */
+public class RtfDestinationInfo extends RtfDestination {
+	private String elementName = "";
+	private String text = "";
+
+	
+	public RtfDestinationInfo() {
+		super(null);
+	}
+	/**
+	 * Constructs a new RtfDestinationInfo.
+	 * 
+	 * @param parser The RtfParser object.
+	 */
+	public RtfDestinationInfo(RtfParser parser, String elementname) {
+		super(parser);
+		setToDefaults();
+		this.elementName = elementname;
+	}
+	public void setParser(RtfParser parser) {
+		this.rtfParser = parser;
+		this.setToDefaults();
+	}
+	public void setElementName(String value) {
+		this.elementName = value;
+	}
+	/* (non-Javadoc)
+	 * @see com.lowagie.text.rtf.parser.destinations.RtfDestination#handleOpenNewGroup()
+	 */
+	public boolean handleOpeningSubGroup() {
+		return true;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.lowagie.text.rtf.direct.RtfDestination#closeDestination()
+	 */
+	public boolean closeDestination() {
+		return true;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.lowagie.text.rtf.direct.RtfDestination#handleGroupEnd()
+	 */
+	public boolean handleCloseGroup() {
+		if (this.text.length() > 0) {		
+			Document doc = this.rtfParser.getDocument();
+			if(doc != null) {
+				if(this.elementName.equals("author")){
+					doc.addAuthor(this.text);
+				}
+				if(this.elementName.equals("title")){
+					doc.addTitle(this.text);
+				}
+				if(this.elementName.equals("subject")){
+					doc.addSubject(this.text);
+				}
+			} else {
+				RtfDocument rtfDoc = this.rtfParser.getRtfDocument();
+				if(rtfDoc != null) {
+					if(this.elementName.equals("author")){
+						Meta meta = new Meta(this.elementName, this.text);
+						RtfInfoElement elem = new RtfInfoElement(rtfDoc, meta);
+						rtfDoc.getDocumentHeader().addInfoElement(elem);
+					}
+					if(this.elementName.equals("title")){
+						Meta meta = new Meta(this.elementName, this.text);
+						RtfInfoElement elem = new RtfInfoElement(rtfDoc, meta);
+						rtfDoc.getDocumentHeader().addInfoElement(elem);
+					}
+					if(this.elementName.equals("subject")){
+						Meta meta = new Meta(this.elementName, this.text);
+						RtfInfoElement elem = new RtfInfoElement(rtfDoc, meta);
+						rtfDoc.getDocumentHeader().addInfoElement(elem);
+					}
+				}
+			}
+			this.setToDefaults();
+		}
+		return true;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.lowagie.text.rtf.direct.RtfDestination#handleGroupStart()
+	 */
+	public boolean handleOpenGroup() {
+
+		return true;
+	}
+	/* (non-Javadoc)
+	 * @see com.lowagie.text.rtf.direct.RtfDestination#handleCharacter(char[])
+	 */
+	public boolean handleCharacter(int ch) {
+		this.text += (char)ch;
+		return true;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.lowagie.text.rtf.parser.destinations.RtfDestination#handleControlWord(com.lowagie.text.rtf.parser.ctrlwords.RtfCtrlWordData)
+	 */
+	public boolean handleControlWord(RtfCtrlWordData ctrlWordData) {
+		elementName = ctrlWordData.ctrlWord;
+		return true;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.lowagie.text.rtf.parser.destinations.RtfDestination#setToDefaults()
+	 */
+	public void setToDefaults() {
+		this.text = "";
+	}
+
+}
Index: src/core/com/lowagie/text/rtf/list/RtfListLevel.java
===================================================================
--- src/core/com/lowagie/text/rtf/list/RtfListLevel.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/list/RtfListLevel.java	(revision 0)
@@ -0,0 +1,824 @@
+/*
+ * $Id: RtfListLevel.java 3580 2008-08-06 15:52:00Z howard_s $
+ *
+ * Copyright 2008 by Howard Shank (hgshank@yahoo.com)
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+package com.lowagie.text.rtf.list;
+
+import java.awt.Color;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import com.lowagie.text.Chunk;
+import com.lowagie.text.DocWriter;
+import com.lowagie.text.Element;
+import com.lowagie.text.Font;
+import com.lowagie.text.rtf.RtfElement;
+import com.lowagie.text.rtf.RtfExtendedElement;
+import com.lowagie.text.rtf.document.RtfDocument;
+import com.lowagie.text.rtf.style.RtfColor;
+import com.lowagie.text.rtf.style.RtfFont;
+import com.lowagie.text.rtf.style.RtfFontList;
+import com.lowagie.text.rtf.style.RtfParagraphStyle;
+import com.lowagie.text.rtf.text.RtfParagraph;
+
+/**
+ * The RtfListLevel is a listlevel object in a list.
+ * 
+ * @version $Id: RtfListLevel.java 3580 2008-08-06 15:52:00Z howard_s $
+ * @author Howard Shank (hgshank@yahoo.com)
+ * @since 2.1.3
+ */
+public class RtfListLevel extends RtfElement implements RtfExtendedElement {
+    /**
+     * Constant for list level
+     */
+    private static final byte[] LIST_LEVEL = DocWriter.getISOBytes("\\listlevel");
+    /**
+     * Constant for list level
+     */
+    private static final byte[] LIST_LEVEL_TEMPLATE_ID = DocWriter.getISOBytes("\\leveltemplateid");
+    /**
+     * Constant for list level style old
+     */
+    private static final byte[] LIST_LEVEL_TYPE = DocWriter.getISOBytes("\\levelnfc");
+    /**
+     * Constant for list level style new
+     */
+    private static final byte[] LIST_LEVEL_TYPE_NEW = DocWriter.getISOBytes("\\levelnfcn");
+    /**
+     * Constant for list level alignment old
+     */
+    private static final byte[] LIST_LEVEL_ALIGNMENT = DocWriter.getISOBytes("\\leveljc");
+    /**
+     * Constant for list level alignment new
+     */
+    private static final byte[] LIST_LEVEL_ALIGNMENT_NEW = DocWriter.getISOBytes("\\leveljcn");
+    /**
+     * Constant for list level start at
+     */
+    private static final byte[] LIST_LEVEL_START_AT = DocWriter.getISOBytes("\\levelstartat");
+    /**
+     * Constant for list level text
+     */
+    private static final byte[] LIST_LEVEL_TEXT = DocWriter.getISOBytes("\\leveltext");
+    /**
+     * Constant for the beginning of the list level numbered style
+     */
+    private static final byte[] LIST_LEVEL_STYLE_NUMBERED_BEGIN = DocWriter.getISOBytes("\\\'02\\\'");
+    /**
+     * Constant for the end of the list level numbered style
+     */
+    private static final byte[] LIST_LEVEL_STYLE_NUMBERED_END = DocWriter.getISOBytes(".;");
+    /**
+     * Constant for the beginning of the list level bulleted style
+     */
+    private static final byte[] LIST_LEVEL_STYLE_BULLETED_BEGIN = DocWriter.getISOBytes("\\\'01");
+    /**
+     * Constant for the end of the list level bulleted style
+     */
+    private static final byte[] LIST_LEVEL_STYLE_BULLETED_END = DocWriter.getISOBytes(";");
+    /**
+     * Constant for the beginning of the list level numbers
+     */
+    private static final byte[] LIST_LEVEL_NUMBERS_BEGIN = DocWriter.getISOBytes("\\levelnumbers");
+    /**
+     * Constant which specifies which character follows the level text
+     */
+    private static final byte[] LIST_LEVEL_FOLOW = DocWriter.getISOBytes("\\levelfollow");
+    /**
+     * Constant which specifies the levelspace controlword
+     */
+    private static final byte[] LIST_LEVEL_SPACE = DocWriter.getISOBytes("\\levelspace");
+    /**
+     * Constant which specifies the levelindent control word
+     */
+    private static final byte[] LIST_LEVEL_INDENT = DocWriter.getISOBytes("\\levelindent");
+    /**
+     * Constant which specifies (1) if list numbers from previous levels should be converted
+     * to Arabic numbers; (0) if they should be left with the format specified by their
+     * own level's definition.
+     */
+    private static final byte[] LIST_LEVEL_LEGAL = DocWriter.getISOBytes("\\levellegal");
+    /**
+     * Constant which specifies 
+     * (1) if this level does/does not restart its count each time a super ordinate level is incremented
+     * (0) if this level does not restart its count each time a super ordinate level is incremented.
+     */
+    private static final byte[] LIST_LEVEL_NO_RESTART = DocWriter.getISOBytes("\\levelnorestart");
+    /**
+     * Constant for the list level numbers
+     */
+    private static final byte[] LIST_LEVEL_NUMBERS_NUMBERED = DocWriter.getISOBytes("\\\'01");
+    /**
+     * Constant for the end of the list level numbers
+     */
+    private static final byte[] LIST_LEVEL_NUMBERS_END = DocWriter.getISOBytes(";");
+    
+    /**
+     * Constant for the first indentation
+     */
+    private static final byte[] LIST_LEVEL_FIRST_INDENT = DocWriter.getISOBytes("\\fi");
+    /**
+     * Constant for the symbol indentation
+     */
+    private static final byte[] LIST_LEVEL_SYMBOL_INDENT = DocWriter.getISOBytes("\\tx");
+    
+    /**
+     * Constant for the lvltentative control word
+     */
+    private static final byte[] LIST_LEVEL_TENTATIVE = DocWriter.getISOBytes("\\lvltentative");
+    /**
+     * Constant for the levelpictureN control word
+     */
+    private static final byte[] LIST_LEVEL_PICTURE = DocWriter.getISOBytes("\\levelpicture");
+    
+
+    public static final int LIST_TYPE_NUMBERED = 1;
+    public static final int LIST_TYPE_UPPER_LETTERS = 2;
+    public static final int LIST_TYPE_LOWER_LETTERS = 3;
+    public static final int LIST_TYPE_UPPER_ROMAN = 4;
+    public static final int LIST_TYPE_LOWER_ROMAN = 5;
+
+    public static final int LIST_TYPE_UNKNOWN = -1; 					/* unknown type */
+    public static final int LIST_TYPE_BASE = 1000; 						/* BASE value to subtract to get RTF Value if above base*/
+    public static final int LIST_TYPE_ARABIC = 1000; 					/* 0 Arabic (1, 2, 3) */
+    public static final int LIST_TYPE_UPPERCASE_ROMAN_NUMERAL = 1001;	/* 1 Uppercase Roman numeral (I, II, III) */
+    public static final int LIST_TYPE_LOWERCASE_ROMAN_NUMERAL = 1002;	/* 2 Lowercase Roman numeral (i, ii, iii)*/
+    public static final int LIST_TYPE_UPPERCASE_LETTER = 1003;			/* 3 Uppercase letter (A, B, C)*/
+    public static final int LIST_TYPE_LOWERCASE_LETTER = 1004;			/* 4 Lowercase letter (a, b, c)*/
+    public static final int LIST_TYPE_ORDINAL_NUMBER = 1005;			/* 5 Ordinal number (1st, 2nd, 3rd)*/
+    public static final int LIST_TYPE_CARDINAL_TEXT_NUMBER = 1006;		/* 6 Cardinal text number (One, Two Three)*/
+    public static final int LIST_TYPE_ORDINAL_TEXT_NUMBER = 1007;		/* 7 Ordinal text number (First, Second, Third)*/
+    public static final int LIST_TYPE_ARABIC_LEADING_ZERO = 1022;		/* 22	Arabic with leading zero (01, 02, 03, ..., 10, 11)*/
+    public static final int LIST_TYPE_BULLET = 1023;					/* 23	Bullet (no number at all)*/
+    public static final int LIST_TYPE_NO_NUMBER = 1255;				/*  255	No number */
+/*
+ 
+10	Kanji numbering without the digit character (*dbnum1)
+11	Kanji numbering with the digit character (*dbnum2)
+12	46 phonetic katakana characters in "aiueo" order (*aiueo)
+13	46 phonetic katakana characters in "iroha" order (*iroha)
+14	Double-byte character
+15	Single-byte character
+16	Kanji numbering 3 (*dbnum3)
+17	Kanji numbering 4 (*dbnum4)
+18	Circle numbering (*circlenum)
+19	Double-byte Arabic numbering	
+20	46 phonetic double-byte katakana characters (*aiueo*dbchar)
+    21	46 phonetic double-byte katakana characters (*iroha*dbchar)
+    22	Arabic with leading zero (01, 02, 03, ..., 10, 11)
+    24	Korean numbering 2 (*ganada)
+    25	Korean numbering 1 (*chosung)
+    26	Chinese numbering 1 (*gb1)
+    27	Chinese numbering 2 (*gb2)
+    28	Chinese numbering 3 (*gb3)
+    29	Chinese numbering 4 (*gb4)
+    30	Chinese Zodiac numbering 1 (* zodiac1)
+    31	Chinese Zodiac numbering 2 (* zodiac2) 
+    32	Chinese Zodiac numbering 3 (* zodiac3)
+    33	Taiwanese double-byte numbering 1
+    34	Taiwanese double-byte numbering 2
+    35	Taiwanese double-byte numbering 3
+    36	Taiwanese double-byte numbering 4
+    37	Chinese double-byte numbering 1
+    38	Chinese double-byte numbering 2
+    39	Chinese double-byte numbering 3
+    40	Chinese double-byte numbering 4
+    41	Korean double-byte numbering 1
+    42	Korean double-byte numbering 2
+    43	Korean double-byte numbering 3
+    44	Korean double-byte numbering 4
+    45	Hebrew non-standard decimal 
+    46	Arabic Alif Ba Tah
+    47	Hebrew Biblical standard
+    48	Arabic Abjad style
+    255	No number
+*/
+    /**
+     * Whether this RtfList is numbered
+     */
+    private int listType = LIST_TYPE_UNKNOWN;
+
+    /**
+     * The text to use as the bullet character
+     */
+    private String bulletCharacter = "\u00b7"; 
+    /**
+     * @since 2.1.4
+     */
+    private Chunk bulletChunk = null;
+    /**
+     * The number to start counting at
+     */
+    private int listStartAt = 1;
+    /**
+     * The level of this RtfListLevel
+     */
+    private int listLevel = 0;
+    /**
+     * The first indentation of this RtfList
+     */
+    private int firstIndent = 0;
+    /**
+     * The left indentation of this RtfList
+     */
+    private int leftIndent = 0;
+    /**
+     * The right indentation of this RtfList
+     */
+    private int rightIndent = 0;
+    /**
+     * The symbol indentation of this RtfList
+     */
+    private int symbolIndent = 0;
+    /**
+     * Flag to indicate if the tentative control word should be emitted.
+     */
+    private boolean isTentative = true;
+    /**
+     * Flag to indicate if the levellegal control word should be emitted.
+     * true  if any list numbers from previous levels should be converted to Arabic numbers; 
+     * false if they should be left with the format specified by their own level definition.
+     */
+    private boolean isLegal = false;
+    
+    /**
+     * Does the list restart numbering each time a super ordinate level is incremented
+     */
+    private int listNoRestart = 0;
+    public static final int LIST_LEVEL_FOLLOW_TAB = 0; 
+    public static final int LIST_LEVEL_FOLLOW_SPACE = 1; 
+    public static final int LIST_LEVEL_FOLLOW_NOTHING = 2; 
+    private int levelFollowValue = LIST_LEVEL_FOLLOW_TAB;
+
+    /**
+     * The alignment of this RtfList
+     */
+    private int alignment = Element.ALIGN_LEFT;
+    /**
+     * Which picture bullet from the \listpicture destination should be applied
+     */
+    private int levelPicture = -1;
+    
+    private int levelTextNumber = 0;
+    /**
+     * The RtfFont for numbered lists
+     */
+    private RtfFont fontNumber;
+    /**
+     * The RtfFont for bulleted lists
+     */
+    private RtfFont fontBullet;
+    
+    private int templateID = -1;
+    
+    private RtfListLevel listLevelParent = null;
+    
+    /** 
+     * Parent list object
+     */
+    private RtfList parent = null;
+    
+	public RtfListLevel(RtfDocument doc)
+	{
+		super(doc);
+		templateID = document.getRandomInt();
+        setFontNumber( new RtfFont(document, new Font(Font.TIMES_ROMAN, 10, Font.NORMAL, new Color(0, 0, 0))));
+        setBulletFont(new Font(Font.SYMBOL, 10, Font.NORMAL, new Color(0, 0, 0)));
+	}
+	
+	public RtfListLevel(RtfDocument doc, RtfList parent)
+	{
+		super(doc);
+		this.parent = parent;
+		templateID = document.getRandomInt();
+		setFontNumber( new RtfFont(document, new Font(Font.TIMES_ROMAN, 10, Font.NORMAL, new Color(0, 0, 0))));
+        setBulletFont(new Font(Font.SYMBOL, 10, Font.NORMAL, new Color(0, 0, 0)));
+	}
+	
+	public RtfListLevel(RtfListLevel ll)
+	{
+		super(ll.document);
+		templateID = document.getRandomInt();
+		this.alignment = ll.alignment;
+		this.bulletCharacter = ll.bulletCharacter;
+		this.firstIndent = ll.firstIndent;
+		this.fontBullet = ll.fontBullet;
+		this.fontNumber = ll.fontNumber;
+		this.inHeader = ll.inHeader;
+		this.inTable = ll.inTable;
+		this.leftIndent = ll.leftIndent;
+		this.listLevel = ll.listLevel;
+		this.listNoRestart = ll.listNoRestart;
+		this.listStartAt = ll.listStartAt;
+		this.listType = ll.listType;
+		this.parent = ll.parent;
+		this.rightIndent = ll.rightIndent;
+		this.symbolIndent = ll.symbolIndent;
+	}
+
+	/**
+	 * @return the listNoRestart
+	 */
+	public int getListNoRestart() {
+		return listNoRestart;
+	}
+
+	/**
+	 * @param listNoRestart the listNoRestart to set
+	 */
+	public void setListNoRestart(int listNoRestart) {
+		this.listNoRestart = listNoRestart;
+	}
+
+	/**
+	 * @return the alignment
+	 */
+	public int getAlignment() {
+		return alignment;
+	}
+
+	/**
+	 * @param alignment the alignment to set
+	 */
+	public void setAlignment(int alignment) {
+		this.alignment = alignment;
+	}
+
+	public void writeDefinition(final OutputStream result) throws IOException {
+        result.write(OPEN_GROUP);
+        result.write(LIST_LEVEL);
+        result.write(LIST_LEVEL_TYPE);
+        switch(this.listType) {
+            case LIST_TYPE_BULLET        : result.write(intToByteArray(23)); break;
+            case LIST_TYPE_NUMBERED      : result.write(intToByteArray(0)); break;
+            case LIST_TYPE_UPPER_LETTERS : result.write(intToByteArray(3)); break;
+            case LIST_TYPE_LOWER_LETTERS : result.write(intToByteArray(4)); break;
+            case LIST_TYPE_UPPER_ROMAN   : result.write(intToByteArray(1)); break;
+            case LIST_TYPE_LOWER_ROMAN   : result.write(intToByteArray(2)); break;
+            /* New types */
+            case LIST_TYPE_ARABIC   	 : result.write(intToByteArray(0)); break;
+            case LIST_TYPE_UPPERCASE_ROMAN_NUMERAL   	 : result.write(intToByteArray(1)); break;
+            case LIST_TYPE_LOWERCASE_ROMAN_NUMERAL   	 : result.write(intToByteArray(2)); break;
+            case LIST_TYPE_UPPERCASE_LETTER   	 : result.write(intToByteArray(3)); break;
+            case LIST_TYPE_ORDINAL_NUMBER   	 : result.write(intToByteArray(4)); break;
+            case LIST_TYPE_CARDINAL_TEXT_NUMBER   	 : result.write(intToByteArray(5)); break;
+            case LIST_TYPE_ORDINAL_TEXT_NUMBER   	 : result.write(intToByteArray(6)); break;
+            case LIST_TYPE_LOWERCASE_LETTER   	 : result.write(intToByteArray(7)); break;
+            case LIST_TYPE_ARABIC_LEADING_ZERO   	 : result.write(intToByteArray(22)); break;
+            case LIST_TYPE_NO_NUMBER   	 : result.write(intToByteArray(255)); break;
+            default:	// catch all for other unsupported types
+            	if(this.listType >= RtfListLevel.LIST_TYPE_BASE) {
+            		result.write(intToByteArray(this.listType - RtfListLevel.LIST_TYPE_BASE));
+            	}
+            break;
+        }
+        
+        result.write(LIST_LEVEL_TYPE_NEW);
+        switch(this.listType) {
+            case LIST_TYPE_BULLET        : result.write(intToByteArray(23)); break;
+            case LIST_TYPE_NUMBERED      : result.write(intToByteArray(0)); break;
+            case LIST_TYPE_UPPER_LETTERS : result.write(intToByteArray(3)); break;
+            case LIST_TYPE_LOWER_LETTERS : result.write(intToByteArray(4)); break;
+            case LIST_TYPE_UPPER_ROMAN   : result.write(intToByteArray(1)); break;
+            case LIST_TYPE_LOWER_ROMAN   : result.write(intToByteArray(2)); break;
+            /* New types */
+            case LIST_TYPE_ARABIC   	 : result.write(intToByteArray(0)); break;
+            case LIST_TYPE_UPPERCASE_ROMAN_NUMERAL   	 : result.write(intToByteArray(1)); break;
+            case LIST_TYPE_LOWERCASE_ROMAN_NUMERAL   	 : result.write(intToByteArray(2)); break;
+            case LIST_TYPE_UPPERCASE_LETTER   	 : result.write(intToByteArray(3)); break;
+            case LIST_TYPE_ORDINAL_NUMBER   	 : result.write(intToByteArray(4)); break;
+            case LIST_TYPE_CARDINAL_TEXT_NUMBER   	 : result.write(intToByteArray(5)); break;
+            case LIST_TYPE_ORDINAL_TEXT_NUMBER   	 : result.write(intToByteArray(6)); break;
+            case LIST_TYPE_LOWERCASE_LETTER   	 : result.write(intToByteArray(7)); break;
+            case LIST_TYPE_ARABIC_LEADING_ZERO   	 : result.write(intToByteArray(22)); break;
+            case LIST_TYPE_NO_NUMBER   	 : result.write(intToByteArray(255)); break;
+            default:	// catch all for other unsupported types
+            	if(this.listType >= RtfListLevel.LIST_TYPE_BASE) {
+            		result.write(intToByteArray(this.listType - RtfListLevel.LIST_TYPE_BASE));
+            	}
+            break;
+        }
+        result.write(LIST_LEVEL_ALIGNMENT);
+        result.write(intToByteArray(0));
+        result.write(LIST_LEVEL_ALIGNMENT_NEW);
+        result.write(intToByteArray(0));
+        result.write(LIST_LEVEL_FOLOW);
+        result.write(intToByteArray(levelFollowValue));
+        result.write(LIST_LEVEL_START_AT);
+        result.write(intToByteArray(this.listStartAt));
+        if(this.isTentative) {
+            result.write(LIST_LEVEL_TENTATIVE);
+        }
+        if(this.isLegal) {
+            result.write(LIST_LEVEL_LEGAL);
+        }
+        result.write(LIST_LEVEL_SPACE);
+        result.write(intToByteArray(0));
+        result.write(LIST_LEVEL_INDENT);
+        result.write(intToByteArray(0));
+        if(levelPicture != -1) {
+            result.write(LIST_LEVEL_PICTURE);
+            result.write(intToByteArray(levelPicture));
+        }
+        
+        result.write(OPEN_GROUP); // { leveltext
+        result.write(LIST_LEVEL_TEXT);
+        result.write(LIST_LEVEL_TEMPLATE_ID);
+        result.write(intToByteArray(this.templateID));
+        /* NEVER seperate the LEVELTEXT elements with a return in between 
+         * them or it will not fuction correctly!
+         */
+        // TODO Needs to be rewritten to support 1-9 levels, not just simple single level
+        if(this.listType != LIST_TYPE_BULLET) {
+            result.write(LIST_LEVEL_STYLE_NUMBERED_BEGIN);
+            if(this.levelTextNumber < 10) {
+                result.write(intToByteArray(0));
+            }
+            result.write(intToByteArray(this.levelTextNumber));
+            result.write(LIST_LEVEL_STYLE_NUMBERED_END);
+        } else {
+            result.write(LIST_LEVEL_STYLE_BULLETED_BEGIN);
+            this.document.filterSpecialChar(result, this.bulletCharacter, false, false);
+            result.write(LIST_LEVEL_STYLE_BULLETED_END);
+        }
+        result.write(CLOSE_GROUP);	// } leveltext
+        
+        result.write(OPEN_GROUP);  // { levelnumbers
+        result.write(LIST_LEVEL_NUMBERS_BEGIN);
+        if(this.listType != LIST_TYPE_BULLET) {
+            result.write(LIST_LEVEL_NUMBERS_NUMBERED);
+        }
+        result.write(LIST_LEVEL_NUMBERS_END);
+        result.write(CLOSE_GROUP);// { levelnumbers
+        
+        // write properties now
+        result.write(RtfFontList.FONT_NUMBER);
+        if(this.listType != LIST_TYPE_BULLET) {
+            result.write(intToByteArray(fontNumber.getFontNumber()));
+        } else {
+            result.write(intToByteArray(fontBullet.getFontNumber()));
+        }
+        result.write(DocWriter.getISOBytes("\\cf"));
+//        document.getDocumentHeader().getColorNumber(new RtfColor(this.document,this.getFontNumber().getColor()));
+        result.write(intToByteArray(document.getDocumentHeader().getColorNumber(new RtfColor(this.document,this.getFontNumber().getColor()))));
+            
+        writeIndentation(result);
+        result.write(CLOSE_GROUP);
+        this.document.outputDebugLinebreak(result);
+        
+	}
+    /**
+     * unused
+     */    
+    public void writeContent(final OutputStream result) throws IOException
+    {
+    }     
+    
+    /**
+     * Writes only the list number and list level number.
+     * 
+     * @param result The <code>OutputStream</code> to write to
+     * @throws IOException On i/o errors.
+     */
+    protected void writeListNumbers(final OutputStream result) throws IOException {
+
+        if(listLevel > 0) {
+            result.write(RtfList.LIST_LEVEL_NUMBER);
+            result.write(intToByteArray(listLevel));
+        }
+    }
+    
+    
+    /**
+     * Write the indentation values for this <code>RtfList</code>.
+     * 
+     * @param result The <code>OutputStream</code> to write to.
+     * @throws IOException On i/o errors.
+     */
+    public void writeIndentation(final OutputStream result) throws IOException {
+        result.write(LIST_LEVEL_FIRST_INDENT);
+        result.write(intToByteArray(firstIndent));
+        result.write(RtfParagraphStyle.INDENT_LEFT);
+        result.write(intToByteArray(leftIndent));
+        result.write(RtfParagraphStyle.INDENT_RIGHT);
+        result.write(intToByteArray(rightIndent));
+        result.write(LIST_LEVEL_SYMBOL_INDENT);
+        result.write(intToByteArray(this.leftIndent));
+
+    }
+    /**
+     * Writes the initialization part of the RtfList
+     * 
+     * @param result The <code>OutputStream</code> to write to
+     * @throws IOException On i/o errors.
+     */
+    public void writeListBeginning(final OutputStream result) throws IOException {
+        result.write(RtfParagraph.PARAGRAPH_DEFAULTS);
+        if(this.inTable) {
+            result.write(RtfParagraph.IN_TABLE);
+        }
+        switch (this.alignment) {
+            case Element.ALIGN_LEFT:
+                result.write(RtfParagraphStyle.ALIGN_LEFT);
+                break;
+            case Element.ALIGN_RIGHT:
+                result.write(RtfParagraphStyle.ALIGN_RIGHT);
+                break;
+            case Element.ALIGN_CENTER:
+                result.write(RtfParagraphStyle.ALIGN_CENTER);
+                break;
+            case Element.ALIGN_JUSTIFIED:
+            case Element.ALIGN_JUSTIFIED_ALL:
+                result.write(RtfParagraphStyle.ALIGN_JUSTIFY);
+                break;
+        }
+        writeIndentation(result);
+        result.write(RtfFont.FONT_SIZE);
+        result.write(intToByteArray(fontNumber.getFontSize() * 2));
+        if(this.symbolIndent > 0) {
+            result.write(LIST_LEVEL_SYMBOL_INDENT);
+            result.write(intToByteArray(this.leftIndent));
+        }
+    }
+    /**
+     * Correct the indentation of this level
+     */
+    protected void correctIndentation() {
+
+        if(this.listLevelParent != null) {
+            this.leftIndent = this.leftIndent + this.listLevelParent.getLeftIndent() + this.listLevelParent.getFirstIndent();
+        }
+    }
+    /**
+     * Gets the list level of this RtfList
+     * 
+     * @return Returns the list level.
+     */
+    public int getListLevel() {
+        return listLevel;
+    }
+    
+    
+    /**
+     * Sets the list level of this RtfList. 
+     * 
+     * @param listLevel The list level to set.
+     */
+    public void setListLevel(int listLevel) {
+        this.listLevel = listLevel;
+    }
+    
+    
+	public String getBulletCharacter() {
+		return this.bulletCharacter;
+	}
+	/**
+	 * @return the listStartAt
+	 */
+	public int getListStartAt() {
+		return listStartAt;
+	}
+	/**
+	 * @param listStartAt the listStartAt to set
+	 */
+	public void setListStartAt(int listStartAt) {
+		this.listStartAt = listStartAt;
+	}
+
+	/**
+	 * @return the firstIndent
+	 */
+	public int getFirstIndent() {
+		return firstIndent;
+	}
+	/**
+	 * @param firstIndent the firstIndent to set
+	 */
+	public void setFirstIndent(int firstIndent) {
+		this.firstIndent = firstIndent;
+	}
+	/**
+	 * @return the leftIndent
+	 */
+	public int getLeftIndent() {
+		return leftIndent;
+	}
+	/**
+	 * @param leftIndent the leftIndent to set
+	 */
+	public void setLeftIndent(int leftIndent) {
+		this.leftIndent = leftIndent;
+	}
+	/**
+	 * @return the rightIndent
+	 */
+	public int getRightIndent() {
+		return rightIndent;
+	}
+	/**
+	 * @param rightIndent the rightIndent to set
+	 */
+	public void setRightIndent(int rightIndent) {
+		this.rightIndent = rightIndent;
+	}
+	/**
+	 * @return the symbolIndent
+	 */
+	public int getSymbolIndent() {
+		return symbolIndent;
+	}
+	/**
+	 * @param symbolIndent the symbolIndent to set
+	 */
+	public void setSymbolIndent(int symbolIndent) {
+		this.symbolIndent = symbolIndent;
+	}
+	/**
+	 * @return the parent
+	 */
+	public RtfList getParent() {
+		return parent;
+	}
+	/**
+	 * @param parent the parent to set
+	 */
+	public void setParent(RtfList parent) {
+		this.parent = parent;
+	}
+	/**
+	 * @param bulletCharacter the bulletCharacter to set
+	 */
+	public void setBulletCharacter(String bulletCharacter) {
+		this.bulletCharacter = bulletCharacter;
+	}
+	/**
+	 * 
+	 * @param bulletCharacter
+	 * @since 2.1.4
+	 */
+	public void setBulletChunk(Chunk bulletCharacter) {
+		this.bulletChunk = bulletCharacter;
+	}
+	/**
+	 * @return the listType
+	 */
+	public int getListType() {
+		return listType;
+	}
+	/**
+	 * @param listType the listType to set
+	 */
+	public void setListType(int listType) {
+		this.listType = listType;
+	}
+	/**
+	 * set the bullet font
+	 * @param f
+	 */
+	public void setBulletFont(Font f) {
+		this.fontBullet = new RtfFont(document, f);
+	}
+
+	/**
+	 * @return the fontNumber
+	 */
+	public RtfFont getFontNumber() {
+		return fontNumber;
+	}
+
+	/**
+	 * @param fontNumber the fontNumber to set
+	 */
+	public void setFontNumber(RtfFont fontNumber) {
+		this.fontNumber = fontNumber;
+	}
+
+	/**
+	 * @return the fontBullet
+	 */
+	public RtfFont getFontBullet() {
+		return fontBullet;
+	}
+
+	/**
+	 * @param fontBullet the fontBullet to set
+	 */
+	public void setFontBullet(RtfFont fontBullet) {
+		this.fontBullet = fontBullet;
+	}
+
+	/**
+	 * @return the isTentative
+	 */
+	public boolean isTentative() {
+		return isTentative;
+	}
+
+	/**
+	 * @param isTentative the isTentative to set
+	 */
+	public void setTentative(boolean isTentative) {
+		this.isTentative = isTentative;
+	}
+
+	/**
+	 * @return the isLegal
+	 */
+	public boolean isLegal() {
+		return isLegal;
+	}
+
+	/**
+	 * @param isLegal the isLegal to set
+	 */
+	public void setLegal(boolean isLegal) {
+		this.isLegal = isLegal;
+	}
+
+	/**
+	 * @return the levelFollowValue
+	 */
+	public int getLevelFollowValue() {
+		return levelFollowValue;
+	}
+
+	/**
+	 * @param levelFollowValue the levelFollowValue to set
+	 */
+	public void setLevelFollowValue(int levelFollowValue) {
+		this.levelFollowValue = levelFollowValue;
+	}
+
+	/**
+	 * @return the levelTextNumber
+	 */
+	public int getLevelTextNumber() {
+		return levelTextNumber;
+	}
+
+	/**
+	 * @param levelTextNumber the levelTextNumber to set
+	 */
+	public void setLevelTextNumber(int levelTextNumber) {
+		this.levelTextNumber = levelTextNumber;
+	}
+
+	/**
+	 * @return the listLevelParent
+	 */
+	public RtfListLevel getListLevelParent() {
+		return listLevelParent;
+	}
+
+	/**
+	 * @param listLevelParent the listLevelParent to set
+	 */
+	public void setListLevelParent(RtfListLevel listLevelParent) {
+		this.listLevelParent = listLevelParent;
+	}
+}
Index: src/core/com/lowagie/text/rtf/parser/properties/RtfProperty.java
===================================================================
--- src/core/com/lowagie/text/rtf/parser/properties/RtfProperty.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/parser/properties/RtfProperty.java	(revision 0)
@@ -0,0 +1,581 @@
+/* $Id: RtfProperty.java 3373 2008-05-12 16:21:24Z xlv $
+ *
+ * Copyright 2007 by Howard Shank (hgshank@yahoo.com)
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999-2006 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000-2006 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+package com.lowagie.text.rtf.parser.properties;
+
+import java.awt.Color;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+
+import com.lowagie.text.rtf.parser.ctrlwords.RtfCtrlWordData;
+
+/**
+ * <code>RtfProperty</code> handles document, paragraph, etc. property values
+ * 
+ * @author Howard Shank (hgshank@yahoo.com)
+ * @since 2.0.8
+ */
+public class RtfProperty {
+	public static final int OFF = 0;
+	public static final int ON = 1;
+	
+	/* property groups */
+	public static final String COLOR = "color.";
+	public static final String CHARACTER = "character.";
+	public static final String PARAGRAPH = "paragraph.";
+	public static final String SECTION = "section.";
+	public static final String DOCUMENT = "document.";
+	
+	/* color properties */
+	public static final String COLOR_FG = COLOR + "fg"; //Color Object
+	public static final String COLOR_BG = COLOR + "bg"; //Color Object
+	
+	/* character properties */
+	public static final String CHARACTER_BOLD = CHARACTER + "bold";	
+	public static final String CHARACTER_UNDERLINE = CHARACTER + "underline";
+	public static final String CHARACTER_ITALIC = CHARACTER + "italic";
+	public static final String CHARACTER_SIZE = CHARACTER + "size"; 
+	public static final String CHARACTER_FONT = CHARACTER + "font";
+	public static final String CHARACTER_STYLE = CHARACTER + "style";
+
+	/* paragraph properties */
+	/** Justify left */
+	public static final int JUSTIFY_LEFT = 0;
+	/** Justify right */
+	public static final int JUSTIFY_RIGHT = 1;
+	/** Justify center */
+	public static final int JUSTIFY_CENTER = 2;
+	/** Justify full */
+	public static final int JUSTIFY_FULL = 3;
+	
+	public static final String PARAGRAPH_INDENT_LEFT = PARAGRAPH + "indentLeft";	//  twips
+	public static final String PARAGRAPH_INDENT_RIGHT = PARAGRAPH + "indentRight";	// twips
+	public static final String PARAGRAPH_INDENT_FIRST_LINE = PARAGRAPH + "indentFirstLine";	// twips
+	public static final String PARAGRAPH_JUSTIFICATION = PARAGRAPH + "justification";
+	
+	public static final String PARAGRAPH_BORDER = PARAGRAPH + "border";
+	public static final String PARAGRAPH_BORDER_CELL = PARAGRAPH + "borderCell";
+	
+	/** possible border settting */
+	public static final int PARAGRAPH_BORDER_NIL = 0;
+	/** possible border settting */
+	public static final int PARAGRAPH_BORDER_BOTTOM = 1;
+	/** possible border settting */
+	public static final int PARAGRAPH_BORDER_TOP = 2;
+	/** possible border settting */
+	public static final int PARAGRAPH_BORDER_LEFT = 4;
+	/** possible border settting */
+	public static final int PARAGRAPH_BORDER_RIGHT = 8;
+	/** possible border settting */
+	public static final int PARAGRAPH_BORDER_DIAGONAL_UL_LR = 16;
+	/** possible border settting */
+	public static final int PARAGRAPH_BORDER_DIAGONAL_UR_LL = 32;
+	/** possible border settting */
+	public static final int PARAGRAPH_BORDER_TABLE_HORIZONTAL = 64;
+	/** possible border settting */
+	public static final int PARAGRAPH_BORDER_TABLE_VERTICAL = 128;
+	
+	/* section properties */
+	/** Decimal number format */
+	public static final int PGN_DECIMAL = 0; 
+	/** Uppercase Roman Numeral */
+	public static final int PGN_ROMAN_NUMERAL_UPPERCASE = 1;
+	/** Lowercase Roman Numeral */
+	public static final int PGN_ROMAN_NUMERAL_LOWERCASE = 2;
+	/** Uppercase Letter */
+	public static final int PGN_LETTER_UPPERCASE = 3;
+	/** Lowercase Letter */
+	public static final int PGN_LETTER_LOWERCASE = 4;
+	/** Section Break None */
+	public static final int SBK_NONE = 0;
+	/** Section Break Column break */
+	public static final int SBK_COLUMN = 1;
+	/** Section Break Even page break */
+	public static final int SBK_EVEN = 2;
+	/** Section Break Odd page break */
+	public static final int SBK_ODD = 3;
+	/** Section Break Page break */
+	public static final int SBK_PAGE = 4;
+	
+	public static final String SECTION_NUMBER_OF_COLUMNS =  SECTION + "numberOfColumns";
+	public static final String SECTION_BREAK_TYPE = SECTION + "SectionBreakType";
+	public static final String SECTION_PAGE_NUMBER_POSITION_X = SECTION + "pageNumberPositionX";
+	public static final String SECTION_PAGE_NUMBER_POSITION_Y = SECTION + "pageNumberPositionY";
+	public static final String SECTION_PAGE_NUMBER_FORMAT = SECTION + "pageNumberFormat";
+	
+	/* document properties */
+	/** Portrait orientation */
+	public static final String PAGE_PORTRAIT = "0";
+	/** Landscape orientation */
+	public static final String PAGE_LANDSCAPE = "1";
+	
+	public static final String DOCUMENT_PAGE_WIDTH_TWIPS = DOCUMENT + "pageWidthTwips";
+	public static final String DOCUMENT_PAGE_HEIGHT_TWIPS = DOCUMENT + "pageHeightTwips";
+	public static final String DOCUMENT_MARGIN_LEFT_TWIPS = DOCUMENT + "marginLeftTwips";
+	public static final String DOCUMENT_MARGIN_TOP_TWIPS = DOCUMENT + "marginTopTwips";
+	public static final String DOCUMENT_MARGIN_RIGHT_TWIPS = DOCUMENT + "marginRightTwips";
+	public static final String DOCUMENT_MARGIN_BOTTOM_TWIPS = DOCUMENT + "marginBottomTwips";
+	public static final String DOCUMENT_PAGE_NUMBER_START = DOCUMENT + "pageNumberStart";
+	public static final String DOCUMENT_ENABLE_FACING_PAGES = DOCUMENT + "enableFacingPages";
+	public static final String DOCUMENT_PAGE_ORIENTATION = DOCUMENT + "pageOrientation";
+	public static final String DOCUMENT_DEFAULT_FONT_NUMER = DOCUMENT + "defaultFontNumber";
+	
+	/** Properties for this RtfProperty object */
+	protected HashMap properties = new HashMap();
+	
+	private boolean modifiedCharacter = false; 
+	private boolean modifiedParagraph = false; 
+	private boolean modifiedSection = false; 
+	private boolean modifiedDocument = false; 
+
+	
+	/** The <code>RtfPropertyListener</code>. */
+    private ArrayList listeners = new ArrayList();
+	/**
+	 * Set all property objects to default values.
+	 * @since 2.0.8
+	 */
+	public void setToDefault() {
+		setToDefault(COLOR);
+		setToDefault(CHARACTER);
+		setToDefault(PARAGRAPH);
+		setToDefault(SECTION);
+		setToDefault(DOCUMENT);
+	}
+	/**
+	 * Set individual property group to default values.
+	 * @param propertyGroup <code>String</code> name of the property group to set to default.
+	 * @since 2.0.8
+	 */
+	public void setToDefault(String propertyGroup) {
+		if(COLOR.equals(propertyGroup)) {
+			setProperty(COLOR_FG, new Color(0,0,0));
+			setProperty(COLOR_BG, new Color(255,255,255));
+			return;
+		}
+		if(CHARACTER.equals(propertyGroup)) {
+			setProperty(CHARACTER_BOLD, 0);
+			setProperty(CHARACTER_UNDERLINE, 0);
+			setProperty(CHARACTER_ITALIC, 0);
+			setProperty(CHARACTER_SIZE, 24);// 1/2 pt sizes
+			setProperty(CHARACTER_FONT, 0);
+			return;
+		}
+		if(PARAGRAPH.equals(propertyGroup)) {
+			setProperty(PARAGRAPH_INDENT_LEFT, 0);
+			setProperty(PARAGRAPH_INDENT_RIGHT, 0);
+			setProperty(PARAGRAPH_INDENT_FIRST_LINE, 0);
+			setProperty(PARAGRAPH_JUSTIFICATION, JUSTIFY_LEFT);
+			setProperty(PARAGRAPH_BORDER, PARAGRAPH_BORDER_NIL);
+			setProperty(PARAGRAPH_BORDER_CELL, PARAGRAPH_BORDER_NIL);
+			return;
+		}
+		if(SECTION.equals(propertyGroup)) {
+			setProperty(SECTION_NUMBER_OF_COLUMNS, 0);
+			setProperty(SECTION_BREAK_TYPE, SBK_NONE);
+			setProperty(SECTION_PAGE_NUMBER_POSITION_X, 0);
+			setProperty(SECTION_PAGE_NUMBER_POSITION_Y, 0);
+			setProperty(SECTION_PAGE_NUMBER_FORMAT, PGN_DECIMAL);
+			return;
+		}
+		if(DOCUMENT.equals(propertyGroup)) {
+			setProperty(DOCUMENT_PAGE_WIDTH_TWIPS, 12240);
+			setProperty(DOCUMENT_PAGE_HEIGHT_TWIPS, 15480);
+			setProperty(DOCUMENT_MARGIN_LEFT_TWIPS, 1800);
+			setProperty(DOCUMENT_MARGIN_TOP_TWIPS, 1440);
+			setProperty(DOCUMENT_MARGIN_RIGHT_TWIPS, 1800);
+			setProperty(DOCUMENT_MARGIN_BOTTOM_TWIPS, 1440);
+			setProperty(DOCUMENT_PAGE_NUMBER_START, 1);
+			setProperty(DOCUMENT_ENABLE_FACING_PAGES, 1);
+			setProperty(DOCUMENT_PAGE_ORIENTATION, PAGE_PORTRAIT);
+			setProperty(DOCUMENT_DEFAULT_FONT_NUMER, 0);	
+			return;
+		}
+	}
+
+
+	/**
+	 * Toggle the value of the property identified by the <code>RtfCtrlWordData.specialHandler</code> parameter.
+	 * Toggle values are assumed to be integer values per the RTF spec with a value of 0=off or 1=on.
+	 * 
+	 * @param ctrlWordData The property name to set
+	 * @return <code>true</code> for handled or <code>false</code> if <code>propertyName</code> is <code>null</code> or <i>blank</i>
+	 */
+	public boolean toggleProperty(RtfCtrlWordData ctrlWordData) { //String propertyName) {
+		
+		String propertyName = ctrlWordData.specialHandler;
+		
+		if(propertyName == null || propertyName.length() == 0) return false;
+		
+		Object propertyValue = getProperty(propertyName);
+		if(propertyValue == null) {
+			propertyValue = new Integer(RtfProperty.ON);
+		} else {
+			if(propertyValue instanceof Integer) {
+				int value = ((Integer)propertyValue).intValue();
+				if(value != 0) {
+					removeProperty(propertyName);
+				}
+				return true;
+			} else {
+				if(propertyValue instanceof Long) {
+					long value = ((Long)propertyValue).intValue();
+					if(value != 0) {
+						removeProperty(propertyName);
+					}
+					return true;
+				}
+			}
+		}
+		setProperty(propertyName, propertyValue);
+		return true;
+	}
+	/**
+	 * Set the value of the property identified by the parameter.
+	 * 
+	 * @param ctrlWordData The controlword with the name to set
+	 * @return <code>true</code> for handled or <code>false</code> if <code>propertyName</code> or <code>propertyValue</code> is <code>null</code>
+	 */
+	public boolean setProperty(RtfCtrlWordData ctrlWordData) { //String propertyName, Object propertyValueNew) {
+		String propertyName = ctrlWordData.specialHandler;
+		Object propertyValueNew = ctrlWordData.param;
+		// depending on the control word, set mulitiple or reset settings, etc.
+		//if pard then reset settings
+		//
+		setProperty(propertyName, propertyValueNew);
+		return true;
+	}
+	/**
+	 * Set the value of the property identified by the parameter.
+	 * 
+	 * @param propertyName The property name to set
+	 * @param propertyValueNew The object to set the property value to
+	 * @return <code>true</code> for handled or <code>false</code> if <code>propertyName</code> or <code>propertyValue</code> is <code>null</code>
+	 */
+	private boolean setProperty(String propertyName, Object propertyValueNew) {
+		if(propertyName == null || propertyValueNew == null) return false;
+		
+		Object propertyValueOld = getProperty(propertyName);
+		if(propertyValueOld instanceof Integer && propertyValueNew instanceof Integer) {
+			int valueOld = ((Integer)propertyValueOld).intValue();
+			int valueNew = ((Integer)propertyValueNew).intValue();
+			if (valueOld==valueNew) return true;
+		} else {
+			if(propertyValueOld instanceof Long && propertyValueNew instanceof Long) {
+				long valueOld = ((Long)propertyValueOld).intValue();
+				long valueNew = ((Long)propertyValueNew).intValue();
+				if (valueOld==valueNew) return true;
+			}
+		}
+		beforeChange(propertyName);
+		properties.put(propertyName, propertyValueNew);
+		afterChange(propertyName);
+		setModified(propertyName, true);
+		return true;
+	}
+	/**
+	 * Set the value of the property identified by the parameter.
+	 * 
+	 * @param propertyName The property name to set
+	 * @param propertyValueNew The object to set the property value to
+	 * @return <code>true</code> for handled or <code>false</code> if <code>propertyName</code> is <code>null</code>
+	 */
+	private boolean setProperty(String propertyName, int propertyValueNew) {
+		if(propertyName == null) return false;
+		Object propertyValueOld = getProperty(propertyName);
+		if(propertyValueOld instanceof Integer) {
+			int valueOld = ((Integer)propertyValueOld).intValue();
+			if (valueOld==propertyValueNew) return true;
+		} 
+		beforeChange(propertyName);
+		properties.put(propertyName, new Integer(propertyValueNew));
+		afterChange(propertyName);
+		setModified(propertyName, true);
+		return true;
+	}
+	/**
+	 * Add the value of the property identified by the parameter.
+	 * 
+	 * @param propertyName The property name to set
+	 * @param propertyValue The object to set the property value to
+	 * @return <code>true</code> for handled or <code>false</code> if <code>propertyName</code> is <code>null</code>
+	 */
+	private boolean addToProperty(String propertyName, int propertyValue) {
+		if(propertyName == null) return false;
+		int value = ((Integer)properties.get(propertyName)).intValue();
+		if((value | propertyValue) == value) return true;
+		value |= propertyValue;
+		beforeChange(propertyName);
+		properties.put(propertyName, new Integer(value));
+		afterChange(propertyName);
+		setModified(propertyName, true);
+		return true;
+	}
+	/**
+	 * Set the value of the property identified by the parameter.
+	 * 
+	 * @param propertyName The property name to set
+	 * @param propertyValueNew The object to set the property value to
+	 * @return <code>true</code> for handled or <code>false</code> if <code>propertyName</code> is <code>null</code>
+	 */
+	private boolean setProperty(String propertyName, long propertyValueNew) {
+		if(propertyName == null) return false;
+		Object propertyValueOld = getProperty(propertyName);
+		if(propertyValueOld instanceof Long) {
+			long valueOld = ((Long)propertyValueOld).longValue();
+			if (valueOld==propertyValueNew) return true;
+		} 
+		beforeChange(propertyName);
+		properties.put(propertyName, new Long(propertyValueNew));
+		afterChange(propertyName);
+		setModified(propertyName, true);
+		return true;
+	}
+	/**
+	 * Add the value of the property identified by the parameter.
+	 * 
+	 * @param propertyName The property name to set
+	 * @param propertyValue The object to set the property value to
+	 * @return <code>true</code> for handled or <code>false</code> if <code>propertyName</code> is <code>null</code>
+	 */
+	private boolean addToProperty(String propertyName, long propertyValue) {
+		if(propertyName == null) return false;
+		long value = ((Long)properties.get(propertyName)).longValue();
+		if((value | propertyValue) == value) return true;
+		value |= propertyValue;
+		beforeChange(propertyName);
+		properties.put(propertyName, new Long(value));
+		afterChange(propertyName);
+		setModified(propertyName, true);
+		return true;
+	}
+	private boolean removeProperty(String propertyName) {
+		if(propertyName == null) return false;
+		if(properties.containsKey(propertyName)) {
+			beforeChange(propertyName);
+			properties.remove(propertyName);
+			afterChange(propertyName);
+			setModified(propertyName, true);
+		}
+		return true;
+	}
+	/**
+	 * Get the value of the property identified by the parameter.
+	 * 
+	 * @param propertyName String containing the property name to get
+	 * @return Property Object requested or null if not found in map.
+	 */
+	public Object getProperty(String propertyName) {
+		return properties.get(propertyName);
+	}
+	/**
+	 * Get a group of properties.
+	 * 
+	 * @param propertyGroup The group name to obtain.
+	 * @return Properties object with requested values.
+	 */
+	public HashMap getProperties(String propertyGroup) {
+		HashMap props = new HashMap();
+		if(!properties.isEmpty()) {
+			//properties.get
+			Iterator it = properties.keySet().iterator();
+			while(it.hasNext()) {
+				String key = (String)it.next();
+				if(key.startsWith(propertyGroup)) {
+					props.put(key, this.properties.get(key));
+				}
+			}
+		}
+		return props;
+	}
+	
+	/**
+	 * @return the modified
+	 */
+	public boolean isModified() {
+		return modifiedCharacter || modifiedParagraph || modifiedSection || modifiedDocument;
+	}
+	/**
+	 * @param propertyName the propertyName that is modified
+	 * @param modified the modified to set
+	 */
+	public void setModified(String propertyName, boolean modified) {
+		if(propertyName.startsWith(CHARACTER)) {
+			this.setModifiedCharacter(modified);
+		} else {
+			if(propertyName.startsWith(PARAGRAPH)) {
+				this.setModifiedParagraph(modified);
+			} else {
+				if(propertyName.startsWith(SECTION)) {
+					this.setModifiedSection(modified);
+				} else {
+					if(propertyName.startsWith(DOCUMENT)) {
+						this.setModifiedDocument(modified);
+					}
+				}
+			}
+		}
+	}
+	/**
+	 * @return the modifiedCharacter
+	 */
+	public boolean isModifiedCharacter() {
+		return modifiedCharacter;
+	}
+	/**
+	 * @param modifiedCharacter the modifiedCharacter to set
+	 */
+	public void setModifiedCharacter(boolean modifiedCharacter) {
+		this.modifiedCharacter = modifiedCharacter;
+	}
+	/**
+	 * @return the modifiedParagraph
+	 */
+	public boolean isModifiedParagraph() {
+		return modifiedParagraph;
+	}
+	/**
+	 * @param modifiedParagraph the modifiedParagraph to set
+	 */
+	public void setModifiedParagraph(boolean modifiedParagraph) {
+		this.modifiedParagraph = modifiedParagraph;
+	}
+	/**
+	 * @return the modifiedSection
+	 */
+	public boolean isModifiedSection() {
+		return modifiedSection;
+	}
+	/**
+	 * @param modifiedSection the modifiedSection to set
+	 */
+	public void setModifiedSection(boolean modifiedSection) {
+		this.modifiedSection = modifiedSection;
+	}
+	/**
+	 * @return the modifiedDocument
+	 */
+	public boolean isModifiedDocument() {
+		return modifiedDocument;
+	}
+	/**
+	 * @param modifiedDocument the modifiedDocument to set
+	 */
+	public void setModifiedDocument(boolean modifiedDocument) {
+		this.modifiedDocument = modifiedDocument;
+	}
+	
+	/**
+	 * Adds a <CODE>RtfPropertyListener</CODE> to the <CODE>RtfProperty</CODE>.
+	 *
+	 * @param listener
+	 *            the new RtfPropertyListener.
+	 */
+	public void addRtfPropertyListener(RtfPropertyListener listener) {
+		listeners.add(listener);
+	}
+	/**
+	 * Removes a <CODE>RtfPropertyListener</CODE> from the <CODE>RtfProperty</CODE>.
+	 *
+	 * @param listener
+	 *            the new RtfPropertyListener.
+	 */
+	public void removeRtfPropertyListener(RtfPropertyListener listener) {
+		listeners.remove(listener);
+	}
+	
+	public void beforeChange(String propertyName) {
+		// call listener for all
+		RtfPropertyListener listener;
+		for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
+            listener = (RtfPropertyListener) iterator.next();
+            listener.beforePropertyChange(propertyName);
+        }
+		
+		if(propertyName.startsWith(CHARACTER)) {
+			// call listener for character chane
+		} else {
+			if(propertyName.startsWith(PARAGRAPH)) {
+				// call listener for paragraph change
+			} else {
+				if(propertyName.startsWith(SECTION)) {
+					// call listener for section change
+				} else {
+					if(propertyName.startsWith(DOCUMENT)) {
+						// call listener for document change
+					}
+				}
+			}
+		}
+	}
+	
+	public void afterChange(String propertyName) {
+		// call listener for all
+		RtfPropertyListener listener;
+		for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
+            listener = (RtfPropertyListener) iterator.next();
+            listener.afterPropertyChange(propertyName);
+        }
+
+		if(propertyName.startsWith(CHARACTER)) {
+			// call listener for character chane
+		} else {
+			if(propertyName.startsWith(PARAGRAPH)) {
+				// call listener for paragraph change
+			} else {
+				if(propertyName.startsWith(SECTION)) {
+					// call listener for section change
+				} else {
+					if(propertyName.startsWith(DOCUMENT)) {
+						// call listener for document change
+					}
+				}
+			}
+		}
+	}
+}
Index: src/core/com/lowagie/text/rtf/document/RtfInfoGroup.java
===================================================================
--- src/core/com/lowagie/text/rtf/document/RtfInfoGroup.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/document/RtfInfoGroup.java	(revision 0)
@@ -0,0 +1,130 @@
+/*
+ * $Id: RtfInfoGroup.java 3580 2008-08-06 15:52:00Z howard_s $
+ *
+ * Copyright 2003, 2004 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.rtf.document;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+
+import com.lowagie.text.DocWriter;
+import com.lowagie.text.rtf.RtfElement;
+
+
+/**
+ * The RtfInfoGroup stores information group elements. 
+ * 
+ * @version $Id: RtfInfoGroup.java 3580 2008-08-06 15:52:00Z howard_s $
+ * @author Mark Hall (Mark.Hall@mail.room3b.eu)
+ * @author Thomas Bickel (tmb99@inode.at)
+ * @author Howard Shank (hgshank@yahoo.com)
+ */
+public class RtfInfoGroup extends RtfElement {
+    /**
+     * Information group starting tag
+     */
+    private static final byte[] INFO_GROUP = DocWriter.getISOBytes("\\info");
+    
+    /**
+     * Constant for the password element.
+     * Author: Howard Shank (hgshank@yahoo.com)
+     * @since 2.1.1
+     */
+    private static final byte[] INFO_PASSWORD = DocWriter.getISOBytes("\\*\\password");
+
+    /**
+     * The RtfInfoElements that belong to this RtfInfoGroup
+     */
+    ArrayList infoElements = null;
+    
+    /**
+     * Constructs a RtfInfoGroup belonging to a RtfDocument
+     * 
+     * @param doc The RtfDocument this RtfInfoGroup belongs to
+     */
+    public RtfInfoGroup(RtfDocument doc) {
+        super(doc);
+        infoElements = new ArrayList();
+    }
+    
+    /**
+     * Adds an RtfInfoElement to the RtfInfoGroup
+     * 
+     * @param infoElement The RtfInfoElement to add
+     */
+    public void add(RtfInfoElement infoElement) {
+        this.infoElements.add(infoElement);
+    }
+    
+    /**
+     * Writes the RTF information group and its elements.
+     */    
+    public void writeContent(final OutputStream result) throws IOException
+    {
+    	result.write(OPEN_GROUP);
+		result.write(INFO_GROUP);
+		for(int i = 0; i < infoElements.size(); i++) {
+			RtfInfoElement infoElement = (RtfInfoElement) infoElements.get(i);
+			infoElement.writeContent(result);
+		}
+		
+		// handle document protection
+    	if(document.getDocumentSettings().isDocumentProtected()) {
+	    	result.write(OPEN_GROUP);
+			result.write(INFO_PASSWORD);
+			result.write(DELIMITER);
+			result.write(document.getDocumentSettings().getProtectionHashBytes());
+			result.write(CLOSE_GROUP);
+    	}
+
+		result.write(CLOSE_GROUP);
+		this.document.outputDebugLinebreak(result);
+    }        
+    
+}
Index: src/core/com/lowagie/text/rtf/RtfMapper.java
===================================================================
--- src/core/com/lowagie/text/rtf/RtfMapper.java	(revision 0)
+++ src/core/com/lowagie/text/rtf/RtfMapper.java	(revision 0)
@@ -0,0 +1,205 @@
+/*
+ * $Id:RtfMapper.java 3126 2008-02-07 20:30:46Z hallm $
+ *
+ * Copyright 2003, 2004 by Mark Hall
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
+ * provisions of LGPL are applicable instead of those above.  If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.rtf;
+
+import java.util.ArrayList;
+
+import com.lowagie.text.Anchor;
+import com.lowagie.text.Annotation;
+import com.lowagie.text.Chapter;
+import com.lowagie.text.Chunk;
+import com.lowagie.text.DocumentException;
+import com.lowagie.text.Element;
+imp