[pdfmod] [PdfSharp] Update to svn r63489



commit 5701024530dcefc59f9168e8d469fb2325a51ee1
Author: Gabriel Burt <gabriel burt gmail com>
Date:   Fri Aug 27 11:52:51 2010 -0500

    [PdfSharp] Update to svn r63489

 lib/PdfSharp/!internal/Directives.cs               |   11 +-
 lib/PdfSharp/AgInternals/AgExtensions.cs           |   24 +
 lib/PdfSharp/AgInternals/AgHacks.cs                |  111 +
 lib/PdfSharp/AgInternals/DrawingContext.cs         |  280 +++
 lib/PdfSharp/AgInternals/DrawingVisual.cs          |   46 +
 lib/PdfSharp/AgInternals/Typeface.cs               |   26 +
 lib/PdfSharp/AssemblyInfo-AG.cs                    |   35 +
 lib/PdfSharp/PdfSharp-AG.csproj                    |  380 ++++
 lib/PdfSharp/PdfSharp-AG.csproj.resharper          |    6 +
 lib/PdfSharp/PdfSharp-Hybrid.csproj                |   47 +-
 lib/PdfSharp/PdfSharp-Hybrid.csproj.resharper      |    3 +
 lib/PdfSharp/PdfSharp-WPF.csproj                   |   50 +-
 lib/PdfSharp/PdfSharp-WPF.csproj.resharper         |    3 +
 lib/PdfSharp/PdfSharp.Drawing.BarCodes/BarCode.cs  |   14 +-
 .../PdfSharp.Drawing.BarCodes/BarCodeRenderInfo.cs |    2 +-
 lib/PdfSharp/PdfSharp.Drawing.BarCodes/BcgSR.cs    |    4 +-
 .../Code2of5Interleaved.cs                         |    6 +-
 .../PdfSharp.Drawing.BarCodes/Code3of9Standard.cs  |    6 +-
 lib/PdfSharp/PdfSharp.Drawing.BarCodes/CodeBase.cs |    7 +-
 .../PdfSharp.Drawing.BarCodes/CodeDataMatrix.cs    |    2 +-
 lib/PdfSharp/PdfSharp.Drawing.BarCodes/CodeOmr.cs  |    2 +-
 .../PdfSharp.Drawing.BarCodes/DataMatrixImage.cs   |    2 +-
 .../PdfSharp.Drawing.BarCodes/MatrixCode.cs        |    6 +-
 lib/PdfSharp/PdfSharp.Drawing.BarCodes/OmrData.cs  |    2 +-
 .../ThickThinBarcodeRenderer.cs                    |    6 +-
 .../PdfSharp.Drawing.BarCodes/enums/AnchorType.cs  |    2 +-
 .../enums/CodeDirection.cs                         |    2 +-
 .../PdfSharp.Drawing.BarCodes/enums/CodeType.cs    |    2 +-
 .../enums/DataMatrixEncoding.cs                    |    2 +-
 .../enums/MarkDistance.cs                          |    2 +-
 .../enums/TextLocation.cs                          |    2 +-
 .../PdfSharp.Drawing.Layout/XTextFormatter.cs      |   21 +-
 .../enums/XParagraphAlignment.cs                   |    2 +-
 .../PdfSharp.Drawing.Pdf/PdfGraphicsState.cs       |   17 +-
 .../PdfSharp.Drawing.Pdf/XGraphicsPdfRenderer.cs   |   41 +-
 .../PdfSharp.Drawing.Pdf/enums/DirtyFlags.cs       |    2 +-
 .../PdfSharp.Drawing.Pdf/enums/StreamMode.cs       |    2 +-
 lib/PdfSharp/PdfSharp.Drawing.Shapes/Shape.cs      |    2 +-
 lib/PdfSharp/PdfSharp.Drawing.Wpf/!info.txt        |    1 +
 lib/PdfSharp/PdfSharp.Drawing/FontHelper.cs        |  152 ++-
 lib/PdfSharp/PdfSharp.Drawing/GeometryHelper.cs    |  405 ++++-
 .../PdfSharp.Drawing/GraphicsStateStack.cs         |    2 +-
 .../PdfSharp.Drawing/IXGraphicsRenderer.cs         |    2 +-
 lib/PdfSharp/PdfSharp.Drawing/ImageHelper.cs       |    4 +-
 .../PdfSharp.Drawing/InternalGraphicsState.cs      |    7 +-
 lib/PdfSharp/PdfSharp.Drawing/PdfFontOptions.cs    |   10 +-
 lib/PdfSharp/PdfSharp.Drawing/XBrush.cs            |    2 +-
 lib/PdfSharp/PdfSharp.Drawing/XBrushes.cs          |    6 +-
 lib/PdfSharp/PdfSharp.Drawing/XColor.cs            |   10 +-
 .../PdfSharp.Drawing/XColorResourceManager.cs      |   84 +-
 lib/PdfSharp/PdfSharp.Drawing/XColors.cs           |    7 +-
 lib/PdfSharp/PdfSharp.Drawing/XConvert.cs          |    6 +-
 lib/PdfSharp/PdfSharp.Drawing/XFont.cs             |  167 ++-
 lib/PdfSharp/PdfSharp.Drawing/XFontFamily.cs       |   27 +-
 lib/PdfSharp/PdfSharp.Drawing/XFontMetrics.cs      |    2 +-
 lib/PdfSharp/PdfSharp.Drawing/XFontStretch.cs      |   57 +
 lib/PdfSharp/PdfSharp.Drawing/XFontWeight.cs       |  178 ++
 lib/PdfSharp/PdfSharp.Drawing/XFontWeights.cs      |  295 +++
 lib/PdfSharp/PdfSharp.Drawing/XForm.cs             |   39 +-
 lib/PdfSharp/PdfSharp.Drawing/XGlyphTypeface.cs    | 2272 ++++++++++++++++++++
 lib/PdfSharp/PdfSharp.Drawing/XGraphics.cs         |  314 ++-
 .../PdfSharp.Drawing/XGraphicsContainer.cs         |    2 +-
 lib/PdfSharp/PdfSharp.Drawing/XGraphicsPath.cs     |  305 +++-
 .../PdfSharp.Drawing/XGraphicsPathInternals.cs     |    2 +-
 lib/PdfSharp/PdfSharp.Drawing/XGraphicsPathItem.cs |    2 +-
 lib/PdfSharp/PdfSharp.Drawing/XGraphicsState.cs    |    2 +-
 lib/PdfSharp/PdfSharp.Drawing/XImage.cs            |  358 +++-
 lib/PdfSharp/PdfSharp.Drawing/XImageFormat.cs      |    2 +-
 lib/PdfSharp/PdfSharp.Drawing/XKnownColorTable.cs  |    2 +-
 .../PdfSharp.Drawing/XLinearGradientBrush.cs       |   60 +-
 lib/PdfSharp/PdfSharp.Drawing/XMatrix.cs           | 1016 +--------
 lib/PdfSharp/PdfSharp.Drawing/XPdfForm.cs          |   26 +-
 lib/PdfSharp/PdfSharp.Drawing/XPen.cs              |   14 +-
 lib/PdfSharp/PdfSharp.Drawing/XPens.cs             |    6 +-
 lib/PdfSharp/PdfSharp.Drawing/XPoint.cs            |  250 +---
 .../PdfSharp.Drawing/XPrivateFontCollection.cs     |  338 +++-
 lib/PdfSharp/PdfSharp.Drawing/XRect.cs             |  486 +----
 lib/PdfSharp/PdfSharp.Drawing/XSize.cs             |  259 +---
 lib/PdfSharp/PdfSharp.Drawing/XSolidBrush.cs       |    2 +-
 lib/PdfSharp/PdfSharp.Drawing/XStringFormat.cs     |    4 +-
 lib/PdfSharp/PdfSharp.Drawing/XStringFormats.cs    |    2 +-
 lib/PdfSharp/PdfSharp.Drawing/XTypeFace.cs         |  778 +++++++
 lib/PdfSharp/PdfSharp.Drawing/XUnit.cs             |   18 +-
 lib/PdfSharp/PdfSharp.Drawing/XVector.cs           |   11 +-
 lib/PdfSharp/PdfSharp.Drawing/enums/PathStart.cs   |    2 +-
 lib/PdfSharp/PdfSharp.Drawing/enums/XColorSpace.cs |    2 +-
 .../PdfSharp.Drawing/enums/XCombineMode.cs         |    2 +-
 lib/PdfSharp/PdfSharp.Drawing/enums/XDashStyle.cs  |    2 +-
 lib/PdfSharp/PdfSharp.Drawing/enums/XFillMode.cs   |    2 +-
 lib/PdfSharp/PdfSharp.Drawing/enums/XFontStyle.cs  |    2 +-
 .../PdfSharp.Drawing/enums/XGraphicRenderTarget.cs |    4 +-
 .../enums/XGraphicsPathItemType.cs                 |    2 +-
 .../enums/XGraphicsPdfPageOptions.cs               |    4 +-
 .../PdfSharp.Drawing/enums/XGraphicsUnit.cs        |    2 +-
 lib/PdfSharp/PdfSharp.Drawing/enums/XKnownColor.cs |    2 +-
 .../PdfSharp.Drawing/enums/XLineAlignment.cs       |    2 +-
 lib/PdfSharp/PdfSharp.Drawing/enums/XLineCap.cs    |    2 +-
 lib/PdfSharp/PdfSharp.Drawing/enums/XLineJoin.cs   |    2 +-
 .../PdfSharp.Drawing/enums/XLinearGradientMode.cs  |    2 +-
 .../PdfSharp.Drawing/enums/XMatrixOrder.cs         |    2 +-
 .../PdfSharp.Drawing/enums/XPageDirection.cs       |    2 +-
 .../PdfSharp.Drawing/enums/XSmoothingMode.cs       |    2 +-
 .../PdfSharp.Drawing/enums/XStringAlignment.cs     |    2 +-
 .../PdfSharp.Fonts.OpenType/ExternalHelper.cs      |   77 +
 lib/PdfSharp/PdfSharp.Fonts.OpenType/FontData.cs   |  Bin 0 -> 50144 bytes
 .../PdfSharp.Fonts.OpenType/FontDataStock.cs       |  145 ++
 .../PdfSharp.Fonts.OpenType/GenericFontTable.cs    |   74 +
 .../PdfSharp.Fonts.OpenType/GlyphDataTable.cs      |  Bin 0 -> 12450 bytes
 .../PdfSharp.Fonts.OpenType/IRefFontTable.cs       |   87 +
 .../IndexToLocationTable.cs                        |  Bin 0 -> 10378 bytes
 .../PdfSharp.Fonts.OpenType/OpenTypeDescriptor.cs  |  380 ++++
 .../PdfSharp.Fonts.OpenType/OpenTypeFontTable.cs   |  118 +
 .../PdfSharp.Fonts.OpenType/OpenTypeFontWriter.cs  |   62 +
 .../PdfSharp.Fonts.OpenType/OpenTypeStructures.cs  |  Bin 0 -> 71350 bytes
 .../PdfSharp.Fonts.OpenType/TableDirectoryEntry.cs |  Bin 0 -> 8222 bytes
 .../enums/FontTechnology.cs                        |   55 +
 .../PdfSharp.Fonts.OpenType/enums/TableTag.cs      |   38 +
 .../PdfSharp.Fonts.OpenType/enums/TableTagNames.cs |  212 ++
 lib/PdfSharp/PdfSharp.Fonts/AdobeGlyphList20.cs    |    6 +-
 .../PdfSharp.Fonts/AdobeGlyphListForNewFonts.cs    |    4 +-
 lib/PdfSharp/PdfSharp.Fonts/CMapInfo.cs            |   38 +-
 lib/PdfSharp/PdfSharp.Fonts/FontDescriptor.cs      |  330 +++
 lib/PdfSharp/PdfSharp.Fonts/FontDescriptorStock.cs |  548 +++++
 lib/PdfSharp/PdfSharp.Fonts/FontWriter.cs          |    5 +-
 lib/PdfSharp/PdfSharp.Forms/ColorComboBox.cs       |    2 +-
 lib/PdfSharp/PdfSharp.Forms/DeviceInfos.cs         |    2 +-
 lib/PdfSharp/PdfSharp.Forms/PagePreview.cs         |   60 +-
 lib/PdfSharp/PdfSharp.Forms/PagePreviewCanvas.cs   |    2 +-
 lib/PdfSharp/PdfSharp.Forms/enums/RenderMode.cs    |    2 +-
 lib/PdfSharp/PdfSharp.Forms/enums/Zoom.cs          |   10 +-
 lib/PdfSharp/PdfSharp.Internal/Calc.cs             |    2 +-
 lib/PdfSharp/PdfSharp.Internal/ColorHelper.cs      |    2 +-
 lib/PdfSharp/PdfSharp.Internal/DoubleUtil.cs       |    2 +-
 lib/PdfSharp/PdfSharp.Internal/NativeMethods.cs    |    4 +-
 lib/PdfSharp/PdfSharp.Internal/TokenizerHelper.cs  |   19 +-
 .../PdfSharp.Pdf.AcroForms/PdfAcroField.cs         |   33 +-
 lib/PdfSharp/PdfSharp.Pdf.AcroForms/PdfAcroForm.cs |    4 +-
 .../PdfSharp.Pdf.AcroForms/PdfButtonField.cs       |   13 +-
 .../PdfSharp.Pdf.AcroForms/PdfCheckBoxField.cs     |    2 +-
 .../PdfSharp.Pdf.AcroForms/PdfChoiceField.cs       |  170 ++
 .../PdfSharp.Pdf.AcroForms/PdfComboBoxField.cs     |    4 +-
 .../PdfSharp.Pdf.AcroForms/PdfGenericField.cs      |    2 +-
 .../PdfSharp.Pdf.AcroForms/PdfListBoxField.cs      |    4 +-
 .../PdfSharp.Pdf.AcroForms/PdfPushButtonField.cs   |    2 +-
 .../PdfSharp.Pdf.AcroForms/PdfRadioButtonField.cs  |    4 +-
 .../PdfSharp.Pdf.AcroForms/PdfSignatureField.cs    |    6 +-
 .../PdfSharp.Pdf.AcroForms/PdfTextField.cs         |    4 +-
 .../enums/PdfAcroFieldFlags.cs                     |    6 +-
 lib/PdfSharp/PdfSharp.Pdf.Actions/PdfAction.cs     |    6 +-
 .../enums/PdfNamedActionNames.cs                   |    2 +-
 .../PdfSharp.Pdf.Advanced/IContentStream.cs        |    2 +-
 lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfCIDFont.cs   |  Bin 19510 -> 20074 bytes
 lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfCatalog.cs   |    8 +-
 lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfContent.cs   |    6 +-
 lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfContents.cs  |    2 +-
 .../PdfDictionaryWithContentStream.cs              |    6 +-
 lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfExtGState.cs |    4 +-
 .../PdfSharp.Pdf.Advanced/PdfExtGStateTable.cs     |   27 +-
 lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfFont.cs      |   10 +-
 .../PdfSharp.Pdf.Advanced/PdfFontDescriptor.cs     |   14 +-
 lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfFontTable.cs |   35 +-
 .../PdfSharp.Pdf.Advanced/PdfFormXObject.cs        |    8 +-
 .../PdfSharp.Pdf.Advanced/PdfFormXObjectTable.cs   |   31 +-
 .../PdfSharp.Pdf.Advanced/PdfGroupAttributes.cs    |    4 +-
 .../PdfSharp.Pdf.Advanced/PdfImage.FaxEncode.cs    |  900 ++++++++
 lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfImage.cs     |  500 ++++--
 .../PdfSharp.Pdf.Advanced/PdfImageTable.cs         |   15 +-
 .../PdfImportedObjectTable.cs                      |   13 +-
 lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfInternals.cs |   43 +-
 .../PdfSharp.Pdf.Advanced/PdfObjectInternals.cs    |   94 +
 .../PdfPageInheritableObjects.cs                   |    2 +-
 lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfReference.cs |   13 +-
 .../PdfSharp.Pdf.Advanced/PdfResourceMap.cs        |    9 +-
 .../PdfSharp.Pdf.Advanced/PdfResourceTable.cs      |    4 +-
 lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfResources.cs |   59 +-
 lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfShading.cs   |    4 +-
 .../PdfSharp.Pdf.Advanced/PdfShadingPattern.cs     |    4 +-
 .../PdfSharp.Pdf.Advanced/PdfShadingTable.cs       |    2 +-
 lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfSoftMask.cs  |    4 +-
 .../PdfSharp.Pdf.Advanced/PdfTilingPattern.cs      |    4 +-
 .../PdfSharp.Pdf.Advanced/PdfToUnicodeMap.cs       |   14 +-
 lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfTrailer.cs   |   13 +-
 .../PdfTransparencyGroupAttributes.cs              |    4 +-
 .../PdfSharp.Pdf.Advanced/PdfTrueTypeFont.cs       |    6 +-
 lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfType0Font.cs |   39 +-
 lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfType1Font.cs |    2 +-
 lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfXObject.cs   |    4 +-
 .../PdfSharp.Pdf.Annotations/PdfAnnotation.cs      |    6 +-
 .../PdfSharp.Pdf.Annotations/PdfAnnotations.cs     |   27 +-
 .../PdfGenericAnnotation.cs                        |    2 +-
 .../PdfSharp.Pdf.Annotations/PdfLinkAnnotation.cs  |   13 +-
 .../PdfRubberStampAnnotation.cs                    |    4 +-
 .../PdfSharp.Pdf.Annotations/PdfTextAnnotation.cs  |    4 +-
 .../PdfWidgetAnnotation.cs                         |    2 +-
 .../enums/PdfAnnotationFlags.cs                    |    2 +-
 .../enums/PdfRubberStampAnnotationIcon.cs          |    2 +-
 .../enums/PdfTextAnnotationIcon.cs                 |    2 +-
 .../PdfSharp.Pdf.Content.Objects/CObjects.cs       |  270 ++-
 .../PdfSharp.Pdf.Content.Objects/Operators.cs      |   21 +-
 .../enum/OpCodeFlags.cs                            |    2 +-
 .../enum/OpCodeName.cs                             |    5 +-
 lib/PdfSharp/PdfSharp.Pdf.Content/CLexer.cs        |  Bin 38282 -> 38598 bytes
 lib/PdfSharp/PdfSharp.Pdf.Content/CParser.cs       |   15 +-
 lib/PdfSharp/PdfSharp.Pdf.Content/Chars.cs         |    8 +-
 lib/PdfSharp/PdfSharp.Pdf.Content/ContentReader.cs |    4 +-
 .../PdfSharp.Pdf.Content/ContentReaderException.cs |    2 +-
 lib/PdfSharp/PdfSharp.Pdf.Content/ContentWriter.cs |    5 +-
 lib/PdfSharp/PdfSharp.Pdf.Content/enums/Symbol.cs  |    2 +-
 lib/PdfSharp/PdfSharp.Pdf.Filters/ASCII85Decode.cs |   36 +-
 .../PdfSharp.Pdf.Filters/ASCIIHexDecode.cs         |    2 +-
 lib/PdfSharp/PdfSharp.Pdf.Filters/Filter.cs        |    4 +-
 lib/PdfSharp/PdfSharp.Pdf.Filters/Filtering.cs     |    2 +-
 lib/PdfSharp/PdfSharp.Pdf.Filters/FlateDecode.cs   |    2 +-
 lib/PdfSharp/PdfSharp.Pdf.Filters/LzwDecode.cs     |   13 +-
 lib/PdfSharp/PdfSharp.Pdf.IO/Chars.cs              |    6 +-
 lib/PdfSharp/PdfSharp.Pdf.IO/Lexer.cs              |   34 +-
 lib/PdfSharp/PdfSharp.Pdf.IO/Parser.cs             |   18 +-
 lib/PdfSharp/PdfSharp.Pdf.IO/PdfReader.cs          |   43 +-
 lib/PdfSharp/PdfSharp.Pdf.IO/PdfReaderException.cs |    2 +-
 lib/PdfSharp/PdfSharp.Pdf.IO/PdfWriter.cs          |    8 +-
 lib/PdfSharp/PdfSharp.Pdf.IO/ShiftStack.cs         |   13 +-
 .../PdfSharp.Pdf.IO/enums/PasswordValidity.cs      |   54 +
 .../PdfSharp.Pdf.IO/enums/PdfDocumentOpenMode.cs   |    4 +-
 .../PdfSharp.Pdf.IO/enums/PdfWriterLayout.cs       |    8 +-
 .../PdfSharp.Pdf.IO/enums/PdfWriterOptions.cs      |    2 +-
 lib/PdfSharp/PdfSharp.Pdf.IO/enums/Symbol.cs       |    2 +-
 lib/PdfSharp/PdfSharp.Pdf.Internal/AnsiEncoding.cs |    2 +-
 .../PdfSharp.Pdf.Internal/ColorSpaceHelper.cs      |    4 +-
 lib/PdfSharp/PdfSharp.Pdf.Internal/DocEncoding.cs  |   25 +-
 .../PdfSharp.Pdf.Internal/GlobalObjectTable.cs     |    5 +-
 lib/PdfSharp/PdfSharp.Pdf.Internal/PdfEncoders.cs  |   69 +-
 lib/PdfSharp/PdfSharp.Pdf.Internal/RawEncoding.cs  |    6 +-
 .../PdfSharp.Pdf.Internal/RawUnicodeEncoding.cs    |    2 +-
 .../PdfSharp.Pdf.Internal/ThreadLocalStorage.cs    |   19 +-
 .../PdfSharp.Pdf.Printing/PdfFilePrinter.cs        |    8 +-
 .../PdfSharp.Pdf.Security/PdfSecurityHandler.cs    |    2 +-
 .../PdfSharp.Pdf.Security/PdfSecuritySettings.cs   |    6 +-
 .../PdfStandardSecurityHandler.cs                  |   71 +-
 .../enums/PdfDocumentSecurity.cs                   |    2 +-
 .../enums/PdfUserAccessPermission.cs               |    2 +-
 lib/PdfSharp/PdfSharp.Pdf/EntryInfoAttribute.cs    |    4 +-
 lib/PdfSharp/PdfSharp.Pdf/KeysBase.cs              |    2 +-
 lib/PdfSharp/PdfSharp.Pdf/KeysMeta.cs              |   12 +-
 lib/PdfSharp/PdfSharp.Pdf/PdfArray.cs              |  115 +-
 lib/PdfSharp/PdfSharp.Pdf/PdfBoolean.cs            |    2 +-
 lib/PdfSharp/PdfSharp.Pdf/PdfBooleanObject.cs      |    2 +-
 lib/PdfSharp/PdfSharp.Pdf/PdfCustomValue.cs        |   12 +-
 lib/PdfSharp/PdfSharp.Pdf/PdfCustomValues.cs       |    4 +-
 lib/PdfSharp/PdfSharp.Pdf/PdfDate.cs               |    2 +-
 lib/PdfSharp/PdfSharp.Pdf/PdfDictionary.cs         |  295 ++--
 lib/PdfSharp/PdfSharp.Pdf/PdfDocument.cs           |   39 +-
 .../PdfSharp.Pdf/PdfDocumentInformation.cs         |    4 +-
 lib/PdfSharp/PdfSharp.Pdf/PdfDocumentOptions.cs    |    2 +-
 lib/PdfSharp/PdfSharp.Pdf/PdfDocumentSettings.cs   |   20 +-
 lib/PdfSharp/PdfSharp.Pdf/PdfInteger.cs            |    4 +-
 lib/PdfSharp/PdfSharp.Pdf/PdfIntegerObject.cs      |    2 +-
 lib/PdfSharp/PdfSharp.Pdf/PdfItem.cs               |   10 +-
 lib/PdfSharp/PdfSharp.Pdf/PdfLiteral.cs            |    6 +-
 lib/PdfSharp/PdfSharp.Pdf/PdfName.cs               |   11 +-
 lib/PdfSharp/PdfSharp.Pdf/PdfNameObject.cs         |    2 +-
 lib/PdfSharp/PdfSharp.Pdf/PdfNull.cs               |    2 +-
 lib/PdfSharp/PdfSharp.Pdf/PdfNullObject.cs         |    2 +-
 lib/PdfSharp/PdfSharp.Pdf/PdfNumber.cs             |    2 +-
 lib/PdfSharp/PdfSharp.Pdf/PdfNumberObject.cs       |    6 +-
 lib/PdfSharp/PdfSharp.Pdf/PdfObject.cs             |   81 +-
 lib/PdfSharp/PdfSharp.Pdf/PdfObjectID.cs           |    2 +-
 lib/PdfSharp/PdfSharp.Pdf/PdfOutline.cs            |    7 +-
 lib/PdfSharp/PdfSharp.Pdf/PdfPage.cs               |   80 +-
 lib/PdfSharp/PdfSharp.Pdf/PdfPages.cs              |   41 +-
 lib/PdfSharp/PdfSharp.Pdf/PdfReal.cs               |    2 +-
 lib/PdfSharp/PdfSharp.Pdf/PdfRealObject.cs         |    2 +-
 lib/PdfSharp/PdfSharp.Pdf/PdfRectangle.cs          |    6 +-
 lib/PdfSharp/PdfSharp.Pdf/PdfReferenceTable.cs     |   84 +-
 lib/PdfSharp/PdfSharp.Pdf/PdfString.cs             |   68 +-
 lib/PdfSharp/PdfSharp.Pdf/PdfStringObject.cs       |   19 +-
 lib/PdfSharp/PdfSharp.Pdf/PdfUInteger.cs           |    2 +-
 lib/PdfSharp/PdfSharp.Pdf/PdfUIntegerObject.cs     |    2 +-
 lib/PdfSharp/PdfSharp.Pdf/PdfViewerPreferences.cs  |    2 +-
 lib/PdfSharp/PdfSharp.Pdf/TrimMargins.cs           |    2 +-
 lib/PdfSharp/PdfSharp.Pdf/enums/DocumentState.cs   |    5 +-
 lib/PdfSharp/PdfSharp.Pdf/enums/PdfColorMode.cs    |    2 +-
 .../enums/PdfCustomValueCompression.cs             |    6 +-
 .../PdfSharp.Pdf/enums/PdfFontEmbedding.cs         |    2 +-
 lib/PdfSharp/PdfSharp.Pdf/enums/PdfFontEncoding.cs |    2 +-
 lib/PdfSharp/PdfSharp.Pdf/enums/PdfOutlineStyle.cs |    2 +-
 lib/PdfSharp/PdfSharp.Pdf/enums/PdfPageLayout.cs   |    2 +-
 lib/PdfSharp/PdfSharp.Pdf/enums/PdfPageMode.cs     |    2 +-
 .../PdfSharp.Pdf/enums/PdfReadingDirection.cs      |    2 +-
 .../PdfSharp.Pdf/enums/PdfTextStringEncoding.cs    |    2 +-
 .../PdfSharp.SharpZipLib/Checksums/Adler32.cs      |  325 ++--
 .../Zip/Compression/Deflater.cs                    | 1054 +++++-----
 .../Zip/Compression/DeflaterHuffman.cs             | 1744 ++++++++-------
 .../Zip/Compression/DeflaterPending.cs             |   33 +-
 .../Zip/Compression/Inflater.cs                    | 1548 +++++++-------
 .../Zip/Compression/InflaterHuffmanTree.cs         |   14 +-
 .../Zip/Compression/PendingBuffer.cs               |  465 +++--
 .../Compression/Streams/DeflaterOutputStream.cs    |    6 +-
 .../Zip/Compression/Streams/InflaterInputStream.cs |  968 +++++----
 .../Zip/Compression/Streams/OutputWindow.cs        |  389 ++--
 .../Zip/Compression/Streams/StreamManipulator.cs   |  468 +++--
 lib/PdfSharp/PdfSharp.Windows/enums/RenderMode.cs  |   26 +-
 lib/PdfSharp/PdfSharp.Windows/enums/Zoom.cs        |    4 +-
 lib/PdfSharp/PdfSharp.csproj                       |  175 +-
 lib/PdfSharp/PdfSharp.csproj.resharper             |    3 +
 lib/PdfSharp/PdfSharp/PSSR.cs                      |   31 +-
 lib/PdfSharp/PdfSharp/PageSizeConverter.cs         |    6 +-
 lib/PdfSharp/PdfSharp/PdfSharpException.cs         |    4 +-
 lib/PdfSharp/PdfSharp/ProductVersionInfo.cs        |   18 +-
 lib/PdfSharp/PdfSharp/VersionInfo.cs               |    2 +-
 lib/PdfSharp/PdfSharp/enums/PSMsgID.cs             |   28 +-
 lib/PdfSharp/PdfSharp/enums/PageOrientation.cs     |    9 +-
 lib/PdfSharp/PdfSharp/enums/PageSize.cs            |   94 +-
 lib/PdfSharp/Properties/AssemblyInfo.cs            |    2 +-
 lib/PdfSharp/Resources/Messages.de.resources       |  Bin 884 -> 892 bytes
 lib/PdfSharp/Resources/Messages.resources          |  Bin 759 -> 767 bytes
 .../Resources/PdfSharp.resources.VS2005.vcproj     |  114 +
 316 files changed, 15971 insertions(+), 7095 deletions(-)
---
diff --git a/lib/PdfSharp/!internal/Directives.cs b/lib/PdfSharp/!internal/Directives.cs
index 8dbb18f..763f216 100644
--- a/lib/PdfSharp/!internal/Directives.cs
+++ b/lib/PdfSharp/!internal/Directives.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -71,7 +71,12 @@
 #endif
 
 #elif WPF
-// PDFsharp based on Windows Presentation Foundation in a future release...
+// PDFsharp based on Windows Presentation Foundation
+#elif SILVERLIGHT
+// PDFsharp based on Silverlight
+#if !WPF
+#error 'SILVERLIGHT' must be defined together with 'WPF'
+#endif
 #else
-#error Either 'GDI' or 'WPF' must be defined
+#error Either 'GDI', 'WPF' or 'SILVERLIGHT' must be defined
 #endif
diff --git a/lib/PdfSharp/AgInternals/AgExtensions.cs b/lib/PdfSharp/AgInternals/AgExtensions.cs
new file mode 100644
index 0000000..b1914fc
--- /dev/null
+++ b/lib/PdfSharp/AgInternals/AgExtensions.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Net;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Documents;
+using System.Windows.Ink;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+using System.Windows.Media.Imaging;
+using System.Windows.Shapes;
+
+namespace PdfSharp
+{
+  static class AgExtensions
+  {
+
+    public static string Format(this BitmapSource bitmapSource)
+    {
+      return "Silverlight";
+    }
+
+  }
+}
diff --git a/lib/PdfSharp/AgInternals/AgHacks.cs b/lib/PdfSharp/AgInternals/AgHacks.cs
new file mode 100644
index 0000000..ecd49d6
--- /dev/null
+++ b/lib/PdfSharp/AgInternals/AgHacks.cs
@@ -0,0 +1,111 @@
+using System;
+using System.Collections.Generic;
+using System.Net;
+#if WPF || SILVERLIGHT
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Documents;
+using System.Windows.Ink;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+using System.Windows.Shapes;
+#endif
+
+#if SILVERLIGHT
+namespace PdfSharp
+{
+  public class ApplicationException : Exception
+  {
+    public ApplicationException()
+    { }
+
+    public ApplicationException(string message)
+      : base(message)
+    { }
+
+    public ApplicationException(string message, Exception innerException)
+      : base(message, innerException)
+    { }
+  }
+
+  public class ArgumentOutOfRangeException : ArgumentException
+  {
+    public ArgumentOutOfRangeException()
+    { }
+
+    public ArgumentOutOfRangeException(string message)
+      : base(message)
+    { }
+
+    public ArgumentOutOfRangeException(string message, string message2)
+      : base(message, message2)
+    { }
+
+    public ArgumentOutOfRangeException(string message, object value, string message2)
+      : base(message, message2)
+    { }
+
+    public ArgumentOutOfRangeException(string message, Exception innerException)
+      : base(message, innerException)
+    { }
+  }
+
+  public class InvalidEnumArgumentException : ArgumentException
+  {
+    public InvalidEnumArgumentException()
+    { }
+
+    public InvalidEnumArgumentException(string message)
+      : base(message)
+    { }
+
+    public InvalidEnumArgumentException(string message, string message2)
+      : base(message, message2)
+    { }
+
+    public InvalidEnumArgumentException(string message, int n, Type type)
+      : base(message)
+    { }
+
+    public InvalidEnumArgumentException(string message, Exception innerException)
+      : base(message, innerException)
+    { }
+  }
+
+  //public class FileNotFoundException : Exception
+  //{
+  //  public FileNotFoundException()
+  //  { }
+
+  //  public FileNotFoundException(string message)
+  //    : base(message)
+  //  { }
+
+  //  public FileNotFoundException(string message, string path)
+  //    : base(message + "/" + path)
+  //  { }
+
+  //  public FileNotFoundException(string message, Exception innerException)
+  //    : base(message, innerException)
+  //  { }
+  //}
+
+  class Serializable : Attribute
+  { }
+
+  class BrowsableAttribute : Attribute
+  {
+    public BrowsableAttribute()
+    { }
+
+    public BrowsableAttribute(bool browsable)
+    { }
+  }
+
+  public interface ICloneable
+  {
+    Object Clone();
+  }
+}
+#endif
diff --git a/lib/PdfSharp/AgInternals/DrawingContext.cs b/lib/PdfSharp/AgInternals/DrawingContext.cs
new file mode 100644
index 0000000..e4807ec
--- /dev/null
+++ b/lib/PdfSharp/AgInternals/DrawingContext.cs
@@ -0,0 +1,280 @@
+using System;
+using System.Collections.Generic;
+using System.Net;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Documents;
+using System.Windows.Ink;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+using System.Windows.Shapes;
+using PdfSharp.Drawing;
+
+#if SILVERLIGHT
+namespace System.Windows.Media
+{
+  /// <summary>
+  /// Silverlight 3 version of DrawingContext.
+  /// </summary>
+  public class DrawingContext
+  {
+    internal DrawingContext(Canvas canvas)
+    {
+      if (canvas == null)
+        throw new ArgumentNullException("canvas");
+
+      _canvas = canvas;
+
+      // Init stack with identity matrix
+      _matrixStack.Push(new XMatrix());
+
+#if DEBUG
+      Rectangle rectange = new Rectangle();
+      rectange.Width = 100;
+      rectange.Height = 50;
+      rectange.Fill = new SolidColorBrush { Color = Colors.Red };
+      Canvas.SetLeft(rectange, 50);
+      Canvas.SetTop(rectange, 70);
+      _canvas.Children.Add(rectange);
+#endif
+    }
+
+    public void Close()
+    {
+
+    }
+
+    //public void DrawDrawing(Drawing drawing);
+
+    public void DrawEllipse(Brush brush, Pen pen, Point center, double radiusX, double radiusY)
+    {
+      Ellipse ellipse = new Ellipse();
+      SetupShape(ellipse, center.X - radiusX, center.Y - radiusY, radiusX * 2, radiusY * 2, brush, pen);
+      ellipse.Fill = brush;
+      _canvas.Children.Add(ellipse);
+    }
+
+    //public void DrawEllipse(Brush brush, Pen pen, Point center, AnimationClock centerAnimations, double radiusX, AnimationClock radiusXAnimations, double radiusY, AnimationClock radiusYAnimations);
+
+    public void DrawGeometry(Brush brush, Pen pen, Geometry geometry)
+    {
+      //geometry.
+    }
+
+    //public void DrawGlyphRun(Brush foregroundBrush, GlyphRun glyphRun);
+
+    public void DrawImage(ImageSource imageSource, Rect rectangle)
+    {
+    }
+
+    public void DrawLine(Pen pen, Point point0, Point point1)
+    {
+      Line line = new Line();
+      SetupShape(line, point0.X, point0.Y, point1.X - point0.X, point1.Y - point0.Y, null, pen);
+      line.X1 = point0.X;
+      line.Y1 = point0.Y;
+      line.X2 = point1.X;
+      line.Y2 = point1.Y;
+      _canvas.Children.Add(line);
+    }
+
+    public void DrawRectangle(Brush brush, Pen pen, Rect rectangle)
+    {
+    }
+
+    public void DrawRoundedRectangle(Brush brush, Pen pen, Rect rectangle, double radiusX, double radiusY)
+    {
+    }
+
+    static void SetupShape(Shape shape, double x, double y, double width, double height, Brush brush, Pen pen)
+    {
+      Canvas.SetLeft(shape, x);
+      Canvas.SetTop(shape, y);
+      shape.Width = width;
+      shape.Height = height;
+      shape.Fill = brush;
+      if (pen != null)
+      {
+        shape.Stroke = pen.Brush;
+        shape.StrokeThickness = pen.Thickness;
+      }
+    }
+
+    //public void DrawRoundedRectangle(Brush brush, Pen pen, Rect rectangle, AnimationClock rectangleAnimations, double radiusX, AnimationClock radiusXAnimations, double radiusY, AnimationClock radiusYAnimations);
+    //public void DrawText(FormattedText formattedText, Point origin);
+    //public void DrawVideo(MediaPlayer player, Rect rectangle);
+    //public void DrawVideo(MediaPlayer player, Rect rectangle, AnimationClock rectangleAnimations);
+
+    public void Pop()
+    { }
+
+    public void PushClip(Geometry clipGeometry)
+    {
+    }
+
+    //public void PushEffect(BitmapEffect effect, BitmapEffectInput effectInput);
+    //public void PushGuidelineSet(GuidelineSet guidelines);
+    //public void PushOpacity(double opacity);
+    //public void PushOpacity(double opacity, AnimationClock opacityAnimations);
+    //public void PushOpacityMask(Brush opacityMask);
+
+    public void PushTransform(MatrixTransform transform)
+    {
+      XMatrix matrix = _matrixStack.Peek();
+      matrix.Append(transform.Matrix);
+    }
+
+    public void DrawString(XGraphics gfx, string text, XFont font, XBrush brush, XRect layoutRectangle, XStringFormat format)
+    {
+      double x = layoutRectangle.X;
+      double y = layoutRectangle.Y;
+
+      double lineSpace = font.GetHeight(gfx);
+      double cyAscent = lineSpace * font.cellAscent / font.cellSpace;
+      double cyDescent = lineSpace * font.cellDescent / font.cellSpace;
+
+      bool bold = (font.Style & XFontStyle.Bold) != 0;
+      bool italic = (font.Style & XFontStyle.Italic) != 0;
+      bool strikeout = (font.Style & XFontStyle.Strikeout) != 0;
+      bool underline = (font.Style & XFontStyle.Underline) != 0;
+
+      //FormattedText formattedText = new FormattedText(text, new CultureInfo("en-us"), // WPFHACK
+      //  FlowDirection.LeftToRight, font.typeface, font.Size, brush.RealizeWpfBrush());
+      TextBlock textBlock = FontHelper.CreateTextBlock(text, null, font.Size, brush.RealizeWpfBrush());
+
+      Canvas.SetLeft(textBlock, x);
+      Canvas.SetTop(textBlock, y);
+
+      //formattedText.SetTextDecorations(TextDecorations.OverLine);
+      switch (format.Alignment)
+      {
+        case XStringAlignment.Near:
+          // nothing to do, this is the default
+          //formattedText.TextAlignment = TextAlignment.Left;
+          break;
+
+        case XStringAlignment.Center:
+          x += layoutRectangle.Width / 2;
+          textBlock.TextAlignment = TextAlignment.Center;
+          break;
+
+        case XStringAlignment.Far:
+          x += layoutRectangle.Width;
+          textBlock.TextAlignment = TextAlignment.Right;
+          break;
+      }
+      if (gfx.PageDirection == XPageDirection.Downwards)
+      {
+        switch (format.LineAlignment)
+        {
+          case XLineAlignment.Near:
+            //y += cyAscent;
+            break;
+
+          //case XLineAlignment.Center:
+          //  // TODO use CapHeight. PDFlib also uses 3/4 of ascent
+          //  y += -formattedText.Baseline + (cyAscent * 1 / 3) + layoutRectangle.Height / 2;
+          //  //y += -formattedText.Baseline + (font.Size * font.Metrics.CapHeight / font.unitsPerEm / 2) + layoutRectangle.Height / 2;
+          //  break;
+
+          //case XLineAlignment.Far:
+          //  y += -formattedText.Baseline - cyDescent + layoutRectangle.Height;
+          //  break;
+
+          //case XLineAlignment.BaseLine:
+          //  y -= formattedText.Baseline;
+          //  break;
+        }
+      }
+      else
+      {
+        // TODOWPF: make unit test
+        switch (format.LineAlignment)
+        {
+          case XLineAlignment.Near:
+            //y += cyDescent;
+            break;
+
+          case XLineAlignment.Center:
+            // TODO use CapHeight. PDFlib also uses 3/4 of ascent
+            //y += -(cyAscent * 3 / 4) / 2 + rect.Height / 2;
+            break;
+
+          case XLineAlignment.Far:
+            //y += -cyAscent + rect.Height;
+            break;
+
+          case XLineAlignment.BaseLine:
+            // nothing to do
+            break;
+        }
+      }
+
+      //if (bold && !descriptor.IsBoldFace)
+      //{
+      //  // TODO: emulate bold by thicker outline
+      //}
+
+      //if (italic && !descriptor.IsBoldFace)
+      //{
+      //  // TODO: emulate italic by shearing transformation
+      //}
+
+      //if (underline)
+      //{
+      //  formattedText.FontStyle.SetTextDecorations(TextDecorations.Underline);
+      //  //double underlinePosition = lineSpace * realizedFont.FontDescriptor.descriptor.UnderlinePosition / font.cellSpace;
+      //  //double underlineThickness = lineSpace * realizedFont.FontDescriptor.descriptor.UnderlineThickness / font.cellSpace;
+      //  //DrawRectangle(null, brush, x, y - underlinePosition, width, underlineThickness);
+      //}
+
+      //if (strikeout)
+      //{
+      //  formattedText.SetTextDecorations(TextDecorations.Strikethrough);
+      //  //double strikeoutPosition = lineSpace * realizedFont.FontDescriptor.descriptor.StrikeoutPosition / font.cellSpace;
+      //  //double strikeoutSize = lineSpace * realizedFont.FontDescriptor.descriptor.StrikeoutSize / font.cellSpace;
+      //  //DrawRectangle(null, brush, x, y - strikeoutPosition - strikeoutSize, width, strikeoutSize);
+      //}
+
+      //formattedText 
+      _canvas.Children.Add(textBlock);
+    }
+
+    public XSize MeasureString(XGraphics gfx, string text, XFont font, XStringFormat stringFormat)
+    {
+      TextBlock textBlock = FontHelper.CreateTextBlock(text, null, font.Size, null);
+      return new XSize(textBlock.ActualWidth, textBlock.ActualHeight);
+    }
+
+    Canvas _canvas = new Canvas();
+
+    readonly Stack<XMatrix> _matrixStack = new Stack<XMatrix>();
+  }
+
+  public sealed class Pen //: Animatable
+  {
+    //public Pen();
+
+    public Pen(Brush brush, double thickness)
+    {
+      Brush = brush;
+      Thickness = thickness;
+    }
+
+    public Brush Brush { get; set; }
+    public double Thickness { get; set; }
+    //public DashStyle DashStyle { get; set; }
+    public double[] DashArray { get; set; }
+    public double DashOffset { get; set; }
+    public PenLineCap StartLineCap { get; set; }
+    public PenLineCap EndLineCap { get; set; }
+    public PenLineCap DashCap { get; set; }
+    public PenLineJoin LineJoin { get; set; }
+    public double MiterLimit { get; set; }
+
+    //public Pen Clone();
+    //public Pen CloneCurrentValue();
+  }
+}
+#endif
\ No newline at end of file
diff --git a/lib/PdfSharp/AgInternals/DrawingVisual.cs b/lib/PdfSharp/AgInternals/DrawingVisual.cs
new file mode 100644
index 0000000..c784c45
--- /dev/null
+++ b/lib/PdfSharp/AgInternals/DrawingVisual.cs
@@ -0,0 +1,46 @@
+using System;
+using System.Net;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Documents;
+using System.Windows.Ink;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+using System.Windows.Shapes;
+
+#if SILVERLIGHT__
+namespace System.Windows.Media
+{
+  /// <summary>
+  /// Silverlight 3 version of DrawingVisual.
+  /// </summary>
+  class DrawingVisual
+  {
+    //   // Fields
+    //private IDrawingContent _content;
+
+    //// Methods
+    //public DrawingVisual();
+    //internal override void FreeContent(DUCE.Channel channel);
+    //internal override Rect GetContentBounds();
+    //internal override DrawingGroup GetDrawing();
+    //protected override GeometryHitTestResult HitTestCore(GeometryHitTestParameters hitTestParameters);
+    //protected override HitTestResult HitTestCore(PointHitTestParameters hitTestParameters);
+    //internal override void PrecomputeContent();
+    //internal override void RenderClose(IDrawingContent newContent);
+    //internal override void RenderContent(RenderContext ctx, bool isOnChannel);
+
+    public DrawingContext RenderOpen()
+    {
+      return new DrawingContext(null);
+    }
+
+    //internal override void UpdateRealizations(RealizationContext ctx);
+    //internal void WalkContent(DrawingContextWalker walker);
+
+    //// Properties
+    //public DrawingGroup Drawing { get; }
+  }
+}
+#endif
diff --git a/lib/PdfSharp/AgInternals/Typeface.cs b/lib/PdfSharp/AgInternals/Typeface.cs
new file mode 100644
index 0000000..cd7562a
--- /dev/null
+++ b/lib/PdfSharp/AgInternals/Typeface.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Net;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Documents;
+using System.Windows.Ink;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+using System.Windows.Shapes;
+
+#if SILVERLIGHT
+namespace System.Windows.Media
+{
+  /// <summary>
+  /// Silverlight 3 version of Typeface.
+  /// </summary>
+  internal class Typeface
+  {
+    public Typeface(FontFamily family, FontStyle fontStyle, FontWeight fontWeight, FontStretch fontStretch )
+    {
+      
+    }
+  }
+}
+#endif
diff --git a/lib/PdfSharp/AssemblyInfo-AG.cs b/lib/PdfSharp/AssemblyInfo-AG.cs
new file mode 100644
index 0000000..00213d6
--- /dev/null
+++ b/lib/PdfSharp/AssemblyInfo-AG.cs
@@ -0,0 +1,35 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("PdfSharp_AG")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft")]
+[assembly: AssemblyProduct("PdfSharp_AG")]
+[assembly: AssemblyCopyright("Copyright © Microsoft 2009")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("9eeb8ac8-68b1-4465-b858-173a44efc3c4")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers 
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/lib/PdfSharp/PdfSharp-AG.csproj b/lib/PdfSharp/PdfSharp-AG.csproj
new file mode 100644
index 0000000..3d39805
--- /dev/null
+++ b/lib/PdfSharp/PdfSharp-AG.csproj
@@ -0,0 +1,380 @@
+<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003";>
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.30729</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{01E4CCB8-F473-4334-9F9A-A52398E84413}</ProjectGuid>
+    <ProjectTypeGuids>{A1591282-1198-4647-A2B1-27E5FF5F6F3B};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>PdfSharp</RootNamespace>
+    <AssemblyName>PdfSharp-AG</AssemblyName>
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+    <SilverlightApplication>false</SilverlightApplication>
+    <ValidateXaml>true</ValidateXaml>
+    <ThrowErrorsInValidation>false</ThrowErrorsInValidation>
+    <FileUpgradeFlags>
+    </FileUpgradeFlags>
+    <UpgradeBackupLocation>
+    </UpgradeBackupLocation>
+    <OldToolsVersion>3.5</OldToolsVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>Bin\Debug</OutputPath>
+    <DefineConstants>TRACE;DEBUG;SILVERLIGHT;WPF</DefineConstants>
+    <NoStdLib>true</NoStdLib>
+    <NoConfig>true</NoConfig>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>Bin\Release</OutputPath>
+    <DefineConstants>TRACE;SILVERLIGHT</DefineConstants>
+    <NoStdLib>true</NoStdLib>
+    <NoConfig>true</NoConfig>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System.Windows" />
+    <Reference Include="mscorlib" />
+    <Reference Include="system" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml" />
+    <Reference Include="System.Net" />
+    <Reference Include="System.Windows.Browser" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="!internal\Directives.cs" />
+    <Compile Include="AgInternals\AgExtensions.cs" />
+    <Compile Include="AgInternals\DrawingVisual.cs" />
+    <Compile Include="AgInternals\DrawingContext.cs" />
+    <Compile Include="AgInternals\AgHacks.cs" />
+    <Compile Include="AgInternals\Typeface.cs" />
+    <Compile Include="PdfSharp.Drawing.BarCodes\BarCode.cs" />
+    <Compile Include="PdfSharp.Drawing.BarCodes\BarCodeRenderInfo.cs" />
+    <Compile Include="PdfSharp.Drawing.BarCodes\BcgSR.cs" />
+    <Compile Include="PdfSharp.Drawing.BarCodes\Code2of5Interleaved.cs" />
+    <Compile Include="PdfSharp.Drawing.BarCodes\Code3of9Standard.cs" />
+    <Compile Include="PdfSharp.Drawing.BarCodes\CodeBase.cs" />
+    <Compile Include="PdfSharp.Drawing.BarCodes\CodeDataMatrix.cs" />
+    <Compile Include="PdfSharp.Drawing.BarCodes\CodeOmr.cs" />
+    <Compile Include="PdfSharp.Drawing.BarCodes\DataMatrixImage.cs" />
+    <Compile Include="PdfSharp.Drawing.BarCodes\enums\AnchorType.cs" />
+    <Compile Include="PdfSharp.Drawing.BarCodes\enums\CodeDirection.cs" />
+    <Compile Include="PdfSharp.Drawing.BarCodes\enums\CodeType.cs" />
+    <Compile Include="PdfSharp.Drawing.BarCodes\enums\DataMatrixEncoding.cs" />
+    <Compile Include="PdfSharp.Drawing.BarCodes\enums\MarkDistance.cs" />
+    <Compile Include="PdfSharp.Drawing.BarCodes\enums\TextLocation.cs" />
+    <Compile Include="PdfSharp.Drawing.BarCodes\MatrixCode.cs" />
+    <Compile Include="PdfSharp.Drawing.BarCodes\OmrData.cs" />
+    <Compile Include="PdfSharp.Drawing.BarCodes\ThickThinBarcodeRenderer.cs" />
+    <Compile Include="PdfSharp.Drawing.Layout\enums\XParagraphAlignment.cs" />
+    <Compile Include="PdfSharp.Drawing.Layout\XTextFormatter.cs" />
+    <Compile Include="PdfSharp.Drawing.Pdf\enums\DirtyFlags.cs" />
+    <Compile Include="PdfSharp.Drawing.Pdf\enums\StreamMode.cs" />
+    <Compile Include="PdfSharp.Drawing.Pdf\PdfGraphicsState.cs" />
+    <Compile Include="PdfSharp.Drawing.Pdf\XGraphicsPdfRenderer.cs" />
+    <Compile Include="PdfSharp.Drawing.Shapes\Shape.cs" />
+    <Compile Include="PdfSharp.Drawing\enums\PathStart.cs" />
+    <Compile Include="PdfSharp.Drawing\enums\XColorSpace.cs" />
+    <Compile Include="PdfSharp.Drawing\enums\XCombineMode.cs" />
+    <Compile Include="PdfSharp.Drawing\enums\XDashStyle.cs" />
+    <Compile Include="PdfSharp.Drawing\enums\XFillMode.cs" />
+    <Compile Include="PdfSharp.Drawing\enums\XFontStyle.cs" />
+    <Compile Include="PdfSharp.Drawing\enums\XGraphicRenderTarget.cs" />
+    <Compile Include="PdfSharp.Drawing\enums\XGraphicsPathItemType.cs" />
+    <Compile Include="PdfSharp.Drawing\enums\XGraphicsPdfPageOptions.cs" />
+    <Compile Include="PdfSharp.Drawing\enums\XGraphicsUnit.cs" />
+    <Compile Include="PdfSharp.Drawing\enums\XKnownColor.cs" />
+    <Compile Include="PdfSharp.Drawing\enums\XLineAlignment.cs" />
+    <Compile Include="PdfSharp.Drawing\enums\XLinearGradientMode.cs" />
+    <Compile Include="PdfSharp.Drawing\enums\XLineCap.cs" />
+    <Compile Include="PdfSharp.Drawing\enums\XLineJoin.cs" />
+    <Compile Include="PdfSharp.Drawing\enums\XMatrixOrder.cs" />
+    <Compile Include="PdfSharp.Drawing\enums\XPageDirection.cs" />
+    <Compile Include="PdfSharp.Drawing\enums\XSmoothingMode.cs" />
+    <Compile Include="PdfSharp.Drawing\enums\XStringAlignment.cs" />
+    <Compile Include="PdfSharp.Drawing\FontHelper.cs" />
+    <Compile Include="PdfSharp.Drawing\GeometryHelper.cs" />
+    <Compile Include="PdfSharp.Drawing\GraphicsStateStack.cs" />
+    <Compile Include="PdfSharp.Drawing\ImageHelper.cs" />
+    <Compile Include="PdfSharp.Drawing\InternalGraphicsState.cs" />
+    <Compile Include="PdfSharp.Drawing\IXGraphicsRenderer.cs" />
+    <Compile Include="PdfSharp.Drawing\PdfFontOptions.cs" />
+    <Compile Include="PdfSharp.Drawing\XBrush.cs" />
+    <Compile Include="PdfSharp.Drawing\XBrushes.cs" />
+    <Compile Include="PdfSharp.Drawing\XColor.cs" />
+    <Compile Include="PdfSharp.Drawing\XColorResourceManager.cs" />
+    <Compile Include="PdfSharp.Drawing\XColors.cs" />
+    <Compile Include="PdfSharp.Drawing\XConvert.cs" />
+    <Compile Include="PdfSharp.Drawing\XFont.cs" />
+    <Compile Include="PdfSharp.Drawing\XFontFamily.cs" />
+    <Compile Include="PdfSharp.Drawing\XFontMetrics.cs" />
+    <Compile Include="PdfSharp.Drawing\XFontStretch.cs" />
+    <Compile Include="PdfSharp.Drawing\XFontWeight.cs" />
+    <Compile Include="PdfSharp.Drawing\XFontWeights.cs" />
+    <Compile Include="PdfSharp.Drawing\XForm.cs" />
+    <Compile Include="PdfSharp.Drawing\XGlyphTypeface.cs" />
+    <Compile Include="PdfSharp.Drawing\XGraphics.cs" />
+    <Compile Include="PdfSharp.Drawing\XGraphicsContainer.cs" />
+    <Compile Include="PdfSharp.Drawing\XGraphicsPath.cs" />
+    <Compile Include="PdfSharp.Drawing\XGraphicsPathInternals.cs" />
+    <Compile Include="PdfSharp.Drawing\XGraphicsPathItem.cs" />
+    <Compile Include="PdfSharp.Drawing\XGraphicsState.cs" />
+    <Compile Include="PdfSharp.Drawing\XImage.cs" />
+    <Compile Include="PdfSharp.Drawing\XImageFormat.cs" />
+    <Compile Include="PdfSharp.Drawing\XKnownColorTable.cs" />
+    <Compile Include="PdfSharp.Drawing\XLinearGradientBrush.cs" />
+    <Compile Include="PdfSharp.Drawing\XMatrix.cs" />
+    <Compile Include="PdfSharp.Drawing\XPdfForm.cs" />
+    <Compile Include="PdfSharp.Drawing\XPen.cs" />
+    <Compile Include="PdfSharp.Drawing\XPens.cs" />
+    <Compile Include="PdfSharp.Drawing\XPoint.cs" />
+    <Compile Include="PdfSharp.Drawing\XPrivateFontCollection.cs" />
+    <Compile Include="PdfSharp.Drawing\XRect.cs" />
+    <Compile Include="PdfSharp.Drawing\XSize.cs" />
+    <Compile Include="PdfSharp.Drawing\XSolidBrush.cs" />
+    <Compile Include="PdfSharp.Drawing\XStringFormat.cs" />
+    <Compile Include="PdfSharp.Drawing\XStringFormats.cs" />
+    <Compile Include="PdfSharp.Drawing\XTypeFace.cs" />
+    <Compile Include="PdfSharp.Drawing\XUnit.cs" />
+    <Compile Include="PdfSharp.Drawing\XVector.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\enums\FontTechnology.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\enums\TableTag.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\enums\TableTagNames.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\ExternalHelper.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\FontData.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\FontDataStock.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\GenericFontTable.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\GlyphDataTable.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\IndexToLocationTable.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\IRefFontTable.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\OpenTypeDescriptor.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\OpenTypeFontTable.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\OpenTypeFontWriter.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\OpenTypeStructures.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\TableDirectoryEntry.cs" />
+    <Compile Include="PdfSharp.Fonts\AdobeGlyphList20.cs" />
+    <Compile Include="PdfSharp.Fonts\AdobeGlyphListForNewFonts.cs" />
+    <Compile Include="PdfSharp.Fonts\CMapInfo.cs" />
+    <Compile Include="PdfSharp.Fonts\FontDescriptor.cs" />
+    <Compile Include="PdfSharp.Fonts\FontDescriptorStock.cs" />
+    <Compile Include="PdfSharp.Fonts\FontWriter.cs" />
+    <Compile Include="PdfSharp.Internal\Calc.cs" />
+    <Compile Include="PdfSharp.Internal\ColorHelper.cs" />
+    <Compile Include="PdfSharp.Internal\DoubleUtil.cs" />
+    <Compile Include="PdfSharp.Internal\NativeMethods.cs" />
+    <Compile Include="PdfSharp.Internal\TokenizerHelper.cs" />
+    <Compile Include="PdfSharp.Pdf.AcroForms\enums\PdfAcroFieldFlags.cs" />
+    <Compile Include="PdfSharp.Pdf.AcroForms\PdfAcroField.cs" />
+    <Compile Include="PdfSharp.Pdf.AcroForms\PdfAcroForm.cs" />
+    <Compile Include="PdfSharp.Pdf.AcroForms\PdfButtonField.cs" />
+    <Compile Include="PdfSharp.Pdf.AcroForms\PdfCheckBoxField.cs" />
+    <Compile Include="PdfSharp.Pdf.AcroForms\PdfChoiceField.cs" />
+    <Compile Include="PdfSharp.Pdf.AcroForms\PdfComboBoxField.cs" />
+    <Compile Include="PdfSharp.Pdf.AcroForms\PdfGenericField.cs" />
+    <Compile Include="PdfSharp.Pdf.AcroForms\PdfListBoxField.cs" />
+    <Compile Include="PdfSharp.Pdf.AcroForms\PdfPushButtonField.cs" />
+    <Compile Include="PdfSharp.Pdf.AcroForms\PdfRadioButtonField.cs" />
+    <Compile Include="PdfSharp.Pdf.AcroForms\PdfSignatureField.cs" />
+    <Compile Include="PdfSharp.Pdf.AcroForms\PdfTextField.cs" />
+    <Compile Include="PdfSharp.Pdf.Actions\enums\PdfNamedActionNames.cs" />
+    <Compile Include="PdfSharp.Pdf.Actions\PdfAction.cs" />
+    <Compile Include="PdfSharp.Pdf.Advanced\IContentStream.cs" />
+    <Compile Include="PdfSharp.Pdf.Advanced\PdfCatalog.cs" />
+    <Compile Include="PdfSharp.Pdf.Advanced\PdfCIDFont.cs" />
+    <Compile Include="PdfSharp.Pdf.Advanced\PdfContent.cs" />
+    <Compile Include="PdfSharp.Pdf.Advanced\PdfContents.cs" />
+    <Compile Include="PdfSharp.Pdf.Advanced\PdfDictionaryWithContentStream.cs" />
+    <Compile Include="PdfSharp.Pdf.Advanced\PdfExtGState.cs" />
+    <Compile Include="PdfSharp.Pdf.Advanced\PdfExtGStateTable.cs" />
+    <Compile Include="PdfSharp.Pdf.Advanced\PdfFont.cs" />
+    <Compile Include="PdfSharp.Pdf.Advanced\PdfFontDescriptor.cs" />
+    <Compile Include="PdfSharp.Pdf.Advanced\PdfFontTable.cs" />
+    <Compile Include="PdfSharp.Pdf.Advanced\PdfFormXObject.cs" />
+    <Compile Include="PdfSharp.Pdf.Advanced\PdfFormXObjectTable.cs" />
+    <Compile Include="PdfSharp.Pdf.Advanced\PdfGroupAttributes.cs" />
+    <Compile Include="PdfSharp.Pdf.Advanced\PdfImage.cs" />
+    <Compile Include="PdfSharp.Pdf.Advanced\PdfImageTable.cs" />
+    <Compile Include="PdfSharp.Pdf.Advanced\PdfImportedObjectTable.cs" />
+    <Compile Include="PdfSharp.Pdf.Advanced\PdfInternals.cs" />
+    <Compile Include="PdfSharp.Pdf.Advanced\PdfObjectInternals.cs" />
+    <Compile Include="PdfSharp.Pdf.Advanced\PdfPageInheritableObjects.cs" />
+    <Compile Include="PdfSharp.Pdf.Advanced\PdfReference.cs" />
+    <Compile Include="PdfSharp.Pdf.Advanced\PdfResourceMap.cs" />
+    <Compile Include="PdfSharp.Pdf.Advanced\PdfResources.cs" />
+    <Compile Include="PdfSharp.Pdf.Advanced\PdfResourceTable.cs" />
+    <Compile Include="PdfSharp.Pdf.Advanced\PdfShading.cs" />
+    <Compile Include="PdfSharp.Pdf.Advanced\PdfShadingPattern.cs" />
+    <Compile Include="PdfSharp.Pdf.Advanced\PdfShadingTable.cs" />
+    <Compile Include="PdfSharp.Pdf.Advanced\PdfSoftMask.cs" />
+    <Compile Include="PdfSharp.Pdf.Advanced\PdfTilingPattern.cs" />
+    <Compile Include="PdfSharp.Pdf.Advanced\PdfToUnicodeMap.cs" />
+    <Compile Include="PdfSharp.Pdf.Advanced\PdfTrailer.cs" />
+    <Compile Include="PdfSharp.Pdf.Advanced\PdfTransparencyGroupAttributes.cs" />
+    <Compile Include="PdfSharp.Pdf.Advanced\PdfTrueTypeFont.cs" />
+    <Compile Include="PdfSharp.Pdf.Advanced\PdfType0Font.cs" />
+    <Compile Include="PdfSharp.Pdf.Advanced\PdfType1Font.cs" />
+    <Compile Include="PdfSharp.Pdf.Advanced\PdfXObject.cs" />
+    <Compile Include="PdfSharp.Pdf.Annotations\enums\PdfAnnotationFlags.cs" />
+    <Compile Include="PdfSharp.Pdf.Annotations\enums\PdfRubberStampAnnotationIcon.cs" />
+    <Compile Include="PdfSharp.Pdf.Annotations\enums\PdfTextAnnotationIcon.cs" />
+    <Compile Include="PdfSharp.Pdf.Annotations\PdfAnnotation.cs" />
+    <Compile Include="PdfSharp.Pdf.Annotations\PdfAnnotations.cs" />
+    <Compile Include="PdfSharp.Pdf.Annotations\PdfGenericAnnotation.cs" />
+    <Compile Include="PdfSharp.Pdf.Annotations\PdfLinkAnnotation.cs" />
+    <Compile Include="PdfSharp.Pdf.Annotations\PdfRubberStampAnnotation.cs" />
+    <Compile Include="PdfSharp.Pdf.Annotations\PdfTextAnnotation.cs" />
+    <Compile Include="PdfSharp.Pdf.Annotations\PdfWidgetAnnotation.cs" />
+    <Compile Include="PdfSharp.Pdf.Content.Objects\CObjects.cs" />
+    <Compile Include="PdfSharp.Pdf.Content.Objects\enum\OpCodeFlags.cs" />
+    <Compile Include="PdfSharp.Pdf.Content.Objects\enum\OpCodeName.cs" />
+    <Compile Include="PdfSharp.Pdf.Content.Objects\Operators.cs" />
+    <Compile Include="PdfSharp.Pdf.Content\Chars.cs" />
+    <Compile Include="PdfSharp.Pdf.Content\CLexer.cs" />
+    <Compile Include="PdfSharp.Pdf.Content\ContentReader.cs" />
+    <Compile Include="PdfSharp.Pdf.Content\ContentReaderException.cs" />
+    <Compile Include="PdfSharp.Pdf.Content\ContentWriter.cs" />
+    <Compile Include="PdfSharp.Pdf.Content\CParser.cs" />
+    <Compile Include="PdfSharp.Pdf.Content\enums\Symbol.cs" />
+    <Compile Include="PdfSharp.Pdf.Filters\ASCII85Decode.cs" />
+    <Compile Include="PdfSharp.Pdf.Filters\ASCIIHexDecode.cs" />
+    <Compile Include="PdfSharp.Pdf.Filters\Filter.cs" />
+    <Compile Include="PdfSharp.Pdf.Filters\Filtering.cs" />
+    <Compile Include="PdfSharp.Pdf.Filters\FlateDecode.cs" />
+    <Compile Include="PdfSharp.Pdf.Filters\LzwDecode.cs" />
+    <Compile Include="PdfSharp.Pdf.Internal\AnsiEncoding.cs" />
+    <Compile Include="PdfSharp.Pdf.Internal\ColorSpaceHelper.cs" />
+    <Compile Include="PdfSharp.Pdf.Internal\DocEncoding.cs" />
+    <Compile Include="PdfSharp.Pdf.Internal\GlobalObjectTable.cs" />
+    <Compile Include="PdfSharp.Pdf.Internal\PdfEncoders.cs" />
+    <Compile Include="PdfSharp.Pdf.Internal\RawEncoding.cs" />
+    <Compile Include="PdfSharp.Pdf.Internal\RawUnicodeEncoding.cs" />
+    <Compile Include="PdfSharp.Pdf.Internal\ThreadLocalStorage.cs" />
+    <Compile Include="PdfSharp.Pdf.IO\Chars.cs" />
+    <Compile Include="PdfSharp.Pdf.IO\enums\PasswordValidity.cs" />
+    <Compile Include="PdfSharp.Pdf.IO\enums\PdfDocumentOpenMode.cs" />
+    <Compile Include="PdfSharp.Pdf.IO\enums\PdfWriterLayout.cs" />
+    <Compile Include="PdfSharp.Pdf.IO\enums\PdfWriterOptions.cs" />
+    <Compile Include="PdfSharp.Pdf.IO\enums\Symbol.cs" />
+    <Compile Include="PdfSharp.Pdf.IO\Lexer.cs" />
+    <Compile Include="PdfSharp.Pdf.IO\Parser.cs" />
+    <Compile Include="PdfSharp.Pdf.IO\PdfReader.cs" />
+    <Compile Include="PdfSharp.Pdf.IO\PdfReaderException.cs" />
+    <Compile Include="PdfSharp.Pdf.IO\PdfWriter.cs" />
+    <Compile Include="PdfSharp.Pdf.IO\ShiftStack.cs" />
+    <Compile Include="PdfSharp.Pdf.Security\enums\PdfDocumentSecurity.cs" />
+    <Compile Include="PdfSharp.Pdf.Security\enums\PdfUserAccessPermission.cs" />
+    <Compile Include="PdfSharp.Pdf.Security\PdfSecurityHandler.cs" />
+    <Compile Include="PdfSharp.Pdf.Security\PdfSecuritySettings.cs" />
+    <Compile Include="PdfSharp.Pdf.Security\PdfStandardSecurityHandler.cs" />
+    <Compile Include="PdfSharp.Pdf\EntryInfoAttribute.cs" />
+    <Compile Include="PdfSharp.Pdf\enums\DocumentState.cs" />
+    <Compile Include="PdfSharp.Pdf\enums\PdfColorMode.cs" />
+    <Compile Include="PdfSharp.Pdf\enums\PdfCustomValueCompression.cs" />
+    <Compile Include="PdfSharp.Pdf\enums\PdfFontEmbedding.cs" />
+    <Compile Include="PdfSharp.Pdf\enums\PdfFontEncoding.cs" />
+    <Compile Include="PdfSharp.Pdf\enums\PdfOutlineStyle.cs" />
+    <Compile Include="PdfSharp.Pdf\enums\PdfPageLayout.cs" />
+    <Compile Include="PdfSharp.Pdf\enums\PdfPageMode.cs" />
+    <Compile Include="PdfSharp.Pdf\enums\PdfReadingDirection.cs" />
+    <Compile Include="PdfSharp.Pdf\enums\PdfTextStringEncoding.cs" />
+    <Compile Include="PdfSharp.Pdf\KeysBase.cs" />
+    <Compile Include="PdfSharp.Pdf\KeysMeta.cs" />
+    <Compile Include="PdfSharp.Pdf\PdfArray.cs" />
+    <Compile Include="PdfSharp.Pdf\PdfBoolean.cs" />
+    <Compile Include="PdfSharp.Pdf\PdfBooleanObject.cs" />
+    <Compile Include="PdfSharp.Pdf\PdfCustomValue.cs" />
+    <Compile Include="PdfSharp.Pdf\PdfCustomValues.cs" />
+    <Compile Include="PdfSharp.Pdf\PdfDate.cs" />
+    <Compile Include="PdfSharp.Pdf\PdfDictionary.cs" />
+    <Compile Include="PdfSharp.Pdf\PdfDocument.cs" />
+    <Compile Include="PdfSharp.Pdf\PdfDocumentInformation.cs" />
+    <Compile Include="PdfSharp.Pdf\PdfDocumentOptions.cs" />
+    <Compile Include="PdfSharp.Pdf\PdfDocumentSettings.cs" />
+    <Compile Include="PdfSharp.Pdf\PdfInteger.cs" />
+    <Compile Include="PdfSharp.Pdf\PdfIntegerObject.cs" />
+    <Compile Include="PdfSharp.Pdf\PdfItem.cs" />
+    <Compile Include="PdfSharp.Pdf\PdfLiteral.cs" />
+    <Compile Include="PdfSharp.Pdf\PdfName.cs" />
+    <Compile Include="PdfSharp.Pdf\PdfNameObject.cs" />
+    <Compile Include="PdfSharp.Pdf\PdfNull.cs" />
+    <Compile Include="PdfSharp.Pdf\PdfNullObject.cs" />
+    <Compile Include="PdfSharp.Pdf\PdfNumber.cs" />
+    <Compile Include="PdfSharp.Pdf\PdfNumberObject.cs" />
+    <Compile Include="PdfSharp.Pdf\PdfObject.cs" />
+    <Compile Include="PdfSharp.Pdf\PdfObjectID.cs" />
+    <Compile Include="PdfSharp.Pdf\PdfOutline.cs" />
+    <Compile Include="PdfSharp.Pdf\PdfPage.cs" />
+    <Compile Include="PdfSharp.Pdf\PdfPages.cs" />
+    <Compile Include="PdfSharp.Pdf\PdfReal.cs" />
+    <Compile Include="PdfSharp.Pdf\PdfRealObject.cs" />
+    <Compile Include="PdfSharp.Pdf\PdfRectangle.cs" />
+    <Compile Include="PdfSharp.Pdf\PdfReferenceTable.cs" />
+    <Compile Include="PdfSharp.Pdf\PdfString.cs" />
+    <Compile Include="PdfSharp.Pdf\PdfStringObject.cs" />
+    <Compile Include="PdfSharp.Pdf\PdfUInteger.cs" />
+    <Compile Include="PdfSharp.Pdf\PdfUIntegerObject.cs" />
+    <Compile Include="PdfSharp.Pdf\PdfViewerPreferences.cs" />
+    <Compile Include="PdfSharp.Pdf\TrimMargins.cs" />
+    <Compile Include="PdfSharp.SharpZipLib\Checksums\Adler32.cs" />
+    <Compile Include="PdfSharp.SharpZipLib\Checksums\CRC32.cs" />
+    <Compile Include="PdfSharp.SharpZipLib\Checksums\IChecksum.cs" />
+    <Compile Include="PdfSharp.SharpZipLib\SharpZip\SharpZipBaseException.cs" />
+    <Compile Include="PdfSharp.SharpZipLib\Zip\Compression\Deflater.cs" />
+    <Compile Include="PdfSharp.SharpZipLib\Zip\Compression\DeflaterConstants.cs" />
+    <Compile Include="PdfSharp.SharpZipLib\Zip\Compression\DeflaterEngine.cs" />
+    <Compile Include="PdfSharp.SharpZipLib\Zip\Compression\DeflaterHuffman.cs" />
+    <Compile Include="PdfSharp.SharpZipLib\Zip\Compression\DeflaterPending.cs" />
+    <Compile Include="PdfSharp.SharpZipLib\Zip\Compression\Inflater.cs" />
+    <Compile Include="PdfSharp.SharpZipLib\Zip\Compression\InflaterDynHeader.cs" />
+    <Compile Include="PdfSharp.SharpZipLib\Zip\Compression\InflaterHuffmanTree.cs" />
+    <Compile Include="PdfSharp.SharpZipLib\Zip\Compression\PendingBuffer.cs" />
+    <Compile Include="PdfSharp.SharpZipLib\Zip\Compression\Streams\DeflaterOutputStream.cs" />
+    <Compile Include="PdfSharp.SharpZipLib\Zip\Compression\Streams\InflaterInputStream.cs" />
+    <Compile Include="PdfSharp.SharpZipLib\Zip\Compression\Streams\OutputWindow.cs" />
+    <Compile Include="PdfSharp.SharpZipLib\Zip\Compression\Streams\StreamManipulator.cs" />
+    <Compile Include="PdfSharp.Windows\enums\RenderMode.cs" />
+    <Compile Include="PdfSharp.Windows\enums\Zoom.cs" />
+    <Compile Include="PdfSharp\enums\PageOrientation.cs" />
+    <Compile Include="PdfSharp\enums\PageSize.cs" />
+    <Compile Include="PdfSharp\enums\PSMsgID.cs" />
+    <Compile Include="PdfSharp\PageSizeConverter.cs" />
+    <Compile Include="PdfSharp\PdfSharpException.cs" />
+    <Compile Include="PdfSharp\ProductVersionInfo.cs" />
+    <Compile Include="PdfSharp\PSSR.cs" />
+    <Compile Include="PdfSharp\VersionInfo.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <Content Include="PdfSharp.Drawing.BarCodes\%40BarCodes.txt" />
+    <Content Include="PdfSharp.SharpZipLib\ReadMe.txt" />
+  </ItemGroup>
+  <ItemGroup>
+    <Folder Include="PdfSharp.Drawing.Wpf\" />
+    <Folder Include="PdfSharp.Fonts.TrueType\enums\" />
+    <Folder Include="PdfSharpPdf.AcroForms\enums\" />
+  </ItemGroup>
+  <Import Project="$(MSBuildExtensionsPath)\Microsoft\Silverlight\v3.0\Microsoft.Silverlight.CSharp.targets" Condition="" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+  <ProjectExtensions>
+    <VisualStudio>
+      <FlavorProperties GUID="{A1591282-1198-4647-A2B1-27E5FF5F6F3B}">
+        <SilverlightProjectProperties />
+      </FlavorProperties>
+    </VisualStudio>
+  </ProjectExtensions>
+</Project>
\ No newline at end of file
diff --git a/lib/PdfSharp/PdfSharp-AG.csproj.resharper b/lib/PdfSharp/PdfSharp-AG.csproj.resharper
new file mode 100644
index 0000000..7cfaef4
--- /dev/null
+++ b/lib/PdfSharp/PdfSharp-AG.csproj.resharper
@@ -0,0 +1,6 @@
+<Configuration>
+  <CSharpLanguageLevel>CSharp30</CSharpLanguageLevel>
+  <NamespaceFolders>
+    <SkipFolder>01E4CCB8-F473-4334-9F9A-A52398E84413/d:PdfSharp.Drawing/d:enums</SkipFolder>
+  </NamespaceFolders>
+</Configuration>
\ No newline at end of file
diff --git a/lib/PdfSharp/PdfSharp-Hybrid.csproj b/lib/PdfSharp/PdfSharp-Hybrid.csproj
index 657bdc1..5d82291 100644
--- a/lib/PdfSharp/PdfSharp-Hybrid.csproj
+++ b/lib/PdfSharp/PdfSharp-Hybrid.csproj
@@ -3,7 +3,7 @@
   <PropertyGroup>
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
     <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProductVersion>9.0.21022</ProductVersion>
+    <ProductVersion>9.0.30729</ProductVersion>
     <SchemaVersion>2.0</SchemaVersion>
     <ProjectGuid>{4C6B899E-D8F5-439E-ACA1-6C9D4CF79407}</ProjectGuid>
     <OutputType>Library</OutputType>
@@ -75,7 +75,6 @@
     <Compile Include="PdfSharp.Drawing.Pdf\enums\StreamMode.cs" />
     <Compile Include="PdfSharp.Drawing.Pdf\PdfGraphicsState.cs" />
     <Compile Include="PdfSharp.Drawing.Pdf\XGraphicsPdfRenderer.cs" />
-    <Compile Include="PdfSharp.Drawing.Rtf\XGraphicsRtfRenderer.cs" />
     <Compile Include="PdfSharp.Drawing.Shapes\Shape.cs" />
     <Compile Include="PdfSharp.Drawing\enums\PathStart.cs" />
     <Compile Include="PdfSharp.Drawing\enums\XColorSpace.cs" />
@@ -112,7 +111,11 @@
     <Compile Include="PdfSharp.Drawing\XFont.cs" />
     <Compile Include="PdfSharp.Drawing\XFontFamily.cs" />
     <Compile Include="PdfSharp.Drawing\XFontMetrics.cs" />
+    <Compile Include="PdfSharp.Drawing\XFontStretch.cs" />
+    <Compile Include="PdfSharp.Drawing\XFontWeight.cs" />
+    <Compile Include="PdfSharp.Drawing\XFontWeights.cs" />
     <Compile Include="PdfSharp.Drawing\XForm.cs" />
+    <Compile Include="PdfSharp.Drawing\XGlyphTypeface.cs" />
     <Compile Include="PdfSharp.Drawing\XGraphics.cs" />
     <Compile Include="PdfSharp.Drawing\XGraphicsContainer.cs" />
     <Compile Include="PdfSharp.Drawing\XGraphicsPath.cs" />
@@ -134,26 +137,29 @@
     <Compile Include="PdfSharp.Drawing\XSolidBrush.cs" />
     <Compile Include="PdfSharp.Drawing\XStringFormat.cs" />
     <Compile Include="PdfSharp.Drawing\XStringFormats.cs" />
+    <Compile Include="PdfSharp.Drawing\XTypeFace.cs" />
     <Compile Include="PdfSharp.Drawing\XUnit.cs" />
     <Compile Include="PdfSharp.Drawing\XVector.cs" />
-    <Compile Include="PdfSharp.Fonts.TrueType\enums\TableTag.cs" />
-    <Compile Include="PdfSharp.Fonts.TrueType\enums\TableTagNames.cs" />
-    <Compile Include="PdfSharp.Fonts.TrueType\ExternalHelper.cs" />
-    <Compile Include="PdfSharp.Fonts.TrueType\FontData.cs" />
-    <Compile Include="PdfSharp.Fonts.TrueType\FontDescriptor.cs" />
-    <Compile Include="PdfSharp.Fonts.TrueType\FontDescriptorStock.cs" />
-    <Compile Include="PdfSharp.Fonts.TrueType\GenericFontTable.cs" />
-    <Compile Include="PdfSharp.Fonts.TrueType\GlyphDataTable.cs" />
-    <Compile Include="PdfSharp.Fonts.TrueType\IndexToLocationTable.cs" />
-    <Compile Include="PdfSharp.Fonts.TrueType\IRefFontTable.cs" />
-    <Compile Include="PdfSharp.Fonts.TrueType\TableDirectoryEntry.cs" />
-    <Compile Include="PdfSharp.Fonts.TrueType\TrueTypeDescriptor.cs" />
-    <Compile Include="PdfSharp.Fonts.TrueType\TrueTypeFontTable.cs" />
-    <Compile Include="PdfSharp.Fonts.TrueType\TrueTypeFontWriter.cs" />
-    <Compile Include="PdfSharp.Fonts.TrueType\TrueTypeStructures.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\enums\FontTechnology.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\enums\TableTag.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\enums\TableTagNames.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\ExternalHelper.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\FontData.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\FontDataStock.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\GenericFontTable.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\GlyphDataTable.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\IndexToLocationTable.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\IRefFontTable.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\OpenTypeDescriptor.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\OpenTypeFontTable.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\OpenTypeFontWriter.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\OpenTypeStructures.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\TableDirectoryEntry.cs" />
     <Compile Include="PdfSharp.Fonts\AdobeGlyphList20.cs" />
     <Compile Include="PdfSharp.Fonts\AdobeGlyphListForNewFonts.cs" />
     <Compile Include="PdfSharp.Fonts\CMapInfo.cs" />
+    <Compile Include="PdfSharp.Fonts\FontDescriptor.cs" />
+    <Compile Include="PdfSharp.Fonts\FontDescriptorStock.cs" />
     <Compile Include="PdfSharp.Fonts\FontWriter.cs" />
     <Compile Include="PdfSharp.Forms\ColorComboBox.cs">
       <SubType>Component</SubType>
@@ -177,7 +183,7 @@
     <Compile Include="PdfSharp.Pdf.AcroForms\PdfAcroForm.cs" />
     <Compile Include="PdfSharp.Pdf.AcroForms\PdfButtonField.cs" />
     <Compile Include="PdfSharp.Pdf.AcroForms\PdfCheckBoxField.cs" />
-    <Compile Include="PdfSharp.Pdf.AcroForms\PdfChoiseField.cs" />
+    <Compile Include="PdfSharp.Pdf.AcroForms\PdfChoiceField.cs" />
     <Compile Include="PdfSharp.Pdf.AcroForms\PdfComboBoxField.cs" />
     <Compile Include="PdfSharp.Pdf.AcroForms\PdfGenericField.cs" />
     <Compile Include="PdfSharp.Pdf.AcroForms\PdfListBoxField.cs" />
@@ -205,6 +211,7 @@
     <Compile Include="PdfSharp.Pdf.Advanced\PdfImageTable.cs" />
     <Compile Include="PdfSharp.Pdf.Advanced\PdfImportedObjectTable.cs" />
     <Compile Include="PdfSharp.Pdf.Advanced\PdfInternals.cs" />
+    <Compile Include="PdfSharp.Pdf.Advanced\PdfObjectInternals.cs" />
     <Compile Include="PdfSharp.Pdf.Advanced\PdfPageInheritableObjects.cs" />
     <Compile Include="PdfSharp.Pdf.Advanced\PdfReference.cs" />
     <Compile Include="PdfSharp.Pdf.Advanced\PdfResourceMap.cs" />
@@ -258,6 +265,7 @@
     <Compile Include="PdfSharp.Pdf.Internal\RawUnicodeEncoding.cs" />
     <Compile Include="PdfSharp.Pdf.Internal\ThreadLocalStorage.cs" />
     <Compile Include="PdfSharp.Pdf.IO\Chars.cs" />
+    <Compile Include="PdfSharp.Pdf.IO\enums\PasswordValidity.cs" />
     <Compile Include="PdfSharp.Pdf.IO\enums\PdfDocumentOpenMode.cs" />
     <Compile Include="PdfSharp.Pdf.IO\enums\PdfWriterLayout.cs" />
     <Compile Include="PdfSharp.Pdf.IO\enums\PdfWriterOptions.cs" />
@@ -352,6 +360,7 @@
   </ItemGroup>
   <ItemGroup>
     <Content Include="PdfSharp.Drawing.BarCodes\%40BarCodes.txt" />
+    <Content Include="PdfSharp.Drawing.Wpf\!info.txt" />
     <Content Include="PdfSharp.SharpZipLib\ReadMe.txt" />
     <None Include="Resources\Messages.de.txt" />
     <None Include="Resources\Messages.txt" />
@@ -378,7 +387,7 @@
     <None Include="Resources\PdfSharp.resources.vcproj" />
   </ItemGroup>
   <ItemGroup>
-    <Folder Include="PdfSharp.Drawing.Wpf\" />
+    <Folder Include="PdfSharp.Drawing.Rtf\" />
     <Folder Include="PdfSharp.Windows\" />
     <Folder Include="Resources\images\" />
   </ItemGroup>
diff --git a/lib/PdfSharp/PdfSharp-Hybrid.csproj.resharper b/lib/PdfSharp/PdfSharp-Hybrid.csproj.resharper
new file mode 100644
index 0000000..16ecced
--- /dev/null
+++ b/lib/PdfSharp/PdfSharp-Hybrid.csproj.resharper
@@ -0,0 +1,3 @@
+<Configuration>
+  <CSharpLanguageLevel>CSharp20</CSharpLanguageLevel>
+</Configuration>
\ No newline at end of file
diff --git a/lib/PdfSharp/PdfSharp-WPF.csproj b/lib/PdfSharp/PdfSharp-WPF.csproj
index 45e3259..90f4d7c 100644
--- a/lib/PdfSharp/PdfSharp-WPF.csproj
+++ b/lib/PdfSharp/PdfSharp-WPF.csproj
@@ -3,7 +3,7 @@
   <PropertyGroup>
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
     <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProductVersion>9.0.21022</ProductVersion>
+    <ProductVersion>9.0.30729</ProductVersion>
     <SchemaVersion>2.0</SchemaVersion>
     <ProjectGuid>{02FCC0BB-2AA2-43BA-8D2F-66D168B87A1D}</ProjectGuid>
     <OutputType>Library</OutputType>
@@ -24,6 +24,7 @@
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
     <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
+    <DocumentationFile>bin\Debug\PdfSharp-WPF.XML</DocumentationFile>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
     <DebugType>pdbonly</DebugType>
@@ -43,6 +44,7 @@
     </Reference>
     <Reference Include="System" />
     <Reference Include="System.Data" />
+    <Reference Include="System.Drawing" />
     <Reference Include="System.Xml" />
     <Reference Include="WindowsBase">
       <RequiredTargetFramework>3.0</RequiredTargetFramework>
@@ -51,6 +53,7 @@
   <ItemGroup>
     <Compile Include="!internal\Directives.cs" />
     <Compile Include="!internal\TargetContext.cs" />
+    <Compile Include="AGInternals\AgHacks.cs" />
     <Compile Include="PdfSharp.Drawing.BarCodes\BarCode.cs" />
     <Compile Include="PdfSharp.Drawing.BarCodes\BarCodeRenderInfo.cs" />
     <Compile Include="PdfSharp.Drawing.BarCodes\BcgSR.cs" />
@@ -75,8 +78,12 @@
     <Compile Include="PdfSharp.Drawing.Pdf\enums\StreamMode.cs" />
     <Compile Include="PdfSharp.Drawing.Pdf\PdfGraphicsState.cs" />
     <Compile Include="PdfSharp.Drawing.Pdf\XGraphicsPdfRenderer.cs" />
-    <Compile Include="PdfSharp.Drawing.Rtf\XGraphicsRtfRenderer.cs" />
     <Compile Include="PdfSharp.Drawing.Shapes\Shape.cs" />
+    <Compile Include="PdfSharp.Drawing\XFontWeights.cs" />
+    <Compile Include="PdfSharp.Drawing\XFontStretch.cs" />
+    <Compile Include="PdfSharp.Drawing\XGlyphTypeFace.cs" />
+    <Compile Include="PdfSharp.Drawing\XFontWeight.cs" />
+    <Compile Include="PdfSharp.Drawing\XTypeFace.cs" />
     <Compile Include="PdfSharp.Drawing\enums\PathStart.cs" />
     <Compile Include="PdfSharp.Drawing\enums\XColorSpace.cs" />
     <Compile Include="PdfSharp.Drawing\enums\XCombineMode.cs" />
@@ -136,24 +143,26 @@
     <Compile Include="PdfSharp.Drawing\XStringFormats.cs" />
     <Compile Include="PdfSharp.Drawing\XUnit.cs" />
     <Compile Include="PdfSharp.Drawing\XVector.cs" />
-    <Compile Include="PdfSharp.Fonts.TrueType\enums\TableTag.cs" />
-    <Compile Include="PdfSharp.Fonts.TrueType\enums\TableTagNames.cs" />
-    <Compile Include="PdfSharp.Fonts.TrueType\ExternalHelper.cs" />
-    <Compile Include="PdfSharp.Fonts.TrueType\FontData.cs" />
-    <Compile Include="PdfSharp.Fonts.TrueType\FontDescriptor.cs" />
-    <Compile Include="PdfSharp.Fonts.TrueType\FontDescriptorStock.cs" />
-    <Compile Include="PdfSharp.Fonts.TrueType\GenericFontTable.cs" />
-    <Compile Include="PdfSharp.Fonts.TrueType\GlyphDataTable.cs" />
-    <Compile Include="PdfSharp.Fonts.TrueType\IndexToLocationTable.cs" />
-    <Compile Include="PdfSharp.Fonts.TrueType\IRefFontTable.cs" />
-    <Compile Include="PdfSharp.Fonts.TrueType\TableDirectoryEntry.cs" />
-    <Compile Include="PdfSharp.Fonts.TrueType\TrueTypeDescriptor.cs" />
-    <Compile Include="PdfSharp.Fonts.TrueType\TrueTypeFontTable.cs" />
-    <Compile Include="PdfSharp.Fonts.TrueType\TrueTypeFontWriter.cs" />
-    <Compile Include="PdfSharp.Fonts.TrueType\TrueTypeStructures.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\enums\FontTechnology.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\enums\TableTag.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\enums\TableTagNames.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\ExternalHelper.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\FontData.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\FontDataStock.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\GenericFontTable.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\GlyphDataTable.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\IndexToLocationTable.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\IRefFontTable.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\OpenTypeDescriptor.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\OpenTypeFontTable.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\OpenTypeFontWriter.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\OpenTypeStructures.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\TableDirectoryEntry.cs" />
     <Compile Include="PdfSharp.Fonts\AdobeGlyphList20.cs" />
     <Compile Include="PdfSharp.Fonts\AdobeGlyphListForNewFonts.cs" />
     <Compile Include="PdfSharp.Fonts\CMapInfo.cs" />
+    <Compile Include="PdfSharp.Fonts\FontDescriptor.cs" />
+    <Compile Include="PdfSharp.Fonts\FontDescriptorStock.cs" />
     <Compile Include="PdfSharp.Fonts\FontWriter.cs" />
     <Compile Include="PdfSharp.Internal\Calc.cs" />
     <Compile Include="PdfSharp.Internal\ColorHelper.cs" />
@@ -165,7 +174,7 @@
     <Compile Include="PdfSharp.Pdf.AcroForms\PdfAcroForm.cs" />
     <Compile Include="PdfSharp.Pdf.AcroForms\PdfButtonField.cs" />
     <Compile Include="PdfSharp.Pdf.AcroForms\PdfCheckBoxField.cs" />
-    <Compile Include="PdfSharp.Pdf.AcroForms\PdfChoiseField.cs" />
+    <Compile Include="PdfSharp.Pdf.AcroForms\PdfChoiceField.cs" />
     <Compile Include="PdfSharp.Pdf.AcroForms\PdfComboBoxField.cs" />
     <Compile Include="PdfSharp.Pdf.AcroForms\PdfGenericField.cs" />
     <Compile Include="PdfSharp.Pdf.AcroForms\PdfListBoxField.cs" />
@@ -175,6 +184,8 @@
     <Compile Include="PdfSharp.Pdf.AcroForms\PdfTextField.cs" />
     <Compile Include="PdfSharp.Pdf.Actions\enums\PdfNamedActionNames.cs" />
     <Compile Include="PdfSharp.Pdf.Actions\PdfAction.cs" />
+    <Compile Include="PdfSharp.Pdf.Advanced\PdfImage.FaxEncode.cs" />
+    <Compile Include="PdfSharp.Pdf.Advanced\PdfObjectInternals.cs" />
     <Compile Include="PdfSharp.Pdf.Advanced\PdfDictionaryWithContentStream.cs" />
     <Compile Include="PdfSharp.Pdf.Advanced\IContentStream.cs" />
     <Compile Include="PdfSharp.Pdf.Advanced\PdfCatalog.cs" />
@@ -246,6 +257,7 @@
     <Compile Include="PdfSharp.Pdf.Internal\RawUnicodeEncoding.cs" />
     <Compile Include="PdfSharp.Pdf.Internal\ThreadLocalStorage.cs" />
     <Compile Include="PdfSharp.Pdf.IO\Chars.cs" />
+    <Compile Include="PdfSharp.Pdf.IO\enums\PasswordValidity.cs" />
     <Compile Include="PdfSharp.Pdf.IO\enums\PdfDocumentOpenMode.cs" />
     <Compile Include="PdfSharp.Pdf.IO\enums\PdfWriterLayout.cs" />
     <Compile Include="PdfSharp.Pdf.IO\enums\PdfWriterOptions.cs" />
@@ -361,6 +373,8 @@
   </ItemGroup>
   <ItemGroup>
     <Folder Include="PdfSharp.Drawing.Wpf\" />
+    <Folder Include="PdfSharp.Forms\" />
+    <Folder Include="PdfSharpPdf.AcroForms\enums\" />
     <Folder Include="Resources\images\" />
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
diff --git a/lib/PdfSharp/PdfSharp-WPF.csproj.resharper b/lib/PdfSharp/PdfSharp-WPF.csproj.resharper
new file mode 100644
index 0000000..16ecced
--- /dev/null
+++ b/lib/PdfSharp/PdfSharp-WPF.csproj.resharper
@@ -0,0 +1,3 @@
+<Configuration>
+  <CSharpLanguageLevel>CSharp20</CSharpLanguageLevel>
+</Configuration>
\ No newline at end of file
diff --git a/lib/PdfSharp/PdfSharp.Drawing.BarCodes/BarCode.cs b/lib/PdfSharp/PdfSharp.Drawing.BarCodes/BarCode.cs
index 9c52d96..9d22d56 100644
--- a/lib/PdfSharp/PdfSharp.Drawing.BarCodes/BarCode.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing.BarCodes/BarCode.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Klaus Potzesny (mailto:Klaus Potzesny pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -67,7 +67,11 @@ namespace PdfSharp.Drawing.BarCodes
           return new Code3of9Standard(text, size, direction);
 
         default:
+#if !SILVERLIGHT
           throw new InvalidEnumArgumentException("type", (int)type, typeof(CodeType));
+#else
+          throw new ArgumentException("type", type.ToString());
+#endif
       }
     }
 
@@ -98,7 +102,7 @@ namespace PdfSharp.Drawing.BarCodes
     /// <summary>
     /// When overridden in a derived class gets or sets the wide narrow ratio.
     /// </summary>
-    public virtual double WideNarrowRatio 
+    public virtual double WideNarrowRatio
     {
       get { return 0; }
       set { }
@@ -125,7 +129,7 @@ namespace PdfSharp.Drawing.BarCodes
     internal int dataLength;
 
     /// <summary>
-    /// Gets or sets the optional start chararacter.
+    /// Gets or sets the optional start character.
     /// </summary>
     public char StartChar
     {
@@ -135,7 +139,7 @@ namespace PdfSharp.Drawing.BarCodes
     internal char startChar;
 
     /// <summary>
-    /// Gets or sets the optional end chararacter.
+    /// Gets or sets the optional end character.
     /// </summary>
     public char EndChar
     {
@@ -153,7 +157,7 @@ namespace PdfSharp.Drawing.BarCodes
       get { return this.turboBit; }
       set { this.turboBit = value; }
     }
-    internal bool turboBit = false;
+    internal bool turboBit;
 
     internal virtual void InitRendering(BarCodeRenderInfo info)
     {
diff --git a/lib/PdfSharp/PdfSharp.Drawing.BarCodes/BarCodeRenderInfo.cs b/lib/PdfSharp/PdfSharp.Drawing.BarCodes/BarCodeRenderInfo.cs
index 0664620..94adc5c 100644
--- a/lib/PdfSharp/PdfSharp.Drawing.BarCodes/BarCodeRenderInfo.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing.BarCodes/BarCodeRenderInfo.cs
@@ -4,7 +4,7 @@
 // Authors:
 //   Klaus Potzesny (mailto:Klaus Potzesny pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 //
diff --git a/lib/PdfSharp/PdfSharp.Drawing.BarCodes/BcgSR.cs b/lib/PdfSharp/PdfSharp.Drawing.BarCodes/BcgSR.cs
index 85c341a..56315f4 100644
--- a/lib/PdfSharp/PdfSharp.Drawing.BarCodes/BcgSR.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing.BarCodes/BcgSR.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Klaus Potzesny (mailto:Klaus Potzesny pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -33,7 +33,7 @@ namespace PdfSharp.Drawing.BarCodes
 {
   // TODO: Mere with PDFsharp strings table
   /// <summary>
-  /// String resources for the empira barcde renderer.
+  /// String resources for the empira barcode renderer.
   /// </summary>
   internal class BcgSR
   {
diff --git a/lib/PdfSharp/PdfSharp.Drawing.BarCodes/Code2of5Interleaved.cs b/lib/PdfSharp/PdfSharp.Drawing.BarCodes/Code2of5Interleaved.cs
index 2aa3a19..a81f9d5 100644
--- a/lib/PdfSharp/PdfSharp.Drawing.BarCodes/Code2of5Interleaved.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing.BarCodes/Code2of5Interleaved.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Klaus Potzesny (mailto:Klaus Potzesny pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -34,7 +34,7 @@ using PdfSharp.Drawing;
 namespace PdfSharp.Drawing.BarCodes
 {
   /// <summary>
-  /// Summary description for Interleave5of9.
+  /// Implementation of the Code 2 of 5 bar code.
   /// </summary>
   public class Code2of5Interleaved : ThickThinBarCode
   {
@@ -122,7 +122,7 @@ namespace PdfSharp.Drawing.BarCodes
 
     /// <summary>
     /// Calculates the thick and thin line widths,
-    /// taking into acount the required rendering size.
+    /// taking into account the required rendering size.
     /// </summary>
     internal override void CalcThinBarWidth(BarCodeRenderInfo info)
     {
diff --git a/lib/PdfSharp/PdfSharp.Drawing.BarCodes/Code3of9Standard.cs b/lib/PdfSharp/PdfSharp.Drawing.BarCodes/Code3of9Standard.cs
index 5d02d9f..fb37012 100644
--- a/lib/PdfSharp/PdfSharp.Drawing.BarCodes/Code3of9Standard.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing.BarCodes/Code3of9Standard.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Klaus Potzesny (mailto:Klaus Potzesny pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -33,7 +33,7 @@ using System.Diagnostics;
 namespace PdfSharp.Drawing.BarCodes
 {
   /// <summary>
-  /// 
+  /// Imlpementation of the Code 3 of 9 bar code.
   /// </summary>
   public class Code3of9Standard : ThickThinBarCode
   {
@@ -173,7 +173,7 @@ namespace PdfSharp.Drawing.BarCodes
 
     /// <summary>
     /// Calculates the thick and thin line widths,
-    /// taking into acount the required rendering size.
+    /// taking into account the required rendering size.
     /// </summary>
     internal override void CalcThinBarWidth(BarCodeRenderInfo info)
     {
diff --git a/lib/PdfSharp/PdfSharp.Drawing.BarCodes/CodeBase.cs b/lib/PdfSharp/PdfSharp.Drawing.BarCodes/CodeBase.cs
index e8a8f74..69a3eda 100644
--- a/lib/PdfSharp/PdfSharp.Drawing.BarCodes/CodeBase.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing.BarCodes/CodeBase.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Klaus Potzesny (mailto:Klaus Potzesny pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -124,7 +124,7 @@ namespace PdfSharp.Drawing.BarCodes
     internal CodeDirection direction;
 
     /// <summary>
-    /// Whem implemented in a derived class, determines whether the specified string can be used as Text
+    /// When implemented in a derived class, determines whether the specified string can be used as Text
     /// for this bar code type.
     /// </summary>
     /// <param name="text">The code string to check.</param>
@@ -137,13 +137,12 @@ namespace PdfSharp.Drawing.BarCodes
     /// <param name="oldType"></param>
     /// <param name="newType"></param>
     /// <param name="size"></param>
-    /// <returns></returns>
     public static XVector CalcDistance(AnchorType oldType, AnchorType newType, XSize size)
     {
       if (oldType == newType)
         return new XVector();
 
-      XVector result = new XVector();
+      XVector result;
       Delta delta = CodeBase.deltas[(int)oldType, (int)newType];
       result = new XVector(size.width / 2 * delta.x, size.height / 2 * delta.y);
       return result;
diff --git a/lib/PdfSharp/PdfSharp.Drawing.BarCodes/CodeDataMatrix.cs b/lib/PdfSharp/PdfSharp.Drawing.BarCodes/CodeDataMatrix.cs
index 1b42fd0..5821f9c 100644
--- a/lib/PdfSharp/PdfSharp.Drawing.BarCodes/CodeDataMatrix.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing.BarCodes/CodeDataMatrix.cs
@@ -4,7 +4,7 @@
 //   David Stephensen (mailto:David Stephensen pdfsharp com)
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Drawing.BarCodes/CodeOmr.cs b/lib/PdfSharp/PdfSharp.Drawing.BarCodes/CodeOmr.cs
index f32f28c..af1420e 100644
--- a/lib/PdfSharp/PdfSharp.Drawing.BarCodes/CodeOmr.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing.BarCodes/CodeOmr.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Klaus Potzesny (mailto:Klaus Potzesny pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Drawing.BarCodes/DataMatrixImage.cs b/lib/PdfSharp/PdfSharp.Drawing.BarCodes/DataMatrixImage.cs
index ba16025..ff4820e 100644
--- a/lib/PdfSharp/PdfSharp.Drawing.BarCodes/DataMatrixImage.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing.BarCodes/DataMatrixImage.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   David Stephensen (mailto:David Stephensen pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Drawing.BarCodes/MatrixCode.cs b/lib/PdfSharp/PdfSharp.Drawing.BarCodes/MatrixCode.cs
index 77b2e40..3e61328 100644
--- a/lib/PdfSharp/PdfSharp.Drawing.BarCodes/MatrixCode.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing.BarCodes/MatrixCode.cs
@@ -4,7 +4,7 @@
 //   David Stephensen (mailto:David Stephensen pdfsharp com)
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -47,7 +47,7 @@ namespace PdfSharp.Drawing.BarCodes
       : base(text, size, CodeDirection.LeftToRight)
     {
       this.encoding = encoding;
-      if (this.encoding == "" || this.encoding == null)
+      if (String.IsNullOrEmpty(this.encoding))
         this.encoding = new String('a', this.text.Length);
 
       if (columns < rows)
@@ -119,7 +119,7 @@ namespace PdfSharp.Drawing.BarCodes
       }
     }
 
-    internal XImage matrixImage = null;
+    internal XImage matrixImage;
 
     /// <summary>
     /// When implemented in a derived class renders the 2D code.
diff --git a/lib/PdfSharp/PdfSharp.Drawing.BarCodes/OmrData.cs b/lib/PdfSharp/PdfSharp.Drawing.BarCodes/OmrData.cs
index 820ab5d..04dc7c1 100644
--- a/lib/PdfSharp/PdfSharp.Drawing.BarCodes/OmrData.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing.BarCodes/OmrData.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Klaus Potzesny (mailto:Klaus Potzesny pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Drawing.BarCodes/ThickThinBarcodeRenderer.cs b/lib/PdfSharp/PdfSharp.Drawing.BarCodes/ThickThinBarcodeRenderer.cs
index 3aa48a9..d1d7e95 100644
--- a/lib/PdfSharp/PdfSharp.Drawing.BarCodes/ThickThinBarcodeRenderer.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing.BarCodes/ThickThinBarcodeRenderer.cs
@@ -4,7 +4,7 @@
 // Authors:
 //   Klaus Potzesny (mailto:Klaus Potzesny pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 //
@@ -51,7 +51,7 @@ namespace PdfSharp.Drawing.BarCodes
       base.InitRendering(info);
       CalcThinBarWidth(info);
       info.BarHeight = Size.Height;
-      // HACK 
+      // HACK in ThickThinBarCode
       if (this.textLocation != TextLocation.None)
         info.BarHeight *= 4.0 / 5;
 
@@ -78,7 +78,7 @@ namespace PdfSharp.Drawing.BarCodes
     }
 
     /// <summary>
-    /// Gets or sets the ration between thick an thin lines. Must be between 2 an 3.
+    /// Gets or sets the ration between thick an thin lines. Must be between 2 and 3.
     /// Optimal and also default value is 2.6.
     /// </summary>
     public override double WideNarrowRatio
diff --git a/lib/PdfSharp/PdfSharp.Drawing.BarCodes/enums/AnchorType.cs b/lib/PdfSharp/PdfSharp.Drawing.BarCodes/enums/AnchorType.cs
index 647b760..525cbdb 100644
--- a/lib/PdfSharp/PdfSharp.Drawing.BarCodes/enums/AnchorType.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing.BarCodes/enums/AnchorType.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Klaus Potzesny (mailto:Klaus Potzesny pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Drawing.BarCodes/enums/CodeDirection.cs b/lib/PdfSharp/PdfSharp.Drawing.BarCodes/enums/CodeDirection.cs
index e0ddbd1..6dfe71e 100644
--- a/lib/PdfSharp/PdfSharp.Drawing.BarCodes/enums/CodeDirection.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing.BarCodes/enums/CodeDirection.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Klaus Potzesny (mailto:Klaus Potzesny pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Drawing.BarCodes/enums/CodeType.cs b/lib/PdfSharp/PdfSharp.Drawing.BarCodes/enums/CodeType.cs
index 823989e..3687770 100644
--- a/lib/PdfSharp/PdfSharp.Drawing.BarCodes/enums/CodeType.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing.BarCodes/enums/CodeType.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Klaus Potzesny (mailto:Klaus Potzesny pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Drawing.BarCodes/enums/DataMatrixEncoding.cs b/lib/PdfSharp/PdfSharp.Drawing.BarCodes/enums/DataMatrixEncoding.cs
index c63a53a..58bee67 100644
--- a/lib/PdfSharp/PdfSharp.Drawing.BarCodes/enums/DataMatrixEncoding.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing.BarCodes/enums/DataMatrixEncoding.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Klaus Potzesny (mailto:Klaus Potzesny pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Drawing.BarCodes/enums/MarkDistance.cs b/lib/PdfSharp/PdfSharp.Drawing.BarCodes/enums/MarkDistance.cs
index 3703d3e..d5a73c5 100644
--- a/lib/PdfSharp/PdfSharp.Drawing.BarCodes/enums/MarkDistance.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing.BarCodes/enums/MarkDistance.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Klaus Potzesny (mailto:Klaus Potzesny pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Drawing.BarCodes/enums/TextLocation.cs b/lib/PdfSharp/PdfSharp.Drawing.BarCodes/enums/TextLocation.cs
index 8a18c7d..a1e61d6 100644
--- a/lib/PdfSharp/PdfSharp.Drawing.BarCodes/enums/TextLocation.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing.BarCodes/enums/TextLocation.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Klaus Potzesny (mailto:Klaus Potzesny pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Drawing.Layout/XTextFormatter.cs b/lib/PdfSharp/PdfSharp.Drawing.Layout/XTextFormatter.cs
index 6520561..48f9d2c 100644
--- a/lib/PdfSharp/PdfSharp.Drawing.Layout/XTextFormatter.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing.Layout/XTextFormatter.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -28,6 +28,7 @@
 #endregion
 
 using System;
+using System.Collections.Generic;
 using System.Diagnostics;
 using System.Collections;
 using System.Text;
@@ -39,7 +40,7 @@ namespace PdfSharp.Drawing.Layout
   /// <summary>
   /// Represents a very simple text formatter.
   /// If this class does not satisfy your needs on formatting paragraphs I recommend to take a look
-  /// at MigraDoc Lite. Alternatively you should copy this class in you own source code and modify it.
+  /// at MigraDoc Foundation. Alternatively you should copy this class in your own source code and modify it.
   /// </summary>
   public class XTextFormatter
   {
@@ -81,7 +82,7 @@ namespace PdfSharp.Drawing.Layout
         this.cyAscent = lineSpace * font.cellAscent / font.cellSpace;
         this.cyDescent = lineSpace * font.cellDescent / font.cellSpace;
 
-        // HACK
+        // HACK in XTextFormatter
         this.spaceWidth = gfx.MeasureString("x x", value).width;
         this.spaceWidth -= gfx.MeasureString("xx", value).width;
       }
@@ -247,28 +248,28 @@ namespace PdfSharp.Drawing.Layout
         }
         else
         {
-          double width = this.spaceWidth + block.Width;
+          double width = block.Width; //!!!modTHHO 19.11.09 don't add this.spaceWidth here
           if ((x + width <= rectWidth || x == 0) && block.Type != BlockType.LineBreak)
           {
             block.Location = new XPoint(x, y);
-            x += width;
+            x += width + spaceWidth; //!!!modTHHO 19.11.09 add this.spaceWidth here
           }
           else
           {
             AlignLine(firstIndex, idx - 1, rectWidth);
             firstIndex = idx;
-            y += this.lineSpace;
+            y += lineSpace;
             if (y > rectHeight)
             {
               block.Stop = true;
               break;
             }
             block.Location = new XPoint(0, y);
-            x = width;
+            x = width + spaceWidth; //!!!modTHHO 19.11.09 add this.spaceWidth here
           }
         }
       }
-      if (firstIndex < count && this.Alignment != XParagraphAlignment.Justify)
+      if (firstIndex < count && Alignment != XParagraphAlignment.Justify)
         AlignLine(firstIndex, count - 1, rectWidth);
     }
 
@@ -312,7 +313,7 @@ namespace PdfSharp.Drawing.Layout
       }
     }
 
-    ArrayList blocks = new ArrayList();
+    readonly List<Block> blocks = new List<Block>();
 
     enum BlockType
     {
@@ -362,7 +363,7 @@ namespace PdfSharp.Drawing.Layout
       public double Width;
 
       /// <summary>
-      /// The location relative to the opper left corner of the layout rectangle.
+      /// The location relative to the upper left corner of the layout rectangle.
       /// </summary>
       public XPoint Location;
 
diff --git a/lib/PdfSharp/PdfSharp.Drawing.Layout/enums/XParagraphAlignment.cs b/lib/PdfSharp/PdfSharp.Drawing.Layout/enums/XParagraphAlignment.cs
index d100e1c..16f279e 100644
--- a/lib/PdfSharp/PdfSharp.Drawing.Layout/enums/XParagraphAlignment.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing.Layout/enums/XParagraphAlignment.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Drawing.Pdf/PdfGraphicsState.cs b/lib/PdfSharp/PdfSharp.Drawing.Pdf/PdfGraphicsState.cs
index ca77aa7..118720f 100644
--- a/lib/PdfSharp/PdfSharp.Drawing.Pdf/PdfGraphicsState.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing.Pdf/PdfGraphicsState.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -31,15 +31,12 @@ using System;
 using System.Diagnostics;
 using System.Globalization;
 using System.Text;
-using System.IO;
 #if GDI
 using System.Drawing;
 using System.Drawing.Drawing2D;
 #endif
 #if WPF
-using System.Windows.Media;
 #endif
-using PdfSharp.Internal;
 using PdfSharp.Pdf;
 using PdfSharp.Pdf.Advanced;
 using PdfSharp.Pdf.Internal;
@@ -71,7 +68,7 @@ namespace PdfSharp.Drawing.Pdf
     {
       this.renderer = renderer;
     }
-    XGraphicsPdfRenderer renderer;
+    readonly XGraphicsPdfRenderer renderer;
 
     public PdfGraphicsState Clone()
     {
@@ -298,7 +295,7 @@ namespace PdfSharp.Drawing.Pdf
 
     internal PdfFont realizedFont;
     string realizedFontName = String.Empty;
-    double realizedFontSize = 0;
+    double realizedFontSize;
 
     public void RealizeFont(XFont font, XBrush brush, int renderMode)
     {
@@ -319,7 +316,7 @@ namespace PdfSharp.Drawing.Pdf
       }
     }
 
-    public XPoint realizedTextPosition = new XPoint();
+    public XPoint realizedTextPosition;
 
     #endregion
 
@@ -328,12 +325,12 @@ namespace PdfSharp.Drawing.Pdf
     /// <summary>
     /// The realized current transformation matrix.
     /// </summary>
-    XMatrix realizedCtm = XMatrix.Identity;
+    private XMatrix realizedCtm;
 
     /// <summary>
     /// The unrealized current transformation matrix.
     /// </summary>
-    XMatrix unrealizedCtm = XMatrix.Identity;
+    XMatrix unrealizedCtm;
 
     /// <summary>
     /// A flag indicating whether the CTM must be realized.
@@ -389,7 +386,7 @@ namespace PdfSharp.Drawing.Pdf
           matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]);
 
         this.realizedCtm.Prepend(this.unrealizedCtm);
-        this.unrealizedCtm = XMatrix.Identity;
+        this.unrealizedCtm = new XMatrix();  //XMatrix.Identity;
         this.MustRealizeCtm = false;
       }
     }
diff --git a/lib/PdfSharp/PdfSharp.Drawing.Pdf/XGraphicsPdfRenderer.cs b/lib/PdfSharp/PdfSharp.Drawing.Pdf/XGraphicsPdfRenderer.cs
index 97e192e..cd98625 100644
--- a/lib/PdfSharp/PdfSharp.Drawing.Pdf/XGraphicsPdfRenderer.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing.Pdf/XGraphicsPdfRenderer.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -44,7 +44,7 @@ using System.Windows.Media;
 using PdfSharp.Internal;
 using PdfSharp.Pdf;
 using PdfSharp.Fonts;
-using PdfSharp.Fonts.TrueType;
+using PdfSharp.Fonts.OpenType;
 using PdfSharp.Pdf.Internal;
 using PdfSharp.Pdf.Advanced;
 
@@ -499,7 +499,7 @@ namespace PdfSharp.Drawing.Pdf
       Debug.Assert(realizedFont != null);
       realizedFont.AddChars(s);
 
-      TrueTypeDescriptor descriptor = realizedFont.FontDescriptor.descriptor;
+      OpenTypeDescriptor descriptor = realizedFont.FontDescriptor.descriptor;
 
       if (bold && !descriptor.IsBoldFace)
       {
@@ -531,7 +531,7 @@ namespace PdfSharp.Drawing.Pdf
 
         byte[] bytes = PdfEncoders.RawUnicodeEncoding.GetBytes(s);
         bytes = PdfEncoders.FormatStringLiteral(bytes, true, false, true, null);
-        string text = PdfEncoders.RawEncoding.GetString(bytes);
+        string text = PdfEncoders.RawEncoding.GetString(bytes, 0, bytes.Length);
         XPoint pos = new XPoint(x, y);
         AdjustTextMatrix(ref pos);
         AppendFormat(
@@ -843,7 +843,7 @@ namespace PdfSharp.Drawing.Pdf
       // Save InternalGraphicsState and transformation of the current graphical state.
       InternalGraphicsState state = this.gfxState.InternalState;
       XMatrix ctm = this.gfxState.Transform;
-      // Empty clip path by switching back the the previous state.
+      // Empty clip path by switching back to the previous state.
       RestoreState();
       SaveState();
       // Save internal state
@@ -870,7 +870,7 @@ namespace PdfSharp.Drawing.Pdf
     public void WriteComment(string comment)
     {
       comment.Replace("\n", "\n% ");
-      // TODO: Some more checks neccessary?
+      // TODO: Some more checks necessary?
       Append("% " + comment + "\n");
     }
 
@@ -1003,8 +1003,8 @@ namespace PdfSharp.Drawing.Pdf
       //   1 | 0
       //     |
       // If the angles lie in quarter 2 or 3, their values are subtracted by 180 and the
-      // resulting curve is reflected at the center. This algorythm works as expected (simply tried out).
-      // There may be a mathematical more elegant solution...
+      // resulting curve is reflected at the center. This algorithm works as expected (simply tried out).
+      // There may be a mathematically more elegant solution...
       bool reflect = false;
       if (α >= 180 && β >= 180)
       {
@@ -1094,6 +1094,24 @@ namespace PdfSharp.Drawing.Pdf
     void AppendPartialArc(System.Windows.Point point1, System.Windows.Point point2, double rotationAngle,
       System.Windows.Size size, bool isLargeArc, System.Windows.Media.SweepDirection sweepDirection, PathStart pathStart)
     {
+#if true
+      //AppendPartialArc(currentPoint, seg.Point, seg.RotationAngle, seg.Size, seg.IsLargeArc, seg.SweepDirection, PathStart.Ignore1st);
+
+      int pieces;
+      PointCollection points = GeometryHelper.ArcToBezier(point1.X, point1.Y, size.Width, size.Height, rotationAngle, isLargeArc, 
+        sweepDirection == SweepDirection.Clockwise, point2.X, point2.Y, out pieces);
+
+      int count = points.Count;
+      int start = count % 3 == 1 ? 1 : 0;
+      if (start == 1)
+        AppendFormat("{0:0.####} {1:0.####} m\n", points[0].X, points[0].Y);
+      for (int idx = start; idx < count; idx += 3)
+        AppendFormat("{0:0.####} {1:0.####} {2:0.####} {3:0.####} {4:0.####} {5:0.####} c\n",
+          points[idx].X, points[idx].Y,
+          points[idx + 1].X, points[idx + 1].Y,
+          points[idx + 2].X, points[idx + 2].Y);
+
+#else
       List<XPoint> points = GeometryHelper.BezierCurveFromArc((XPoint)point1, (XPoint)point2, rotationAngle, (XSize)size,
         isLargeArc, sweepDirection == SweepDirection.Clockwise, pathStart);
       int count = points.Count;
@@ -1105,6 +1123,7 @@ namespace PdfSharp.Drawing.Pdf
           points[idx].X, points[idx].Y,
           points[idx + 1].X, points[idx + 1].Y,
           points[idx + 2].X, points[idx + 2].Y);
+#endif
     }
 #endif
 
@@ -1251,14 +1270,14 @@ namespace PdfSharp.Drawing.Pdf
           {
             QuadraticBezierSegment seg = (QuadraticBezierSegment)segment;
             currentPoint = seg.Point2;
-            // TODOWPF
+            // TODOWPF: Undone because XGraphics has no such curve type
             throw new NotImplementedException("AppendPath with QuadraticBezierSegment.");
           }
           else if (type == typeof(PolyQuadraticBezierSegment))
           {
             PolyQuadraticBezierSegment seg = (PolyQuadraticBezierSegment)segment;
             currentPoint = seg.Points[seg.Points.Count - 1];
-            // TODOWPF
+            // TODOWPF: Undone because XGraphics has no such curve type
             throw new NotImplementedException("AppendPath with PolyQuadraticBezierSegment.");
           }
         }
@@ -1318,7 +1337,7 @@ namespace PdfSharp.Drawing.Pdf
       {
         // Flip page horizontaly and mirror text.
         // TODO: Is PageOriging and PageScale (== Viewport) useful? Or just public DefaultViewMatrix (like Presentation Manager has had)
-        this.defaultViewMatrix = XMatrix.Identity;
+        this.defaultViewMatrix = new XMatrix();  //XMatrix.Identity;
         if (this.gfx.PageDirection == XPageDirection.Downwards)
         {
 #if MIGRADOC
diff --git a/lib/PdfSharp/PdfSharp.Drawing.Pdf/enums/DirtyFlags.cs b/lib/PdfSharp/PdfSharp.Drawing.Pdf/enums/DirtyFlags.cs
index bc8e435..224123e 100644
--- a/lib/PdfSharp/PdfSharp.Drawing.Pdf/enums/DirtyFlags.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing.Pdf/enums/DirtyFlags.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Drawing.Pdf/enums/StreamMode.cs b/lib/PdfSharp/PdfSharp.Drawing.Pdf/enums/StreamMode.cs
index cb06df8..5f62671 100644
--- a/lib/PdfSharp/PdfSharp.Drawing.Pdf/enums/StreamMode.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing.Pdf/enums/StreamMode.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Drawing.Shapes/Shape.cs b/lib/PdfSharp/PdfSharp.Drawing.Shapes/Shape.cs
index 41b7698..33fa2d0 100644
--- a/lib/PdfSharp/PdfSharp.Drawing.Shapes/Shape.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing.Shapes/Shape.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Drawing.Wpf/!info.txt b/lib/PdfSharp/PdfSharp.Drawing.Wpf/!info.txt
new file mode 100644
index 0000000..63e9144
--- /dev/null
+++ b/lib/PdfSharp/PdfSharp.Drawing.Wpf/!info.txt
@@ -0,0 +1 @@
+Reserved for PDFsharp 2.0
\ No newline at end of file
diff --git a/lib/PdfSharp/PdfSharp.Drawing/FontHelper.cs b/lib/PdfSharp/PdfSharp.Drawing/FontHelper.cs
index 5f1e08f..3acbfe3 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/FontHelper.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/FontHelper.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -28,6 +28,7 @@
 #endregion
 
 using System;
+using System.Collections.Generic;
 using System.Diagnostics;
 using System.Globalization;
 using System.IO;
@@ -38,12 +39,14 @@ using System.IO;
 //#endif
 #if WPF
 using System.Windows;
+using System.Windows.Controls;
 using System.Windows.Media;
 #endif
 using PdfSharp.Internal;
 using PdfSharp.Pdf;
 using PdfSharp.Drawing.Pdf;
-using PdfSharp.Fonts.TrueType;
+using PdfSharp.Fonts;
+using PdfSharp.Fonts.OpenType;
 using PdfSharp.Pdf.Advanced;
 
 namespace PdfSharp.Drawing
@@ -58,7 +61,7 @@ namespace PdfSharp.Drawing
     GetCellDescent,
     GetEmHeight,
     GetLineSpacing,
-    IsStyleAvailable
+    //IsStyleAvailable
   }
 
   /// <summary>
@@ -66,17 +69,72 @@ namespace PdfSharp.Drawing
   /// </summary>
   static class FontHelper
   {
+    //private const string testFontName = "Times New Roman";
+    //const string testFontName = "Segoe Condensed";
+    //const string testFontName = "Frutiger LT 45 Light";
+
+    //static FontHelper()
+    //{
+    //  FontFamily fontFamily = new FontFamily(testFontName);
+    //  s_typefaces = new List<Typeface>(fontFamily.GetTypefaces());
+    //}
+
+    //private static List<Typeface> s_typefaces;
+
     /// <summary>
     /// Creates a typeface.
     /// </summary>
-    public static Typeface CreateTypeface(XFontFamily family, XFontStyle style)
+    public static Typeface CreateTypeface(FontFamily family, XFontStyle style)
     {
+      // BUG: does not work with fonts that have others than the four default styles
       FontStyle fontStyle = FontStyleFromStyle(style);
       FontWeight fontWeight = FontWeightFromStyle(style);
-      Typeface typeface = new Typeface(family.wpfFamily, fontStyle, fontWeight, FontStretches.Normal);
+      Typeface typeface = new Typeface(family, fontStyle, fontWeight, FontStretches.Normal);
+
+      //List<Typeface> typefaces = new List<Typeface>(fontFamily.GetTypefaces());
+      //typefaces.GetType();
+      //Typeface typeface = typefaces[3];
+
       return typeface;
     }
 
+#if !SILVERLIGHT
+    /// <summary>
+    /// Creates the formatted text.
+    /// </summary>
+    public static FormattedText CreateFormattedText(string text, Typeface typeface, double emSize, Brush brush)
+    {
+      //FontFamily fontFamily = new FontFamily(testFontName);
+      //typeface = new Typeface(fontFamily, FontStyles.Normal, FontWeights.Bold, FontStretches.Condensed);
+      //List<Typeface> typefaces = new List<Typeface>(fontFamily.GetTypefaces());
+      //typefaces.GetType();
+      //typeface = s_typefaces[0];
+
+      // BUG: does not work with fonts that have others than the four default styles
+      FormattedText formattedText = new FormattedText(text, new CultureInfo("en-us"), FlowDirection.LeftToRight, typeface, emSize, brush);
+      //formattedText.SetFontWeight(FontWeights.Bold);
+      //formattedText.SetFontStyle(FontStyles.Oblique);
+      //formattedText.SetFontStretch(FontStretches.Condensed);
+      return formattedText;
+    }
+#endif
+
+#if SILVERLIGHT
+    /// <summary>
+    /// Creates the TextBlock.
+    /// </summary>
+    public static TextBlock CreateTextBlock(string text, Typeface typeface, double emSize, Brush brush)
+    {
+      TextBlock textBlock = new TextBlock();
+      textBlock.FontFamily = new FontFamily("Verdana");
+      textBlock.FontSize = emSize;
+      textBlock.Foreground = brush;
+      textBlock.Text = text;
+
+      return textBlock;
+    }
+#endif
+
     /// <summary>
     /// Simple hack to make it work...
     /// </summary>
@@ -129,29 +187,81 @@ namespace PdfSharp.Drawing
       switch (value)
       {
         case GWV.GetCellAscent:
-          return (int)metrics.Ascent;
+          return metrics.Ascent;
 
         case GWV.GetCellDescent:
-          return (int)Math.Abs(metrics.Descent);
+          return Math.Abs(metrics.Descent);
 
         case GWV.GetEmHeight:
-          return (int)metrics.CapHeight;
+          //return (int)metrics.CapHeight;
+          return metrics.UnitsPerEm;
 
         case GWV.GetLineSpacing:
-          return (int)(metrics.Ascent + Math.Abs(metrics.Descent) + metrics.Leading);
-
-        case GWV.IsStyleAvailable:
-          // TODOWPF: 
-          System.Collections.Generic.List<Typeface> typefaces = new System.Collections.Generic.List<Typeface>(family.wpfFamily.GetTypefaces());
-          foreach (Typeface typeface in typefaces)
-          {
-            Debugger.Break();
-            //typeface.Style = FontStyles.
-          }
-          // TODOWPF
-          return 1;
+          return metrics.Ascent + Math.Abs(metrics.Descent) + metrics.Leading;
+
+        default:
+          throw new InvalidOperationException("Unknown GWV value.");
+        // DELETE
+        //case GWV.IsStyleAvailable:
+        //  style &= XFontStyle.Regular | XFontStyle.Bold | XFontStyle.Italic | XFontStyle.BoldItalic; // same as XFontStyle.BoldItalic
+        //  List<Typeface> s_typefaces = new List<Typeface>(family.wpfFamily.GetTypefaces());
+        //  foreach (Typeface typeface in s_typefaces)
+        //  {
+        //  }
+        //  Debugger.Break();
+        ////typeface.Style = FontStyles.
+      }
+    }
+
+    /// <summary>
+    /// Determines whether the style is available as a glyph type face in the specified font family, i.e. the specified style is not simulated.
+    /// </summary>
+    public static bool IsStyleAvailable(XFontFamily family, XFontStyle style)
+    {
+#if !SILVERLIGHT
+      // TODOWPF: check for correctness
+      FontDescriptor descriptor = FontDescriptorStock.Global.CreateDescriptor(family, style);
+      XFontMetrics metrics = descriptor.FontMetrics;
+
+      style &= XFontStyle.Regular | XFontStyle.Bold | XFontStyle.Italic | XFontStyle.BoldItalic; // same as XFontStyle.BoldItalic
+      List<Typeface> typefaces = new List<Typeface>(family.wpfFamily.GetTypefaces());
+      foreach (Typeface typeface in typefaces)
+      {
+        bool available = false;
+        GlyphTypeface glyphTypeface;
+        if (typeface.TryGetGlyphTypeface(out glyphTypeface))
+        {
+#if DEBUG
+          glyphTypeface.GetType();
+#endif
+          available = true;
+        }
+
+#if DEBUG_ // 
+        int weightClass = typeface.Weight.ToOpenTypeWeight();
+        switch (style)
+        {
+          case XFontStyle.Regular:
+            //if (typeface.TryGetGlyphTypeface(.Style == FontStyles.Normal && typeface.Weight== FontWeights.Normal.)
+            break;
+
+          case XFontStyle.Bold:
+            break;
+
+          case XFontStyle.Italic:
+            break;
+
+          case XFontStyle.BoldItalic:
+            break;
+        }
+#endif
+        if (available)
+          return true;
       }
-      return 0;
+      return false;
+#else
+      return true; // AGHACK
+#endif
     }
   }
 #endif
diff --git a/lib/PdfSharp/PdfSharp.Drawing/GeometryHelper.cs b/lib/PdfSharp/PdfSharp.Drawing/GeometryHelper.cs
index d0cddb8..87b77bc 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/GeometryHelper.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/GeometryHelper.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -59,16 +59,20 @@ namespace PdfSharp.Drawing
     /// </summary>
     public static BezierSegment CreateCurveSegment(XPoint pt0, XPoint pt1, XPoint pt2, XPoint pt3, double tension3)
     {
+#if !SILVERLIGHT
       return new BezierSegment(
         new System.Windows.Point(pt1.X + tension3 * (pt2.X - pt0.X), pt1.Y + tension3 * (pt2.Y - pt0.Y)),
         new System.Windows.Point(pt2.X - tension3 * (pt3.X - pt1.X), pt2.Y - tension3 * (pt3.Y - pt1.Y)),
         new System.Windows.Point(pt2.X, pt2.Y), true);
+#else
+      return new BezierSegment(); // AGHACK
+#endif
     }
 #endif
 
 #if WPF
     /// <summary>
-    /// Creates a path geometry form a polygon.
+    /// Creates a path geometry from a polygon.
     /// </summary>
     public static PathGeometry CreatePolygonGeometry(System.Windows.Point[] points, XFillMode fillMode, bool closed)
     {
@@ -77,7 +81,9 @@ namespace PdfSharp.Drawing
       // For correct drawing the start point of the segment must not be the same as the first point
       for (int idx = 1; idx < count; idx++)
         seg.Points.Add(new System.Windows.Point(points[idx].X, points[idx].Y));
+#if !SILVERLIGHT
       seg.IsStroked = true;
+#endif
       PathFigure fig = new PathFigure();
       fig.StartPoint = new System.Windows.Point(points[0].X, points[0].Y);
       fig.Segments.Add(seg);
@@ -91,7 +97,7 @@ namespace PdfSharp.Drawing
 
 #if WPF
     /// <summary>
-    /// Creates the arc segment from paramters of the GDI+ DrawArc function.
+    /// Creates the arc segment from parameters of the GDI+ DrawArc function.
     /// </summary>
     public static ArcSegment CreateArcSegment(double x, double y, double width, double height, double startAngle,
       double sweepAngle, out System.Windows.Point startPoint)
@@ -167,8 +173,18 @@ namespace PdfSharp.Drawing
       System.Windows.Size size = new System.Windows.Size(δx, δy);
       bool isLargeArc = Math.Abs(sweepAngle) >= 180;
       SweepDirection sweepDirection = sweepAngle > 0 ? SweepDirection.Clockwise : SweepDirection.Counterclockwise;
+#if !SILVERLIGHT
       bool isStroked = true;
       ArcSegment seg = new ArcSegment(destPoint, size, 0, isLargeArc, sweepDirection, isStroked);
+#else
+      ArcSegment seg = new ArcSegment();
+      seg.Point = destPoint;
+      seg.Size = size;
+      seg.RotationAngle = 0;
+      seg.IsLargeArc = isLargeArc;
+      seg.SweepDirection = sweepDirection;
+      // isStroked does not exist in Silverlight 3
+#endif
       return seg;
     }
 #endif
@@ -299,8 +315,8 @@ namespace PdfSharp.Drawing
       //   1 | 0
       //     |
       // If the angles lie in quarter 2 or 3, their values are subtracted by 180 and the
-      // resulting curve is reflected at the center. This algorythm works as expected (simply tried out).
-      // There may be a mathematical more elegant solution...
+      // resulting curve is reflected at the center. This algorithm works as expected (simply tried out).
+      // There may be a mathematically more elegant solution...
       bool reflect = false;
       if (α >= 180 && β >= 180)
       {
@@ -447,5 +463,384 @@ namespace PdfSharp.Drawing
       return BezierCurveFromArc(center.X - δx * factor, center.Y - δy, 2 * δx * factor, 2 * δy,
         α / Calc.Deg2Rad, sweepAngle / Calc.Deg2Rad, pathStart, ref matrix);
     }
+
+
+
+
+
+
+
+    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+#if WPF
+
+    const double FUZZ = 1e-6;           // Relative 0
+
+
+    //+-------------------------------------------------------------------------------------------------
+
+    // 
+    //  Function: GetArcAngle
+    // 
+    //  Synopsis: Get the number of Bezier arcs, and sine & cosine of each 
+    //
+    //  Notes:    This is a private utility used by ArcToBezier 
+    //            We break the arc into pieces so that no piece will span more than 90 degrees.
+    //            The input points are on the unit circle
+    //
+    //------------------------------------------------------------------------------------------------- 
+    public static void
+    GetArcAngle(
+        XPoint startPoint,      // Start point 
+        XPoint endPoint,        // End point
+        bool isLargeArc,     // Choose the larger of the 2 possible arcs if TRUE 
+      //SweepDirection sweepDirection,      // Direction n which to sweep the arc.
+      bool isClockwise,
+        out double cosArcAngle, // Cosine of a the sweep angle of one arc piece
+        out double sinArcAngle, // Sine of a the sweep angle of one arc piece
+        out int pieces)      // Out: The number of pieces 
+    {
+      double angle;
+
+      // The points are on the unit circle, so:
+      cosArcAngle = startPoint.X * endPoint.X + startPoint.Y * endPoint.Y;
+      sinArcAngle = startPoint.X * endPoint.Y - startPoint.Y * endPoint.X;
+
+      if (cosArcAngle >= 0)
+      {
+        if (isLargeArc)
+        {
+          // The angle is between 270 and 360 degrees, so 
+          pieces = 4;
+        }
+        else
+        {
+          // The angle is between 0 and 90 degrees, so
+          pieces = 1;
+          return; // We already have the cosine and sine of the angle
+        }
+      }
+      else
+      {
+        if (isLargeArc)
+        {
+          // The angle is between 180 and 270 degrees, so
+          pieces = 3;
+        }
+        else
+        {
+          // The angle is between 90 and 180 degrees, so
+          pieces = 2;
+        }
+      }
+
+      // We have to chop the arc into the computed number of pieces.  For cPieces=2 and 4 we could 
+      // have uses the half-angle trig formulas, but for pieces=3 it requires solving a cubic
+      // equation; the performance difference is not worth the extra code, so we'll get the angle, 
+      // divide it, and get its sine and cosine. 
+
+      Debug.Assert(pieces > 0);
+      angle = Math.Atan2(sinArcAngle, cosArcAngle);
+
+      if (isClockwise)
+      {
+        if (angle < 0)
+          angle += Math.PI * 2;
+      }
+      else
+      {
+        if (angle > 0)
+          angle -= Math.PI * 2;
+      }
+
+      angle /= pieces;
+      cosArcAngle = Math.Cos(angle);
+      sinArcAngle = Math.Sin(angle);
+    }
+
+    /******************************************************************************\
+    * 
+    * Function Description: 
+    *
+    * Get the distance from a circular arc's endpoints to the control points of the 
+    * Bezier arc that approximates it, as a fraction of the arc's radius.
+    *
+    * Since the result is relative to the arc's radius, it depends strictly on the
+    * arc's angle. The arc is assumed to be of 90 degrees of less, so the angle is 
+    * determined by the cosine of that angle, which is derived from rDot = the dot
+    * product of two radius vectors.  We need the Bezier curve that agrees with 
+    * the arc's points and tangents at the ends and midpoint.  Here we compute the 
+    * distance from the curve's endpoints to its control points.
+    * 
+    * Since we are looking for the relative distance, we can work on the unit
+    * circle. Place the center of the circle at the origin, and put the X axis as
+    * the bisector between the 2 vectors.  Let a be the angle between the vectors.
+    * Then the X coordinates of the 1st & last points are cos(a/2).  Let x be the X 
+    * coordinate of the 2nd & 3rd points.  At t=1/2 we have a point at (1,0).
+    * But the terms of the polynomial there are all equal: 
+    * 
+    *           (1-t)^3 = t*(1-t)^2 = 2^2*(1-t) = t^3 = 1/8,
+    * 
+    * so from the Bezier formula there we have:
+    *
+    *           1 = (1/8) * (cos(a/2) + 3x + 3x + cos(a/2)),
+    * hence 
+    *           x = (1 - cos(a/2)) / 3
+    * 
+    * The X difference between that and the 1st point is: 
+    *
+    *           DX = x - cos(a/2) = 4(1 - cos(a/2)) / 3. 
+    *
+    * But DX = distance / sin(a/2), hence the distance is
+    *
+    *           dist = (4/3)*(1 - cos(a/2)) / sin(a/2). 
+    *
+    * Created:  5/29/2001 [....] 
+    * 
+    /*****************************************************************************/
+    public static double
+    GetBezierDistance(  // Return the distance as a fraction of the radius
+        double dot,    // In: The dot product of the two radius vectors
+        double radius) // In: The radius of the arc's circle (optional=1)
+    {
+      double radSquared = radius * radius;  // Squared radius
+
+      Debug.Assert(dot >= -radSquared * .1);  // angle < 90 degrees 
+      Debug.Assert(dot <= radSquared * 1.1);  // as dot product of 2 radius vectors
+
+      double dist = 0;   // Acceptable fallback value
+
+      /* Rather than the angle a, we are given rDot = R^2 * cos(a), so we
+          multiply top and bottom by R: 
+
+                          dist = (4/3)*(R - Rcos(a/2)) / Rsin(a/2) 
+ 
+          and use some trig:
+                              __________ 
+                  cos(a/2) = \/1 + cos(a) / 2
+                                  ________________         __________
+                  R*cos(a/2) = \/R^2 + R^2 cos(a) / 2 = \/R^2 + rDot / 2 */
+
+      double cos = (radSquared + dot) / 2;   // =(R*cos(a))^2
+      if (cos < 0)
+        return dist;
+      //                 __________________
+      //  R*sin(a/2) = \/R^2 - R^2 cos(a/2)
+
+      double sin = radSquared - cos;         // =(R*sin(a))^2 
+      if (sin <= 0)
+        return dist;
+
+      sin = Math.Sqrt(sin); //   = R*cos(a) 
+      cos = Math.Sqrt(cos); //   = R*sin(a)
+
+      dist = 4 * (radius - cos) / 3;
+      if (dist <= sin * FUZZ)
+        dist = 0;
+      else
+        dist = 4 * (radius - cos) / sin / 3;
+
+      return dist;
+    }
+
+    //+------------------------------------------------------------------------------------------------- 
+    //
+    //  Function: ArcToBezier 
+    //
+    //  Synopsis: Compute the Bezier approximation of an arc
+    //
+    //  Notes:    This utilitycomputes the Bezier approximation for an elliptical arc as it is defined 
+    //            in the SVG arc spec. The ellipse from which the arc is carved is axis-aligned in its
+    //            own coordinates, and defined there by its x and y radii. The rotation angle defines 
+    //            how the ellipse's axes are rotated relative to our x axis. The start and end points 
+    //            define one of 4 possible arcs; the sweep and large-arc flags determine which one of
+    //            these arcs will be chosen. See SVG spec for details. 
+    //
+    //            Returning pieces = 0 indicates a line instead of an arc
+    //                      pieces = -1 indicates that the arc degenerates to a point
+    // 
+    //--------------------------------------------------------------------------------------------------
+    public static PointCollection ArcToBezier(double xStart, double yStart, double xRadius, double yRadius, double rotationAngle,
+      bool isLargeArc, bool isClockwise, double xEnd, double yEnd, out int pieces)
+    {
+      double cosArcAngle, sinArcAngle, xCenter, yCenter, r, bezDist;
+      XVector vecToBez1, vecToBez2;
+      XMatrix matToEllipse;
+
+      double fuzz2 = FUZZ * FUZZ;
+      bool isZeroCenter = false;
+
+      pieces = -1;
+
+      // In the following, the line segment between between the arc's start and
+      // end points is referred to as "the chord".
+
+      // Transform 1: Shift the origin to the chord's midpoint 
+      double x = (xEnd - xStart) / 2;
+      double y = (yEnd - yStart) / 2;
+
+      double halfChord2 = x * x + y * y;     // (half chord length)^2
+
+      // Degenerate case: single point
+      if (halfChord2 < fuzz2)
+      {
+        // The chord degeneartes to a point, the arc will be ignored 
+        return null;
+      }
+
+      // Degenerate case: straight line
+      if (!AcceptRadius(halfChord2, fuzz2, ref xRadius) || !AcceptRadius(halfChord2, fuzz2, ref yRadius))
+      {
+        // We have a zero radius, add a straight line segment instead of an arc
+        pieces = 0;
+        return null;
+      }
+
+      if (xRadius == 0 || yRadius == 0)
+      {
+        // We have a zero radius, add a straight line segment instead of an arc
+        pieces = 0;
+        return null;
+      }
+
+      // Transform 2: Rotate to the ellipse's coordinate system
+      rotationAngle = -rotationAngle * Calc.Deg2Rad;
+
+      double cos = Math.Cos(rotationAngle);
+      double sin = Math.Sin(rotationAngle);
+
+      r = x * cos - y * sin;
+      y = x * sin + y * cos;
+      x = r;
+
+      // Transform 3: Scale so that the ellipse will become a unit circle 
+      x /= xRadius;
+      y /= yRadius;
+
+      // We get to the center of that circle along a verctor perpendicular to the chord 
+      // from the origin, which is the chord's midpoint. By Pythagoras, the length of that
+      // vector is sqrt(1 - (half chord)^2). 
+
+      halfChord2 = x * x + y * y;   // now in the circle coordinates
+
+      if (halfChord2 > 1)
+      {
+        // The chord is longer than the circle's diameter; we scale the radii uniformly so
+        // that the chord will be a diameter. The center will then be the chord's midpoint, 
+        // which is now the origin.
+        r = Math.Sqrt(halfChord2);
+        xRadius *= r;
+        yRadius *= r;
+        xCenter = yCenter = 0;
+        isZeroCenter = true;
+
+        // Adjust the unit-circle coordinates x and y
+        x /= r;
+        y /= r;
+      }
+      else
+      {
+        // The length of (-y,x) or (x,-y) is sqrt(rHalfChord2), and we want a vector 
+        // of length sqrt(1 - rHalfChord2), so we'll multiply it by:
+        r = Math.Sqrt((1 - halfChord2) / halfChord2);
+        //if (isLargeArc != (eSweepDirection == SweepDirection.Clockwise))
+        if (isLargeArc != isClockwise)
+        // Going to the center from the origin=chord-midpoint 
+        {
+          // in the direction of (-y, x) 
+          xCenter = -r * y;
+          yCenter = r * x;
+        }
+        else
+        {
+          // in the direction of (y, -x)
+          xCenter = r * y;
+          yCenter = -r * x;
+        }
+      }
+
+      // Transformation 4: shift the origin to the center of the circle, which then becomes 
+      // the unit circle. Since the chord's midpoint is the origin, the start point is (-x, -y)
+      // and the endpoint is (x, y).
+      XPoint ptStart = new XPoint(-x - xCenter, -y - yCenter);
+      XPoint ptEnd = new XPoint(x - xCenter, y - yCenter);
+
+      // Set up the matrix that will take us back to our coordinate system.  This matrix is 
+      // the inverse of the combination of transformation 1 thru 4. 
+      matToEllipse = new XMatrix(cos * xRadius, -sin * xRadius,
+                                sin * yRadius, cos * yRadius,
+                                (xEnd + xStart) / 2, (yEnd + yStart) / 2);
+
+      if (!isZeroCenter)
+      {
+        // Prepend the translation that will take the origin to the circle's center
+        matToEllipse.OffsetX += (matToEllipse.M11 * xCenter + matToEllipse.M21 * yCenter);
+        matToEllipse.OffsetY += (matToEllipse.M12 * xCenter + matToEllipse.M22 * yCenter);
+      }
+
+      // Get the sine & cosine of the angle that will generate the arc pieces
+      GetArcAngle(ptStart, ptEnd, isLargeArc, isClockwise, out cosArcAngle, out sinArcAngle, out pieces);
+
+      // Get the vector to the first Bezier control point 
+      bezDist = GetBezierDistance(cosArcAngle, 1);
+
+      //if (eSweepDirection == SweepDirection.Counterclockwise)
+      if (!isClockwise)
+        bezDist = -bezDist;
+
+      vecToBez1 = new XVector(-bezDist * ptStart.Y, bezDist * ptStart.X);
+
+      PointCollection result = new PointCollection();
+
+      // Add the arc pieces, except for the last 
+      for (int idx = 1; idx < pieces; idx++)
+      {
+        // Get the arc piece's endpoint
+        XPoint ptPieceEnd = new XPoint(ptStart.X * cosArcAngle - ptStart.Y * sinArcAngle, ptStart.X * sinArcAngle + ptStart.Y * cosArcAngle);
+        vecToBez2 = new XVector(-bezDist * ptPieceEnd.Y, bezDist * ptPieceEnd.X);
+
+        result.Add(matToEllipse.Transform(ptStart + vecToBez1));
+        result.Add(matToEllipse.Transform(ptPieceEnd - vecToBez2));
+        result.Add(matToEllipse.Transform(ptPieceEnd));
+
+        // Move on to the next arc
+        ptStart = ptPieceEnd;
+        vecToBez1 = vecToBez2;
+      }
+
+      // Last arc - we know the endpoint 
+      vecToBez2 = new XVector(-bezDist * ptEnd.Y, bezDist * ptEnd.X);
+
+      result.Add(matToEllipse.Transform(ptStart + vecToBez1));
+      result.Add(matToEllipse.Transform(ptEnd - vecToBez2));
+      result.Add(new XPoint(xEnd, yEnd));
+
+      return result;
+    }
+
+    /// <summary>
+    /// Gets a value indicating whether radius large enough compared to the chord length.
+    /// </summary>
+    /// <param name="halfChord2">(1/2 chord length)squared </param>
+    /// <param name="fuzz2">Squared fuzz.</param>
+    /// <param name="radius">The radius to accept (or not).</param>
+    public static bool AcceptRadius(double halfChord2, double fuzz2, ref double radius)
+    {
+      Debug.Assert(halfChord2 >= fuzz2);   // Otherewise we have no guarantee that the radius is not 0, and we need to divide by the radius
+      bool accept = radius * radius > halfChord2 * fuzz2;
+      if (accept)
+      {
+        if (radius < 0)
+          radius = 0;
+      }
+      return accept;
+    }
+#endif
   }
 }
\ No newline at end of file
diff --git a/lib/PdfSharp/PdfSharp.Drawing/GraphicsStateStack.cs b/lib/PdfSharp/PdfSharp.Drawing/GraphicsStateStack.cs
index c4f9744..95e72b0 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/GraphicsStateStack.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/GraphicsStateStack.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Drawing/IXGraphicsRenderer.cs b/lib/PdfSharp/PdfSharp.Drawing/IXGraphicsRenderer.cs
index 1998098..2f6f5d8 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/IXGraphicsRenderer.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/IXGraphicsRenderer.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Drawing/ImageHelper.cs b/lib/PdfSharp/PdfSharp.Drawing/ImageHelper.cs
index 04bca7f..cf1612b 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/ImageHelper.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/ImageHelper.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -50,7 +50,7 @@ using PdfSharp.Pdf.Advanced;
 namespace PdfSharp.Drawing
 {
   /// <summary>
-  /// Helper class for images.
+  /// Helper class for processing image files.
   /// </summary>
   static class ImageHelper
   {
diff --git a/lib/PdfSharp/PdfSharp.Drawing/InternalGraphicsState.cs b/lib/PdfSharp/PdfSharp.Drawing/InternalGraphicsState.cs
index 62561b4..086b320 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/InternalGraphicsState.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/InternalGraphicsState.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -41,7 +41,7 @@ namespace PdfSharp.Drawing
   // In GDI+ the functions Save/Restore, BeginContainer/EndContainer, Transform, SetClip and ResetClip
   // can be combined in any order. E.g. you can set a clip region, save the graphics state, empty the
   // clip region and draw without clipping. Then you can restore to the previous clip region. With PDF
-  // this behaviour is hard to implement. To solve this problem I first an automaton that keeps track
+  // this behavior is hard to implement. To solve this problem I first an automaton that keeps track
   // of all clipping paths and the current transformation when the clip path was set. The automation
   // manages a PDF graphics state stack to calculate the desired bahaviour. It also takes into consideration
   // not to multiply with inverse matrixes when the user sets a new transformation matrix.
@@ -118,7 +118,7 @@ namespace PdfSharp.Drawing
       get { return this.transform; }
       set { this.transform = value; }
     }
-    XMatrix transform = XMatrix.Identity;
+    XMatrix transform = new XMatrix();  //XMatrix.Identity;
 
     public void Pushed()
     {
@@ -178,6 +178,5 @@ namespace PdfSharp.Drawing
     // /// The GDI+ GraphicsContainer if contructed from XGraphicsContainer.
     // /// </summary>
     // public GraphicsContainer GdiGraphicsContainer;
-
   }
 }
diff --git a/lib/PdfSharp/PdfSharp.Drawing/PdfFontOptions.cs b/lib/PdfSharp/PdfSharp.Drawing/PdfFontOptions.cs
index 3aac856..9654ed5 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/PdfFontOptions.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/PdfFontOptions.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -39,7 +39,7 @@ using System.Drawing.Drawing2D;
 using System.Windows.Media;
 #endif
 using PdfSharp.Internal;
-using PdfSharp.Fonts.TrueType;
+using PdfSharp.Fonts.OpenType;
 using PdfSharp.Pdf;
 using PdfSharp.Pdf.Advanced;
 
@@ -154,7 +154,7 @@ namespace PdfSharp.Drawing
     { }
 
     /// <summary>
-    /// Gets a value indicating whether the gets embeded in the PDF file.
+    /// Gets a value indicating whether the gets embedded in the PDF file.
     /// </summary>
     [Obsolete("Use FontEmbedding")]
     public bool Embed
@@ -199,7 +199,7 @@ namespace PdfSharp.Drawing
     PdfFontEncoding fontEncoding;
 
     /// <summary>
-    /// Not yet implemted.
+    /// Not yet implemented.
     /// </summary>
     [Obsolete("Not yet implemented")]
     public string BaseFont
@@ -210,7 +210,7 @@ namespace PdfSharp.Drawing
     //string baseFont = "";
 
     /// <summary>
-    /// Not yet implemted.
+    /// Not yet implemented.
     /// </summary>
     [Obsolete("Not yet implemented")]
     public string FontFile
diff --git a/lib/PdfSharp/PdfSharp.Drawing/XBrush.cs b/lib/PdfSharp/PdfSharp.Drawing/XBrush.cs
index 64a3e78..f33757d 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/XBrush.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/XBrush.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Drawing/XBrushes.cs b/lib/PdfSharp/PdfSharp.Drawing/XBrushes.cs
index 7382d98..61fb6fd 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/XBrushes.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/XBrushes.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -34,10 +34,8 @@ namespace PdfSharp.Drawing
   /// <summary>
   /// Brushes for all the pre-defined colors.
   /// </summary>
-  public sealed class XBrushes
+  public static class XBrushes
   {
-    XBrushes() { }
-
     /// <summary>Gets a pre-defined XBrush object.</summary>
     public static XSolidBrush AliceBlue
     {
diff --git a/lib/PdfSharp/PdfSharp.Drawing/XColor.cs b/lib/PdfSharp/PdfSharp.Drawing/XColor.cs
index dd48ac9..477d33c 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/XColor.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/XColor.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -172,7 +172,7 @@ namespace PdfSharp.Drawing
       CheckByte(red, "red");
       CheckByte(green, "green");
       CheckByte(blue, "blue");
-      return new XColor((byte)255, (byte)red, (byte)green, (byte)blue);
+      return new XColor(255, (byte)red, (byte)green, (byte)blue);
     }
 
     /// <summary>
@@ -514,6 +514,7 @@ namespace PdfSharp.Drawing
     /// </summary>
     void RgbChanged()
     {
+      // ReSharper disable LocalVariableHidesMember
       this.cs = XColorSpace.Rgb;
       int c = 255 - this.r;
       int m = 255 - this.g;
@@ -529,6 +530,7 @@ namespace PdfSharp.Drawing
         this.y = (y - k) / black;
       }
       this.k = this.gs = k / 255f;
+      // ReSharper restore LocalVariableHidesMember
     }
 
     ///<summary>
@@ -612,7 +614,7 @@ namespace PdfSharp.Drawing
     /// </summary>
     internal uint Rgb
     {
-      get { return ((uint)this.r << 16) | ((uint)this.g << 8) | (uint)this.b; }
+      get { return ((uint)this.r << 16) | ((uint)this.g << 8) | this.b; }
     }
 
     /// <summary>
@@ -620,7 +622,7 @@ namespace PdfSharp.Drawing
     /// </summary>
     internal uint Argb
     {
-      get { return ((uint)(this.a * 255) << 24) | ((uint)this.r << 16) | ((uint)this.g << 8) | (uint)this.b; }
+      get { return ((uint)(this.a * 255) << 24) | ((uint)this.r << 16) | ((uint)this.g << 8) | this.b; }
     }
 
     /// <summary>
diff --git a/lib/PdfSharp/PdfSharp.Drawing/XColorResourceManager.cs b/lib/PdfSharp/PdfSharp.Drawing/XColorResourceManager.cs
index 00404e3..d035b61 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/XColorResourceManager.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/XColorResourceManager.cs
@@ -1,9 +1,9 @@
-#region PDFsharp - A .NET library for processing PDF
+#region PDFsharp - A .NET library for processing PDF
 //
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -42,7 +42,7 @@ using PdfSharp.Internal;
 namespace PdfSharp.Drawing
 {
   /// <summary>
-  /// Manages the localizaion of the color class.
+  /// Manages the localization of the color class.
   /// </summary>
   public class XColorResourceManager
   {
@@ -177,21 +177,21 @@ namespace PdfSharp.Drawing
       new ColorResourceInfo(XKnownColor.Silver, XColors.Silver, 0xFFC0C0C0, "Silver", "Silber"),
       //new ColorResourceInfo(XKnownColor.Gainsboro, XColors.Gainsboro, 0xFFDCDCDC, "Gainsboro", "Gainsboro"),
       new ColorResourceInfo(XKnownColor.Gainsboro, XColors.Gainsboro, 0xFFDCDCDC, "Gainsboro", "Helles Blaugrau"),
-      //new ColorResourceInfo(XKnownColor.WhiteSmoke, XColors.WhiteSmoke, 0xFFF5F5F5, "Whitesmoke", "Rauchiges Weiß"),
-      new ColorResourceInfo(XKnownColor.WhiteSmoke, XColors.WhiteSmoke, 0xFFF5F5F5, "Whitesmoke", "Rauchweiß"),
-      //new ColorResourceInfo(XKnownColor.GhostWhite, XColors.GhostWhite, 0xFFF8F8FF, "Ghostwhite", "Geisterweiß"),
-      new ColorResourceInfo(XKnownColor.GhostWhite, XColors.GhostWhite, 0xFFF8F8FF, "Ghostwhite", "Schattenweiß"),
-      new ColorResourceInfo(XKnownColor.White, XColors.White, 0xFFFFFFFF, "White", "Weiß"),
-      new ColorResourceInfo(XKnownColor.Snow, XColors.Snow, 0xFFFFFAFA, "Snow", "Schneeweiß"),
+      //new ColorResourceInfo(XKnownColor.WhiteSmoke, XColors.WhiteSmoke, 0xFFF5F5F5, "Whitesmoke", "Rauchiges WeiÃ?"),
+      new ColorResourceInfo(XKnownColor.WhiteSmoke, XColors.WhiteSmoke, 0xFFF5F5F5, "Whitesmoke", "RauchweiÃ?"),
+      //new ColorResourceInfo(XKnownColor.GhostWhite, XColors.GhostWhite, 0xFFF8F8FF, "Ghostwhite", "GeisterweiÃ?"),
+      new ColorResourceInfo(XKnownColor.GhostWhite, XColors.GhostWhite, 0xFFF8F8FF, "Ghostwhite", "SchattenweiÃ?"),
+      new ColorResourceInfo(XKnownColor.White, XColors.White, 0xFFFFFFFF, "White", "WeiÃ?"),
+      new ColorResourceInfo(XKnownColor.Snow, XColors.Snow, 0xFFFFFAFA, "Snow", "SchneeweiÃ?"),
       new ColorResourceInfo(XKnownColor.Ivory, XColors.Ivory, 0xFFFFFFF0, "Ivory", "Elfenbein"),
-      new ColorResourceInfo(XKnownColor.FloralWhite, XColors.FloralWhite, 0xFFFFFAF0, "Floralwhite", "Blütenweiß"),
+      new ColorResourceInfo(XKnownColor.FloralWhite, XColors.FloralWhite, 0xFFFFFAF0, "Floralwhite", "Blütenwei�"),
       new ColorResourceInfo(XKnownColor.SeaShell, XColors.SeaShell, 0xFFFFF5EE, "Seashell", "Muschel"),
       //new ColorResourceInfo(XKnownColor.OldLace, XColors.OldLace, 0xFFFDF5E6, "Oldlace", "Altgold"),
-      new ColorResourceInfo(XKnownColor.OldLace, XColors.OldLace, 0xFFFDF5E6, "Oldlace", "Altweiß"),
+      new ColorResourceInfo(XKnownColor.OldLace, XColors.OldLace, 0xFFFDF5E6, "Oldlace", "AltweiÃ?"),
       //new ColorResourceInfo(XKnownColor.Linen, XColors.Linen, 0xFFFAF0E6, "Linen", "Leinenfarbe"),
       new ColorResourceInfo(XKnownColor.Linen, XColors.Linen, 0xFFFAF0E6, "Linen", "Leinen"),
-      new ColorResourceInfo(XKnownColor.AntiqueWhite, XColors.AntiqueWhite, 0xFFFAEBD7, "Antiquewhite", "Antikes Weiß"),
-      new ColorResourceInfo(XKnownColor.BlanchedAlmond, XColors.BlanchedAlmond, 0xFFFFEBCD, "Blanchedalmond", "Mandelweiß"),
+      new ColorResourceInfo(XKnownColor.AntiqueWhite, XColors.AntiqueWhite, 0xFFFAEBD7, "Antiquewhite", "Antikes WeiÃ?"),
+      new ColorResourceInfo(XKnownColor.BlanchedAlmond, XColors.BlanchedAlmond, 0xFFFFEBCD, "Blanchedalmond", "MandelweiÃ?"),
       //new ColorResourceInfo(XKnownColor.PapayaWhip, XColors.PapayaWhip, 0xFFFFEFD5, "Papayawhip", "Cremiges Papaya"),
       new ColorResourceInfo(XKnownColor.PapayaWhip, XColors.PapayaWhip, 0xFFFFEFD5, "Papayawhip", "Papayacreme"),
       new ColorResourceInfo(XKnownColor.Beige, XColors.Beige, 0xFFF5F5DC, "Beige", "Beige"),
@@ -218,7 +218,7 @@ namespace PdfSharp.Drawing
       new ColorResourceInfo(XKnownColor.Brown, XColors.Brown, 0xFFA52A2A, "Brown", "Braun"),
       new ColorResourceInfo(XKnownColor.DarkRed, XColors.DarkRed, 0xFF8B0000, "Darkred", "Dunkelrot"),
       new ColorResourceInfo(XKnownColor.Maroon, XColors.Maroon, 0xFF800000, "Maroon", "Kastanienbraun"),
-      new ColorResourceInfo(XKnownColor.PaleTurquoise, XColors.PaleTurquoise, 0xFFAFEEEE, "Paleturquoise", "Blasses Türkis"),
+      new ColorResourceInfo(XKnownColor.PaleTurquoise, XColors.PaleTurquoise, 0xFFAFEEEE, "Paleturquoise", "Blasses Türkis"),
       //new ColorResourceInfo(XKnownColor.Firebrick, XColors.Firebrick, 0xFFB22222, "Firebrick", "Ziegelfarbe"),
       new ColorResourceInfo(XKnownColor.Firebrick, XColors.Firebrick, 0xFFB22222, "Firebrick", "Ziegel"),
       new ColorResourceInfo(XKnownColor.IndianRed, XColors.IndianRed, 0xFFCD5C5C, "Indianred", "Indischrot"),
@@ -240,11 +240,11 @@ namespace PdfSharp.Drawing
       new ColorResourceInfo(XKnownColor.RosyBrown, XColors.RosyBrown, 0xFFBC8F8F, "Rosybrown", "Rotbraun"),
       new ColorResourceInfo(XKnownColor.Tan, XColors.Tan, 0xFFD2B48C, "Tan", "Gelbbraun"),
       //new ColorResourceInfo(XKnownColor.BurlyWood, XColors.BurlyWood, 0xFFDEB887, "Burlywood", "Grobes Braun"),
-      new ColorResourceInfo(XKnownColor.BurlyWood, XColors.BurlyWood, 0xFFDEB887, "Burlywood", "Kräftiges Sandbraun"),
+      new ColorResourceInfo(XKnownColor.BurlyWood, XColors.BurlyWood, 0xFFDEB887, "Burlywood", "Kräftiges Sandbraun"),
       new ColorResourceInfo(XKnownColor.Wheat, XColors.Wheat, 0xFFF5DEB3, "Wheat", "Weizen"),
       new ColorResourceInfo(XKnownColor.PeachPuff, XColors.PeachPuff, 0xFFFFDAB9, "Peachpuff", "Pfirsich"),
-      //new ColorResourceInfo(XKnownColor.NavajoWhite, XColors.NavajoWhite, 0xFFFFDEAD, "Navajowhite", "Navajoweiß"),
-      new ColorResourceInfo(XKnownColor.NavajoWhite, XColors.NavajoWhite, 0xFFFFDEAD, "Navajowhite", "Orangeweiß"),
+      //new ColorResourceInfo(XKnownColor.NavajoWhite, XColors.NavajoWhite, 0xFFFFDEAD, "Navajowhite", "NavajoweiÃ?"),
+      new ColorResourceInfo(XKnownColor.NavajoWhite, XColors.NavajoWhite, 0xFFFFDEAD, "Navajowhite", "OrangeweiÃ?"),
       //new ColorResourceInfo(XKnownColor.Bisque, XColors.Bisque, 0xFFFFE4C4, "Bisque", "Tomatencreme"),
       new ColorResourceInfo(XKnownColor.Bisque, XColors.Bisque, 0xFFFFE4C4, "Bisque", "Blasses Rotbraun"),
       //new ColorResourceInfo(XKnownColor.Moccasin, XColors.Moccasin, 0xFFFFE4B5, "Moccasin", "Moccasin"),
@@ -286,7 +286,7 @@ namespace PdfSharp.Drawing
       new ColorResourceInfo(XKnownColor.LightGray, XColors.LightGray, 0xFFD3D3D3, "Lightgray", "Hellgrau"),
       new ColorResourceInfo(XKnownColor.MediumBlue, XColors.MediumBlue, 0xFF0000CD, "Mediumblue", "Mittelblau"),
       new ColorResourceInfo(XKnownColor.Blue, XColors.Blue, 0xFF0000FF, "Blue", "Blau"),
-      new ColorResourceInfo(XKnownColor.RoyalBlue, XColors.RoyalBlue, 0xFF4169E1, "Royalblue", "Königsblau"),
+      new ColorResourceInfo(XKnownColor.RoyalBlue, XColors.RoyalBlue, 0xFF4169E1, "Royalblue", "Königsblau"),
       new ColorResourceInfo(XKnownColor.SteelBlue, XColors.SteelBlue, 0xFF4682B4, "Steelblue", "Stahlblau"),
       new ColorResourceInfo(XKnownColor.CornflowerBlue, XColors.CornflowerBlue, 0xFF6495ED, "Cornflowerblue", "Kornblumenblau"),
       new ColorResourceInfo(XKnownColor.DodgerBlue, XColors.DodgerBlue, 0xFF1E90FF, "Dodgerblue", "Dodger-Blau"),
@@ -295,46 +295,46 @@ namespace PdfSharp.Drawing
       new ColorResourceInfo(XKnownColor.SkyBlue, XColors.SkyBlue, 0xFF87CEEB, "Skyblue", "Himmelblau"),
       new ColorResourceInfo(XKnownColor.LightBlue, XColors.LightBlue, 0xFFADD8E6, "Lightblue", "Hellblau"),
       //// XKnownColor.Aqua removed because the same as XKnownColor.Cyan
-      ////new ColorResourceInfo(XKnownColor.Aqua, XColors.Aqua, 0xFF00FFFF, "Aqua", "Blaugrün"),
+      ////new ColorResourceInfo(XKnownColor.Aqua, XColors.Aqua, 0xFF00FFFF, "Aqua", "Blaugrün"),
       new ColorResourceInfo(XKnownColor.Cyan, XColors.Cyan, 0xFF00FFFF, "Cyan", "Zyan"),
       new ColorResourceInfo(XKnownColor.PowderBlue, XColors.PowderBlue, 0xFFB0E0E6, "Powderblue", "Taubenblau"),
       new ColorResourceInfo(XKnownColor.LightCyan, XColors.LightCyan, 0xFFE0FFFF, "Lightcyan", "Helles Cyanblau"),
       new ColorResourceInfo(XKnownColor.AliceBlue, XColors.AliceBlue, 0xFFA0CE00, "Aliceblue", "Aliceblau"),
       new ColorResourceInfo(XKnownColor.Azure, XColors.Azure, 0xFFF0FFFF, "Azure", "Himmelblau"),
       //new ColorResourceInfo(XKnownColor.MintCream, XColors.MintCream, 0xFFF5FFFA, "Mintcream", "Cremige Pfefferminzfarbe"),
-      new ColorResourceInfo(XKnownColor.MintCream, XColors.MintCream, 0xFFF5FFFA, "Mintcream", "Helles Pfefferminzgrün"),
+      new ColorResourceInfo(XKnownColor.MintCream, XColors.MintCream, 0xFFF5FFFA, "Mintcream", "Helles Pfefferminzgrün"),
       new ColorResourceInfo(XKnownColor.Honeydew, XColors.Honeydew, 0xFFF0FFF0, "Honeydew", "Honigmelone"),
       new ColorResourceInfo(XKnownColor.Aquamarine, XColors.Aquamarine, 0xFF7FFFD4, "Aquamarine", "Aquamarinblau"),
-      new ColorResourceInfo(XKnownColor.Turquoise, XColors.Turquoise, 0xFF40E0D0, "Turquoise", "Türkis"),
-      new ColorResourceInfo(XKnownColor.MediumTurquoise, XColors.MediumTurquoise, 0xFF48D1CC, "Mediumturqoise", "Mittleres Türkis"),
-      new ColorResourceInfo(XKnownColor.DarkTurquoise, XColors.DarkTurquoise, 0xFF00CED1, "Darkturquoise", "Dunkles Türkis"),
+      new ColorResourceInfo(XKnownColor.Turquoise, XColors.Turquoise, 0xFF40E0D0, "Turquoise", "Türkis"),
+      new ColorResourceInfo(XKnownColor.MediumTurquoise, XColors.MediumTurquoise, 0xFF48D1CC, "Mediumturqoise", "Mittleres Türkis"),
+      new ColorResourceInfo(XKnownColor.DarkTurquoise, XColors.DarkTurquoise, 0xFF00CED1, "Darkturquoise", "Dunkles Türkis"),
       new ColorResourceInfo(XKnownColor.MediumAquamarine, XColors.MediumAquamarine, 0xFF66CDAA, "Mediumaquamarine", "Mittleres Aquamarinblau"),
-      new ColorResourceInfo(XKnownColor.LightSeaGreen, XColors.LightSeaGreen, 0xFF20B2AA, "Lightseagreen", "Helles Seegrün"),
+      new ColorResourceInfo(XKnownColor.LightSeaGreen, XColors.LightSeaGreen, 0xFF20B2AA, "Lightseagreen", "Helles Seegrün"),
       new ColorResourceInfo(XKnownColor.DarkCyan, XColors.DarkCyan, 0xFF008B8B, "Darkcyan", "Dunkles Zyanblau"),
       //new ColorResourceInfo(XKnownColor.Teal, XColors.Teal, 0xFF008080, "Teal", "Entenbraun"),
       new ColorResourceInfo(XKnownColor.Teal, XColors.Teal, 0xFF008080, "Teal", "Entenblau"),
       new ColorResourceInfo(XKnownColor.CadetBlue, XColors.CadetBlue, 0xFF5F9EA0, "Cadetblue", "Kadettblau"),
-      new ColorResourceInfo(XKnownColor.MediumSeaGreen, XColors.MediumSeaGreen, 0xFF3CB371, "Mediumseagreen", "Mittleres Seegrün"),
-      new ColorResourceInfo(XKnownColor.DarkSeaGreen, XColors.DarkSeaGreen, 0xFF8FBC8F, "Darkseagreen", "Dunkles Seegrün"),
-      new ColorResourceInfo(XKnownColor.LightGreen, XColors.LightGreen, 0xFF90EE90, "Lightgreen", "Hellgrün"),
-      new ColorResourceInfo(XKnownColor.PaleGreen, XColors.PaleGreen, 0xFF98FB98, "Palegreen", "Blassgrün"),
-      new ColorResourceInfo(XKnownColor.MediumSpringGreen, XColors.MediumSpringGreen, 0xFF00FA9A, "Mediumspringgreen", "Mittleres Frühlingsgrün"),
-      new ColorResourceInfo(XKnownColor.SpringGreen, XColors.SpringGreen, 0xFF00FF7F, "Springgreen", "Frühlingsgrün"),
-      new ColorResourceInfo(XKnownColor.Lime, XColors.Lime, 0xFF00FF00, "Lime", "Zitronengrün"),
-      new ColorResourceInfo(XKnownColor.LimeGreen, XColors.LimeGreen, 0xFF32CD32, "Limegreen", "Gelbgrün"),
-      new ColorResourceInfo(XKnownColor.SeaGreen, XColors.SeaGreen, 0xFF2E8B57, "Seagreen", "Seegrün"),
-      new ColorResourceInfo(XKnownColor.ForestGreen, XColors.ForestGreen, 0xFF228B22, "Forestgreen", "Waldgrün"),
-      new ColorResourceInfo(XKnownColor.Green, XColors.Green, 0xFF008000, "Green", "Grün"),
-      new ColorResourceInfo(XKnownColor.LawnGreen, XColors.LawnGreen, 0xFF008000, "LawnGreen", "Grasgrün"),
-      new ColorResourceInfo(XKnownColor.DarkGreen, XColors.DarkGreen, 0xFF006400, "Darkgreen", "Dunkelgrün"),
+      new ColorResourceInfo(XKnownColor.MediumSeaGreen, XColors.MediumSeaGreen, 0xFF3CB371, "Mediumseagreen", "Mittleres Seegrün"),
+      new ColorResourceInfo(XKnownColor.DarkSeaGreen, XColors.DarkSeaGreen, 0xFF8FBC8F, "Darkseagreen", "Dunkles Seegrün"),
+      new ColorResourceInfo(XKnownColor.LightGreen, XColors.LightGreen, 0xFF90EE90, "Lightgreen", "Hellgrün"),
+      new ColorResourceInfo(XKnownColor.PaleGreen, XColors.PaleGreen, 0xFF98FB98, "Palegreen", "Blassgrün"),
+      new ColorResourceInfo(XKnownColor.MediumSpringGreen, XColors.MediumSpringGreen, 0xFF00FA9A, "Mediumspringgreen", "Mittleres Frühlingsgrün"),
+      new ColorResourceInfo(XKnownColor.SpringGreen, XColors.SpringGreen, 0xFF00FF7F, "Springgreen", "Frühlingsgrün"),
+      new ColorResourceInfo(XKnownColor.Lime, XColors.Lime, 0xFF00FF00, "Lime", "Zitronengrün"),
+      new ColorResourceInfo(XKnownColor.LimeGreen, XColors.LimeGreen, 0xFF32CD32, "Limegreen", "Gelbgrün"),
+      new ColorResourceInfo(XKnownColor.SeaGreen, XColors.SeaGreen, 0xFF2E8B57, "Seagreen", "Seegrün"),
+      new ColorResourceInfo(XKnownColor.ForestGreen, XColors.ForestGreen, 0xFF228B22, "Forestgreen", "Waldgrün"),
+      new ColorResourceInfo(XKnownColor.Green, XColors.Green, 0xFF008000, "Green", "Grün"),
+      new ColorResourceInfo(XKnownColor.LawnGreen, XColors.LawnGreen, 0xFF008000, "LawnGreen", "Grasgrün"),
+      new ColorResourceInfo(XKnownColor.DarkGreen, XColors.DarkGreen, 0xFF006400, "Darkgreen", "Dunkelgrün"),
       //new ColorResourceInfo(XKnownColor.OliveDrab, XColors.OliveDrab, 0xFF6B8E23, "Olivedrab", "Olivfarbiges Graubraun"),
       new ColorResourceInfo(XKnownColor.OliveDrab, XColors.OliveDrab, 0xFF6B8E23, "Olivedrab", "Reife Olive"),
-      new ColorResourceInfo(XKnownColor.DarkOliveGreen, XColors.DarkOliveGreen, 0xFF556B2F, "Darkolivegreen", "Dunkles Olivgrün"),
-      new ColorResourceInfo(XKnownColor.Olive, XColors.Olive, 0xFF808000, "Olive", "Olivgrün"),
+      new ColorResourceInfo(XKnownColor.DarkOliveGreen, XColors.DarkOliveGreen, 0xFF556B2F, "Darkolivegreen", "Dunkles Olivgrün"),
+      new ColorResourceInfo(XKnownColor.Olive, XColors.Olive, 0xFF808000, "Olive", "Olivgrün"),
       new ColorResourceInfo(XKnownColor.DarkKhaki, XColors.DarkKhaki, 0xFFBDB76B, "Darkkhaki", "Dunkles Khaki"),
-      new ColorResourceInfo(XKnownColor.YellowGreen, XColors.YellowGreen, 0xFF9ACD32, "Yellowgreen", "Gelbgrün"),
-      new ColorResourceInfo(XKnownColor.Chartreuse, XColors.Chartreuse, 0xFF7FFF00, "Chartreuse", "Hellgrün"),
-      new ColorResourceInfo(XKnownColor.GreenYellow, XColors.GreenYellow, 0xFFADFF2F, "Greenyellow", "Grüngelb"),
+      new ColorResourceInfo(XKnownColor.YellowGreen, XColors.YellowGreen, 0xFF9ACD32, "Yellowgreen", "Gelbgrün"),
+      new ColorResourceInfo(XKnownColor.Chartreuse, XColors.Chartreuse, 0xFF7FFF00, "Chartreuse", "Hellgrün"),
+      new ColorResourceInfo(XKnownColor.GreenYellow, XColors.GreenYellow, 0xFFADFF2F, "Greenyellow", "Grüngelb"),
     };
 
     internal struct ColorResourceInfo
diff --git a/lib/PdfSharp/PdfSharp.Drawing/XColors.cs b/lib/PdfSharp/PdfSharp.Drawing/XColors.cs
index 8afb3bd..30d90ac 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/XColors.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/XColors.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -45,11 +45,8 @@ namespace PdfSharp.Drawing
   /// Represents a set of 141 pre-defined RGB colors. Incidentally the values are the same
   /// as in System.Drawing.Color.
   /// </summary>
-  public sealed class XColors
+  public static class XColors
   {
-    private XColors()
-    { }
-
     ///<summary>Gets a predefined color.</summary>
     public static XColor AliceBlue { get { return new XColor(XKnownColor.AliceBlue); } }
     ///<summary>Gets a predefined color.</summary>
diff --git a/lib/PdfSharp/PdfSharp.Drawing/XConvert.cs b/lib/PdfSharp/PdfSharp.Drawing/XConvert.cs
index 7dbf6af..6f571f8 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/XConvert.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/XConvert.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -73,7 +73,7 @@ namespace PdfSharp.Drawing
     {
       return wpfLineJoin[(int)lineJoin];
     }
-    static PenLineJoin[] wpfLineJoin = new PenLineJoin[3] { PenLineJoin.Miter, PenLineJoin.Round, PenLineJoin.Bevel };
+    static readonly PenLineJoin[] wpfLineJoin = new PenLineJoin[] { PenLineJoin.Miter, PenLineJoin.Round, PenLineJoin.Bevel };
 #endif
 
 #if WPF
@@ -84,7 +84,7 @@ namespace PdfSharp.Drawing
     {
       return wpfLineCap[(int)lineCap];
     }
-    static PenLineCap[] wpfLineCap = new PenLineCap[3] { PenLineCap.Flat, PenLineCap.Round, PenLineCap.Square };
+    static readonly PenLineCap[] wpfLineCap = new PenLineCap[] { PenLineCap.Flat, PenLineCap.Round, PenLineCap.Square };
 #endif
   }
 }
\ No newline at end of file
diff --git a/lib/PdfSharp/PdfSharp.Drawing/XFont.cs b/lib/PdfSharp/PdfSharp.Drawing/XFont.cs
index f89de91..56e9f8b 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/XFont.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/XFont.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -28,6 +28,7 @@
 #endregion
 
 using System;
+using System.Collections.Generic;
 using System.Diagnostics;
 using System.Runtime.InteropServices;
 using System.ComponentModel;
@@ -41,7 +42,8 @@ using System.Windows;
 using System.Windows.Media;
 #endif
 using PdfSharp.Internal;
-using PdfSharp.Fonts.TrueType;
+using PdfSharp.Fonts;
+using PdfSharp.Fonts.OpenType;
 using PdfSharp.Pdf;
 using PdfSharp.Pdf.Advanced;
 
@@ -51,7 +53,7 @@ using PdfSharp.Pdf.Advanced;
 namespace PdfSharp.Drawing
 {
   /// <summary>
-  /// Defines an object used to draw glyphs.
+  /// Defines an object used to draw text.
   /// </summary>
   [DebuggerDisplay("'{Name}', {Size}")]
   public class XFont
@@ -64,7 +66,7 @@ namespace PdfSharp.Drawing
     public XFont(string familyName, double emSize)
     {
       this.familyName = familyName;
-      this.size = emSize;
+      this.emSize = emSize;
       this.style = XFontStyle.Regular;
       this.pdfOptions = new XPdfFontOptions();
       Initialize();
@@ -79,7 +81,7 @@ namespace PdfSharp.Drawing
     public XFont(string familyName, double emSize, XFontStyle style)
     {
       this.familyName = familyName;
-      this.size = emSize;
+      this.emSize = emSize;
       this.style = style;
       this.pdfOptions = new XPdfFontOptions();
       Initialize();
@@ -95,13 +97,13 @@ namespace PdfSharp.Drawing
     public XFont(string familyName, double emSize, XFontStyle style, XPdfFontOptions pdfOptions)
     {
       this.familyName = familyName;
-      this.size = emSize;
+      this.emSize = emSize;
       this.style = style;
       this.pdfOptions = pdfOptions;
       Initialize();
     }
 
-#if GDI
+#if GDI // #PFC
     /// <summary>
     /// Initializes a new instance of the <see cref="XFont"/> class.
     /// </summary>
@@ -109,16 +111,15 @@ namespace PdfSharp.Drawing
     /// <param name="emSize">The em size.</param>
     /// <param name="style">The font style.</param>
     /// <param name="pdfOptions">Additional PDF options.</param>
-    /// <param name="privateFontCollection">The private font collection.</param>
-    public XFont(System.Drawing.FontFamily family, double emSize, XFontStyle style, XPdfFontOptions pdfOptions,
-      XPrivateFontCollection privateFontCollection)
+    public XFont(System.Drawing.FontFamily family, double emSize, XFontStyle style, XPdfFontOptions pdfOptions /*,
+      XPrivateFontCollection privateFontCollection*/
+                                                    )
     {
       this.familyName = null;
       this.gdifamily = family;
-      this.size = emSize;
+      this.emSize = emSize;
       this.style = style;
       this.pdfOptions = pdfOptions;
-      this.privateFontCollection = privateFontCollection;
       Initialize();
     }
 #endif
@@ -136,7 +137,7 @@ namespace PdfSharp.Drawing
         throw new ArgumentException("Font must use GraphicsUnit.World.");
       this.font = font;
       this.familyName = font.Name;
-      this.size = font.Size;
+      this.emSize = font.Size;
       this.style = FontStyleFrom(font);
       this.pdfOptions = pdfOptions;
       Initialize();
@@ -144,19 +145,49 @@ namespace PdfSharp.Drawing
 #endif
 #endif
 
+    /// <summary>
+    /// Connects the specifications of a font from XFont to a real glyph type face.
+    /// </summary>
     void Initialize()
     {
-      XFontMetrics fm;
+      XFontMetrics fm = null;
+
+#if DEBUG___
+      FontData[] fontDataArray = FontDataStock.Global.GetFontDataList();
+      if (fontDataArray.Length > 0)
+      {
+        ////        GetType();
+        ////#if GDI
+        ////        var x = XPrivateFontCollection.global.GlobalPrivateFontCollection;
+        ////        families = x.Families;
+
+        ////        bool fff = families[0].IsStyleAvailable(System.Drawing.FontStyle.Regular);
+        ////        fff.GetType();
+        ////        this.font = new Font(families[0].Name, 12, System.Drawing.FontStyle.Regular, GraphicsUnit.Pixel);
+
+        ////        this.font = new Font("Oblivious", 12, System.Drawing.FontStyle.Regular, GraphicsUnit.Pixel);
+
+        ////        this.font = new Font(families[0], 12, System.Drawing.FontStyle.Regular, GraphicsUnit.Pixel);
+
+        ////        System.Drawing.FontFamily f = new System.Drawing.FontFamily(families[0].Name);
+        ////        f.GetType();
+        ////#endif
+      }
+#endif
 #if GDI
       if (this.font == null)
       {
         if (this.gdifamily != null)
         {
-          this.font = new Font(this.gdifamily, (float)this.size, (System.Drawing.FontStyle)this.style, GraphicsUnit.World);
+          this.font = new Font(this.gdifamily, (float)this.emSize, (System.Drawing.FontStyle)this.style, GraphicsUnit.World);
           this.familyName = this.gdifamily.Name; // Do we need this???
         }
         else
-          this.font = new Font(this.familyName, (float)this.size, (System.Drawing.FontStyle)this.style, GraphicsUnit.World);
+        {
+          // First check private fonts
+          this.font = XPrivateFontCollection.TryFindPrivateFont(this.familyName, this.emSize, (System.Drawing.FontStyle)this.style) ??
+            new Font(this.familyName, (float)this.emSize, (System.Drawing.FontStyle)this.style, GraphicsUnit.World);
+        }
 #if DEBUG
         // new Font returns MSSansSerif if the requested font was not found ...
         //Debug.Assert(this.familyName == this.font.FontFamily.Name);
@@ -172,7 +203,10 @@ namespace PdfSharp.Drawing
       //Debug.Assert(this.cellSpace == fm.Ascent + Math.Abs(fm.Descent) + fm.Leading, "Value differs from information retrieved from font image.");
 
       this.cellAscent = fontFamily.GetCellAscent(font.Style);
-      Debug.Assert(this.cellAscent == fm.Ascent, "Value differs from information retrieved from font image.");
+#pragma warning disable 1030
+#warning delTHHO
+      //!!!delTHHO 14.08.2008 Debug.Assert(this.cellAscent == fm.Ascent, "Value differs from information retrieved from font image.");
+      //Debug.Assert(this.cellAscent == fm.Ascent, "Value differs from information retrieved from font image.");
 
       this.cellDescent = fontFamily.GetCellDescent(font.Style);
 #if DEBUG
@@ -182,13 +216,34 @@ namespace PdfSharp.Drawing
 #endif
 #endif
 #if WPF
-      // TODOWPF: PrivateFonts
+#if !SILVERLIGHT
+      if (this.family == null)
+      {
+        Debug.Assert(this.typeface == null);
+        this.typeface = XPrivateFontCollection.TryFindTypeface(Name, this.style, out this.family);
+#if true
+        if (this.typeface != null)
+        {
+          GlyphTypeface glyphTypeface;
+
+          ICollection<Typeface> list = this.family.GetTypefaces();
+          foreach (Typeface tf in list)
+          {
+            if (!tf.TryGetGlyphTypeface(out glyphTypeface))
+              Debugger.Break();
+          }
+
+          if (!this.typeface.TryGetGlyphTypeface(out glyphTypeface))
+            throw new InvalidOperationException(PSSR.CannotGetGlyphTypeface(Name));
+        }
+#endif
+      }
+
       if (this.family == null)
-        this.family = new System.Windows.Media.FontFamily(this.Name);
+        this.family = new System.Windows.Media.FontFamily(Name);
 
-      if (this.typeface == null)
-        this.typeface = new Typeface(family, FontHelper.FontStyleFromStyle(this.style),
-          FontHelper.FontWeightFromStyle(this.style), new FontStretch());
+      if (typeface == null)
+        this.typeface = FontHelper.CreateTypeface(this.family, style);
 
       fm = Metrics;
       Debug.Assert(this.unitsPerEm == 0 || this.unitsPerEm == fm.UnitsPerEm);
@@ -202,15 +257,27 @@ namespace PdfSharp.Drawing
 
       Debug.Assert(this.cellDescent == 0 || this.cellDescent == Math.Abs(fm.Descent));
       this.cellDescent = Math.Abs(fm.Descent);
+#else
+      if (fm != null)
+        fm.GetType();
+#endif
 #endif
     }
 
 #if GDI
     // Fonts can be created from familyName or from family!
     //string familyName;
+    /// <summary>
+    /// Gets the GDI family.
+    /// </summary>
+    /// <value>The GDI family.</value>
+    public System.Drawing.FontFamily GdiFamily
+    {
+      get { return this.gdifamily; }
+      //set { this.gdifamily = value; }
+    }
     System.Drawing.FontFamily gdifamily;
 #endif
-    internal XPrivateFontCollection privateFontCollection;
 
 #if GDI
     internal static XFontStyle FontStyleFrom(Font font)
@@ -262,7 +329,7 @@ namespace PdfSharp.Drawing
       RealizeGdiFont();
       double gdiValue = this.font.GetHeight();
 #if DEBUG
-      float myValue = (float)(this.cellSpace * this.size / this.unitsPerEm);
+      float myValue = (float)(this.cellSpace * this.emSize / this.unitsPerEm);
       //Debug.Assert(DoubleUtil.AreClose((float)value, myValue), "Check formula.");
       Debug.Assert(DoubleUtil.AreRoughlyEqual(gdiValue, myValue, 5), "Check formula.");
 
@@ -276,9 +343,8 @@ namespace PdfSharp.Drawing
       return gdiValue;
 #endif
 #if WPF
-      // BUG: wrong value
-      double wpfValue = this.cellSpace * this.size / this.unitsPerEm;
-      return wpfValue;
+      double value = this.cellSpace * this.emSize / this.unitsPerEm;
+      return value;
 #endif
     }
 
@@ -293,11 +359,13 @@ namespace PdfSharp.Drawing
       RealizeGdiFont();
       double value = this.font.GetHeight(graphics.gfx);
       Debug.Assert(value == this.font.GetHeight(graphics.gfx.DpiY));
+      double value2 = this.cellSpace * this.emSize / this.unitsPerEm;
+      Debug.Assert(value - value2 < 1e-3, "??");
       return this.font.GetHeight(graphics.gfx);
 #endif
 #if WPF && !GDI
-      // BUG: wrong value
-      return this.size;
+      double value = this.cellSpace * this.emSize / this.unitsPerEm;
+      return value;
 #endif
 #if GDI && WPF
       if (graphics.targetContext == XGraphicTargetContext.GDI)
@@ -307,8 +375,8 @@ namespace PdfSharp.Drawing
         double value = this.font.GetHeight(graphics.gfx);
 
         // 2355*(0.3/2048)*96 = 33.11719 
-        double myValue = this.cellSpace * (this.size / (96 * this.unitsPerEm)) * 96;
-        myValue = this.cellSpace * this.size / this.unitsPerEm;
+        double myValue = this.cellSpace * (this.emSize / (96 * this.unitsPerEm)) * 96;
+        myValue = this.cellSpace * this.emSize / this.unitsPerEm;
         //Debug.Assert(value == myValue, "??");
         //Debug.Assert(value - myValue < 1e-3, "??");
 #endif
@@ -316,8 +384,7 @@ namespace PdfSharp.Drawing
       }
       else if (graphics.targetContext == XGraphicTargetContext.WPF)
       {
-        //this.cellSpace * this.size *96.0/ this.h
-        double value = this.cellSpace * (this.size / (96 * this.unitsPerEm)) * 96;
+        double value = this.cellSpace * this.emSize / this.unitsPerEm;
         return value;
       }
       Debug.Assert(false);
@@ -348,8 +415,12 @@ namespace PdfSharp.Drawing
           this.fontFamily = new XFontFamily(this.font.FontFamily);
 #endif
 #if WPF
+#if !SILVERLIGHT
           Debug.Assert(this.family != null);
           this.fontFamily = new XFontFamily(this.family);
+#else
+          // AGHACK
+#endif
 #endif
         }
         return this.fontFamily;
@@ -368,7 +439,7 @@ namespace PdfSharp.Drawing
         RealizeGdiFont();
         return this.font.Name;
 #endif
-#if WPF
+#if WPF || SILVERLIGHT
         //RealizeGdiFont();
         return this.familyName;
 #endif
@@ -380,9 +451,9 @@ namespace PdfSharp.Drawing
     /// </summary>
     public double Size
     {
-      get { return this.size; }
+      get { return this.emSize; }
     }
-    double size;
+    double emSize;
 
 
     /// <summary>
@@ -393,17 +464,16 @@ namespace PdfSharp.Drawing
     {
       // Implementation from System.Drawing.Font.cs
       get { return (int)Math.Ceiling(GetHeight()); }
+      // DELETE
       //      {
       //#if GDI && !WPF
       //        RealizeGdiFont();
       //        return this.font.Height;
       //#endif
       //#if WPF && !GDI
-      //        // TODOWPF
       //        return (int)this.size;
       //#endif
       //#if GDI && WPF
-      //        // TODOWPF
       //        // netmassdownloader -d "C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.5" -output G:\dotnet-massdownload\SourceCode -v
       //        RealizeGdiFont();
       //        int gdiHeight = this.font.Height;
@@ -431,7 +501,7 @@ namespace PdfSharp.Drawing
     /// </summary>
     public bool Bold
     {
-      get { return ((this.style & XFontStyle.Bold) == XFontStyle.Bold); }
+      get { return (this.style & XFontStyle.Bold) == XFontStyle.Bold; }
     }
 
     /// <summary>
@@ -439,7 +509,7 @@ namespace PdfSharp.Drawing
     /// </summary>
     public bool Italic
     {
-      get { return ((this.style & XFontStyle.Italic) == XFontStyle.Italic); }
+      get { return (this.style & XFontStyle.Italic) == XFontStyle.Italic; }
     }
 
     /// <summary>
@@ -447,7 +517,7 @@ namespace PdfSharp.Drawing
     /// </summary>
     public bool Strikeout
     {
-      get { return ((this.style & XFontStyle.Strikeout) == XFontStyle.Strikeout); }
+      get { return (this.style & XFontStyle.Strikeout) == XFontStyle.Strikeout; }
     }
 
     /// <summary>
@@ -455,10 +525,21 @@ namespace PdfSharp.Drawing
     /// </summary>
     public bool Underline
     {
-      get { return ((this.style & XFontStyle.Underline) == XFontStyle.Underline); }
+      get { return (this.style & XFontStyle.Underline) == XFontStyle.Underline; }
     }
 
     /// <summary>
+    /// Temporary HACK for XPS to PDF converter.
+    /// </summary>
+    internal bool IsVertical
+    {
+      get { return this.isVertical; }
+      set { this.isVertical = value; }
+    }
+    bool isVertical;
+
+
+    /// <summary>
     /// Gets the PDF options of the font.
     /// </summary>
     public XPdfFontOptions PdfOptions
@@ -520,7 +601,7 @@ namespace PdfSharp.Drawing
     internal Font font;
 #endif
 
-#if WPF
+#if WPF && !SILVERLIGHT
     internal Typeface RealizeWpfTypeface()
     {
       return this.typeface;
diff --git a/lib/PdfSharp/PdfSharp.Drawing/XFontFamily.cs b/lib/PdfSharp/PdfSharp.Drawing/XFontFamily.cs
index 42bdf81..bd74296 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/XFontFamily.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/XFontFamily.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -38,7 +38,7 @@ using System.Drawing.Drawing2D;
 using System.Windows.Media;
 #endif
 using PdfSharp.Pdf;
-using PdfSharp.Fonts.TrueType;
+using PdfSharp.Fonts.OpenType;
 
 // WPFHACK
 #pragma warning disable 162
@@ -67,6 +67,10 @@ namespace PdfSharp.Drawing
     internal XFontFamily(System.Windows.Media.FontFamily family)
     {
       this.name = family.Source;
+      // HACK
+      int idxHash = this.name.LastIndexOf('#');
+      if (idxHash > 0)
+        this.name = this.name.Substring(idxHash + 1);
       this.wpfFamily = family;
 #if GDI
       this.gdiFamily = new System.Drawing.FontFamily(family.Source);
@@ -105,7 +109,7 @@ namespace PdfSharp.Drawing
     {
       get { return this.name; }
     }
-    string name;
+    readonly string name;
 
     /// <summary>
     /// Returns the cell ascent, in design units, of the XFontFamily object of the specified style.
@@ -155,6 +159,10 @@ namespace PdfSharp.Drawing
     public int GetEmHeight(XFontStyle style)
     {
 #if GDI && !WPF
+#if DEBUG
+      int gdiResult = this.gdiFamily.GetEmHeight((FontStyle)style);
+      //int wpfResult = FontHelper.GetWpfValue(this, style, GWV.GetEmHeight);
+#endif
       return this.gdiFamily.GetEmHeight((FontStyle)style);
 #endif
 #if WPF && !GDI
@@ -205,16 +213,16 @@ namespace PdfSharp.Drawing
       return this.gdiFamily.IsStyleAvailable((FontStyle)style);
 #endif
 #if WPF && !GDI
-      return FontHelper.GetWpfValue(this, style, GWV.IsStyleAvailable) == 1;
+      return FontHelper.IsStyleAvailable(this, style);
 #endif
 #if WPF && GDI
 #if DEBUG
       bool gdiResult = this.gdiFamily.IsStyleAvailable((FontStyle)style);
-      bool wpfResult = FontHelper.GetWpfValue(this, style, GWV.IsStyleAvailable) == 1;
-      // TODOWPF
-      //Debug.Assert(gdiResult == wpfResult, "GDI+ and WPF provides different values.");
+      bool wpfResult = FontHelper.IsStyleAvailable(this, style);
+      // TODOWPF: check when fails
+      Debug.Assert(gdiResult == wpfResult, "GDI+ and WPF provides different values.");
 #endif
-      return FontHelper.GetWpfValue(this, style, GWV.IsStyleAvailable) == 1;
+      return FontHelper.IsStyleAvailable(this, style);
 #endif
     }
 
@@ -241,7 +249,7 @@ namespace PdfSharp.Drawing
 #endif
 #if WPF
         //System.Windows.Media.Fonts.GetFontFamilies(
-        // TODOWPF
+        // TODOWPF: not very important
         return null;
 #endif
       }
@@ -263,6 +271,7 @@ namespace PdfSharp.Drawing
         result[idx] = new XFontFamily(families[idx]);
 #endif
 #if WPF
+      // TODOWPF: not very important
       result = null;
 #endif
       return result;
diff --git a/lib/PdfSharp/PdfSharp.Drawing/XFontMetrics.cs b/lib/PdfSharp/PdfSharp.Drawing/XFontMetrics.cs
index 0df6ae6..5433314 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/XFontMetrics.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/XFontMetrics.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Drawing/XFontStretch.cs b/lib/PdfSharp/PdfSharp.Drawing/XFontStretch.cs
new file mode 100644
index 0000000..24f357b
--- /dev/null
+++ b/lib/PdfSharp/PdfSharp.Drawing/XFontStretch.cs
@@ -0,0 +1,57 @@
+#region PDFsharp - A .NET library for processing PDF
+//
+// Authors:
+//   Stefan Lange (mailto:Stefan Lange pdfsharp com)
+//
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
+//
+// http://www.pdfsharp.com
+// http://sourceforge.net/projects/pdfsharp
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+// DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+using System.ComponentModel;
+using System.IO;
+#if GDI
+using System.Drawing;
+using System.Drawing.Drawing2D;
+#endif
+#if WPF
+using System.Windows;
+using System.Windows.Media;
+#endif
+using PdfSharp.Internal;
+using PdfSharp.Fonts.OpenType;
+using PdfSharp.Pdf;
+using PdfSharp.Pdf.Advanced;
+
+namespace PdfSharp.Drawing
+{
+  /// <summary>
+  /// NYI. Reserved for future extensions of PDFsharp.
+  /// </summary>
+  // [DebuggerDisplay("'{Name}', {Size}")]
+  public class XFontStretch
+  {
+  }
+}
diff --git a/lib/PdfSharp/PdfSharp.Drawing/XFontWeight.cs b/lib/PdfSharp/PdfSharp.Drawing/XFontWeight.cs
new file mode 100644
index 0000000..638d413
--- /dev/null
+++ b/lib/PdfSharp/PdfSharp.Drawing/XFontWeight.cs
@@ -0,0 +1,178 @@
+#region PDFsharp - A .NET library for processing PDF
+//
+// Authors:
+//   Stefan Lange (mailto:Stefan Lange pdfsharp com)
+//
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
+//
+// http://www.pdfsharp.com
+// http://sourceforge.net/projects/pdfsharp
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+// DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+using System.ComponentModel;
+using System.IO;
+#if GDI
+using System.Drawing;
+using System.Drawing.Drawing2D;
+#endif
+#if WPF
+using System.Windows;
+using System.Windows.Media;
+#endif
+using PdfSharp.Internal;
+using PdfSharp.Fonts.OpenType;
+using PdfSharp.Pdf;
+using PdfSharp.Pdf.Advanced;
+
+namespace PdfSharp.Drawing
+{
+  /// <summary>
+  /// Defines the density of a typeface, in terms of the lightness or heaviness of the strokes.
+  /// </summary>
+  [DebuggerDisplay("'{Weight}'")]
+  public class XFontWeight : IFormattable
+  {
+    internal XFontWeight(int weight)
+    {
+      this.weight = weight;
+    }
+
+    /// <summary>
+    /// Gets the weight of the font, a value between 1 and 999.
+    /// </summary>
+    public int Weight
+    {
+      get { return (this.weight); }
+    }
+    private int weight;
+
+    //public static XFontWeight FromOpenTypeWeight(int weightValue)
+    //{
+    //  if (weightValue < 1 || weightValue > 999)
+    //    throw new ArgumentOutOfRangeException("weightValue", "Parameter must be between 1 and 999.");
+    //  return new XFontWeight(weightValue);
+    //}
+
+    /// <summary>
+    /// Compares the specified font weights.
+    /// </summary>
+    public static int Compare(XFontWeight left, XFontWeight right)
+    {
+      return left.weight - right.weight;
+    }
+
+    /// <summary>
+    /// Implements the operator &lt;.
+    /// </summary>
+    public static bool operator <(XFontWeight left, XFontWeight right)
+    {
+      return Compare(left, right) < 0;
+    }
+
+    /// <summary>
+    /// Implements the operator &lt;=.
+    /// </summary>
+    public static bool operator <=(XFontWeight left, XFontWeight right)
+    {
+      return Compare(left, right) <= 0;
+    }
+
+    /// <summary>
+    /// Implements the operator &gt;.
+    /// </summary>
+    public static bool operator >(XFontWeight left, XFontWeight right)
+    {
+      return Compare(left, right) > 0;
+    }
+
+    /// <summary>
+    /// Implements the operator &gt;=.
+    /// </summary>
+    public static bool operator >=(XFontWeight left, XFontWeight right)
+    {
+      return Compare(left, right) >= 0;
+    }
+
+    /// <summary>
+    /// Implements the operator ==.
+    /// </summary>
+    public static bool operator ==(XFontWeight left, XFontWeight right)
+    {
+      return Compare(left, right) == 0;
+    }
+
+    /// <summary>
+    /// Implements the operator !=.
+    /// </summary>
+    public static bool operator !=(XFontWeight left, XFontWeight right)
+    {
+      return !(left == right);
+    }
+
+    /// <summary>
+    /// Determines whether the specified <see cref="XFontWeight"/> is equal to the current <see cref="XFontWeight"/>.
+    /// </summary>
+    public bool Equals(XFontWeight obj)
+    {
+      return this == obj;
+    }
+
+    /// <summary>
+    /// Determines whether the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>.
+    /// </summary>
+    public override bool Equals(object obj)
+    {
+      return (obj is XFontWeight) && this == ((XFontWeight) obj);
+    }
+
+    /// <summary>
+    /// Serves as a hash function for this type.
+    /// </summary>
+    public override int GetHashCode()
+    {
+      return Weight;
+    }
+
+    /// <summary>
+    /// Returns a <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>.
+    /// </summary>
+    public override string ToString()
+    {
+      return ConvertToString(null, null);
+    }
+
+    string IFormattable.ToString(string format, IFormatProvider provider)
+    {
+      return ConvertToString(format, provider);
+    }
+
+    private string ConvertToString(string format, IFormatProvider provider)
+    {
+      string str;
+      if (!XFontWeights.FontWeightToString(Weight, out str))
+        return Weight.ToString(provider);
+      return str;
+    }
+  }
+}
diff --git a/lib/PdfSharp/PdfSharp.Drawing/XFontWeights.cs b/lib/PdfSharp/PdfSharp.Drawing/XFontWeights.cs
new file mode 100644
index 0000000..5ede7c8
--- /dev/null
+++ b/lib/PdfSharp/PdfSharp.Drawing/XFontWeights.cs
@@ -0,0 +1,295 @@
+#region PDFsharp - A .NET library for processing PDF
+//
+// Authors:
+//   Stefan Lange (mailto:Stefan Lange pdfsharp com)
+//
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
+//
+// http://www.pdfsharp.com
+// http://sourceforge.net/projects/pdfsharp
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+// DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Diagnostics;
+using System.Globalization;
+
+namespace PdfSharp.Drawing
+{
+  /// <summary>
+  /// Defines a set of static predefined XFontWeight values.
+  /// </summary>
+  public static class XFontWeights
+  {
+    internal static bool FontWeightStringToKnownWeight(string s, IFormatProvider provider, ref XFontWeight fontWeight)
+    {
+      int num;
+      switch (s.ToLower())
+      {
+        case "thin":
+          fontWeight = Thin;
+          return true;
+
+        case "extralight":
+          fontWeight = ExtraLight;
+          return true;
+
+        case "ultralight":
+          fontWeight = UltraLight;
+          return true;
+
+        case "light":
+          fontWeight = Light;
+          return true;
+
+        case "normal":
+          fontWeight = Normal;
+          return true;
+
+        case "regular":
+          fontWeight = Regular;
+          return true;
+
+        case "medium":
+          fontWeight = Medium;
+          return true;
+
+        case "semibold":
+          fontWeight = SemiBold;
+          return true;
+
+        case "demibold":
+          fontWeight = DemiBold;
+          return true;
+
+        case "bold":
+          fontWeight = Bold;
+          return true;
+
+        case "extrabold":
+          fontWeight = ExtraBold;
+          return true;
+
+        case "ultrabold":
+          fontWeight = UltraBold;
+          return true;
+
+        case "heavy":
+          fontWeight = Heavy;
+          return true;
+
+        case "black":
+          fontWeight = Black;
+          return true;
+
+        case "extrablack":
+          fontWeight = ExtraBlack;
+          return true;
+
+        case "ultrablack":
+          fontWeight = UltraBlack;
+          return true;
+      }
+
+      if (Int32.TryParse(s, NumberStyles.Integer, provider, out num))
+      {
+        fontWeight = new XFontWeight(num);
+        return true;
+      }
+      return false;
+    }
+
+    internal static bool FontWeightToString(int weight, out string convertedValue)
+    {
+      switch (weight)
+      {
+        case 100:
+          convertedValue = "Thin";
+          return true;
+
+        case 200:
+          convertedValue = "ExtraLight";
+          return true;
+
+        case 300:
+          convertedValue = "Light";
+          return true;
+
+        case 400:
+          convertedValue = "Normal";
+          return true;
+
+        case 500:
+          convertedValue = "Medium";
+          return true;
+
+        case 600:
+          convertedValue = "SemiBold";
+          return true;
+
+        case 700:
+          convertedValue = "Bold";
+          return true;
+
+        case 800:
+          convertedValue = "ExtraBold";
+          return true;
+
+        case 900:
+          convertedValue = "Black";
+          return true;
+
+        case 950:
+          convertedValue = "ExtraBlack";
+          return true;
+      }
+      convertedValue = null;
+      return false;
+    }
+
+    /// <summary>
+    /// Specifies a "Thin" font weight.
+    /// </summary>
+    public static XFontWeight Thin
+    {
+      get { return new XFontWeight(100); }
+    }
+
+    /// <summary>
+    /// Specifies a "ExtraLight" font weight.
+    /// </summary>
+    public static XFontWeight ExtraLight
+    {
+      get { return new XFontWeight(200); }
+    }
+
+    /// <summary>
+    /// Specifies a "UltraLight" font weight.
+    /// </summary>
+    public static XFontWeight UltraLight
+    {
+      get { return new XFontWeight(200); }
+    }
+
+    /// <summary>
+    /// Specifies a "Light" font weight.
+    /// </summary>
+    public static XFontWeight Light
+    {
+      get { return new XFontWeight(300); }
+    }
+
+    /// <summary>
+    /// Specifies a "Normal" font weight.
+    /// </summary>
+    public static XFontWeight Normal
+    {
+      get { return new XFontWeight(400); }
+    }
+
+    /// <summary>
+    /// Specifies a "Regular" font weight.
+    /// </summary>
+    public static XFontWeight Regular
+    {
+      get { return new XFontWeight(400); }
+    }
+
+    /// <summary>
+    /// Specifies a "Medium" font weight.
+    /// </summary>
+    public static XFontWeight Medium
+    {
+      get { return new XFontWeight(500); }
+    }
+
+    /// <summary>
+    /// Specifies a "SemiBold" font weight.
+    /// </summary>
+    public static XFontWeight SemiBold
+    {
+      get { return new XFontWeight(600); }
+    }
+
+    /// <summary>
+    /// Specifies a "DemiBold" font weight.
+    /// </summary>
+    public static XFontWeight DemiBold
+    {
+      get { return new XFontWeight(600); }
+    }
+
+    /// <summary>
+    /// Specifies a "Bold" font weight.
+    /// </summary>
+    public static XFontWeight Bold
+    {
+      get { return new XFontWeight(700); }
+    }
+
+    /// <summary>
+    /// Specifies a "ExtraBold" font weight.
+    /// </summary>
+    public static XFontWeight ExtraBold
+    {
+      get { return new XFontWeight(800); }
+    }
+
+    /// <summary>
+    /// Specifies a "UltraBold" font weight.
+    /// </summary>
+    public static XFontWeight UltraBold
+    {
+      get { return new XFontWeight(800); }
+    }
+
+    /// <summary>
+    /// Specifies a "Heavy" font weight.
+    /// </summary>
+    public static XFontWeight Heavy
+    {
+      get { return new XFontWeight(900); }
+    }
+
+    /// <summary>
+    /// Specifies a "Black" font weight.
+    /// </summary>
+    public static XFontWeight Black
+    {
+      get { return new XFontWeight(900); }
+    }
+
+    /// <summary>
+    /// Specifies a "ExtraBlack" font weight.
+    /// </summary>
+    public static XFontWeight ExtraBlack
+    {
+      get { return new XFontWeight(950); }
+    }
+
+    /// <summary>
+    /// Specifies a "UltraBlack" font weight.
+    /// </summary>
+    public static XFontWeight UltraBlack
+    {
+      get { return new XFontWeight(950); }
+    }
+  }
+}
\ No newline at end of file
diff --git a/lib/PdfSharp/PdfSharp.Drawing/XForm.cs b/lib/PdfSharp/PdfSharp.Drawing/XForm.cs
index 282b1c2..2e31278 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/XForm.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/XForm.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -42,7 +42,7 @@ using System.Windows.Media;
 #endif
 using PdfSharp.Internal;
 using PdfSharp.Drawing.Pdf;
-using PdfSharp.Fonts.TrueType;
+using PdfSharp.Fonts.OpenType;
 using PdfSharp.Pdf;
 using PdfSharp.Pdf.IO;
 using PdfSharp.Pdf.Advanced;
@@ -88,7 +88,7 @@ namespace PdfSharp.Drawing
 
 #if GDI
     /// <summary>
-    /// Initializes a new instance of the XForm class such that it can be drawn on the specifed graphics
+    /// Initializes a new instance of the XForm class such that it can be drawn on the specified graphics
     /// object.
     /// </summary>
     /// <param name="gfx">The graphics object that later is used to draw this form.</param>
@@ -118,7 +118,7 @@ namespace PdfSharp.Drawing
 
 #if GDI
     /// <summary>
-    /// Initializes a new instance of the XForm class such that it can be drawn on the specifed graphics
+    /// Initializes a new instance of the XForm class such that it can be drawn on the specified graphics
     /// object.
     /// </summary>
     /// <param name="gfx">The graphics object that later is used to draw this form.</param>
@@ -412,7 +412,7 @@ namespace PdfSharp.Drawing
         this.transform = value;
       }
     }
-    internal XMatrix transform = XMatrix.Identity;
+    internal XMatrix transform = new XMatrix();  //XMatrix.Identity;
 
     internal PdfResources Resources
     {
@@ -543,5 +543,34 @@ namespace PdfSharp.Drawing
     internal PdfFormXObject pdfForm;
 
     internal XGraphicsPdfRenderer pdfRenderer;
+
+#if WPF && !SILVERLIGHT
+    /// <summary>
+    /// Gets a value indicating whether this image is cmyk.
+    /// </summary>
+    /// <value><c>true</c> if this image is cmyk; otherwise, <c>false</c>.</value>
+    public override bool IsCmyk
+    {
+      get { return false; } // not supported and not relevant
+    }
+
+    /// <summary>
+    /// Gets a value indicating whether this image is JPEG.
+    /// </summary>
+    /// <value><c>true</c> if this image is JPEG; otherwise, <c>false</c>.</value>
+    public override bool IsJpeg
+    {
+      get { return base.IsJpeg; }// not supported and not relevant
+    }
+
+    /// <summary>
+    /// Gets the JPEG memory stream (if IsJpeg returns true).
+    /// </summary>
+    /// <value>The memory.</value>
+    public override MemoryStream Memory
+    {
+      get { throw new NotImplementedException(); }
+    }
+#endif
   }
 }
\ No newline at end of file
diff --git a/lib/PdfSharp/PdfSharp.Drawing/XGlyphTypeface.cs b/lib/PdfSharp/PdfSharp.Drawing/XGlyphTypeface.cs
new file mode 100644
index 0000000..46fb909
--- /dev/null
+++ b/lib/PdfSharp/PdfSharp.Drawing/XGlyphTypeface.cs
@@ -0,0 +1,2272 @@
+#region PDFsharp - A .NET library for processing PDF
+//
+// Authors:
+//   Stefan Lange (mailto:Stefan Lange pdfsharp com)
+//
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
+//
+// http://www.pdfsharp.com
+// http://sourceforge.net/projects/pdfsharp
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+// DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+using System.ComponentModel;
+using System.IO;
+#if GDI
+using System.Drawing;
+using System.Drawing.Drawing2D;
+#endif
+#if WPF
+using System.Windows;
+using System.Windows.Media;
+#endif
+using PdfSharp.Internal;
+using PdfSharp.Fonts.OpenType;
+using PdfSharp.Pdf;
+using PdfSharp.Pdf.Advanced;
+
+namespace PdfSharp.Drawing
+{
+  /// <summary>
+  /// Specifies a physical font face that corresponds to a font file on the disk.
+  /// </summary>
+  //[DebuggerDisplay("'{Name}', {Size}")]
+  public class XGlyphTypeface
+  {
+    /// <summary>
+    /// Initializes a new instance of the <see cref="XGlyphTypeface"/> class from the specified font file.
+    /// </summary>
+    public XGlyphTypeface(string filename)
+    {
+      if (String.IsNullOrEmpty(filename))
+        throw new ArgumentNullException("filename");
+
+      FileStream stream = null;
+      try
+      {
+        stream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
+        int length = (int)stream.Length;
+        byte[] data = new byte[length];
+        stream.Read(data, 0, length);
+        Initialize(data);
+      }
+      finally
+      {
+        if (stream != null)
+          stream.Close();
+      }
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="XGlyphTypeface"/> class from the specified font bytes.
+    /// </summary>
+    public XGlyphTypeface(byte[] data)
+    {
+      if (data == null)
+        throw new ArgumentNullException("data");
+
+      Initialize(data);
+    }
+
+    void Initialize(byte[] data)
+    {
+      // Cache data and return a FontData
+      this.fontData = FontDataStock.Global.RegisterFontData(data);
+    }
+
+    internal FontData FontData
+    {
+      get { return this.fontData; }
+    }
+    private FontData fontData;
+
+    /// <summary>
+    /// Gets the English family name of the font.
+    /// </summary>
+    public string FamilyName
+    {
+      get { return "Times"; }
+    }
+
+    /// <summary>
+    /// Gets a value indicating whether the font weight is bold.
+    /// </summary>
+    public bool IsBold
+    {
+      get { return false; }
+    }
+
+    /// <summary>
+    /// Gets a value indicating whether the font style is italic.
+    /// </summary>
+    public bool IsItalic
+    {
+      get { return false; }
+    }
+
+    //internal byte[] GetData()
+    //{
+    //  return this.data;
+    //}
+    //private byte[] data;
+
+
+    //public XPrivateFont(string fontName,
+    //  bool bold,
+    //  bool italic,
+    //  byte[] data,
+    //  int length)
+    //{
+    //  this.FontName = fontName;
+    //  this.Bold = bold;
+    //  this.Italic = italic;
+    //  this.Data = data;
+    //  this.Length = length;
+    //}
+
+    //internal string FontName;
+    //internal bool Bold;
+    //internal bool Italic;
+    //internal byte[] Data;
+    //internal int Length;
+
+    //public int GetFontData(ref byte[] data,
+    //   int length)
+    //{
+    //  if (length == this.Length)
+    //  {
+    //    // Copy the data:
+    //    //Data.CopyTo(data, 0);
+    //    Array.Copy(Data, data, length);
+    //  }
+    //  return this.Length;
+    //}
+
+#if true_
+    #region Constructors 
+
+        /// <summary> 
+        /// Creates an uninitialized GlyphTypeface object. Caller should call ISupportInitialize.BeginInit() 
+        /// to begin initializing the object and call ISupportInitialize.EndInit() to finish the initialization.
+        /// </summary> 
+        public GlyphTypeface()
+        {
+        }
+ 
+        /// <summary>
+        /// Creates a new GlyphTypeface object from a .otf, .ttf or .ttc font face specified by typefaceSource. 
+        /// The constructed GlyphTypeface does not use style simulations. 
+        /// </summary>
+        /// <param name="typefaceSource">Specifies the URI of a font file used by the newly created GlyphTypeface.</param> 
+        public GlyphTypeface(Uri typefaceSource) : this(typefaceSource, StyleSimulations.None)
+        {}
+
+        /// <summary> 
+        /// Creates a new GlyphTypeface object from a .otf, .ttf or .ttc font face specified by typefaceSource.
+        /// The constructed GlyphTypeface uses style simulations specified by styleSimulations parameter. 
+        /// </summary> 
+        /// <param name="typefaceSource">Specifies the URI of a font file used by the newly created GlyphTypeface.</param>
+        /// <param name="styleSimulations">Specifies style simulations to be applied to the newly created GlyphTypeface.</param> 
+        /// <SecurityNote>
+        /// Critical - as this calls the internal constructor that's critical.
+        /// Safe - as the internal constructor does a Demand for FileIO for file
+        ///        Uris for the case where fromPublic is true.  We block constructing 
+        ///        GlyphTypeface directly in SEE since this'd allow guessing fonts on
+        ///        a machine by trying to create a GlyphTypeface object. 
+        /// 
+        /// </SecurityNote>
+        [SecurityCritical] 
+        public GlyphTypeface(Uri typefaceSource, StyleSimulations styleSimulations) :
+                            this (typefaceSource, styleSimulations, /* fromPublic = */ true)
+        {}
+ 
+        /// <summary>
+        /// Creates a new GlyphTypeface object from a .otf, .ttf or .ttc font face specified by typefaceSource. 
+        /// The constructed GlyphTypeface uses style simulations specified by styleSimulations parameter. 
+        /// </summary>
+        /// <param name="typefaceSource">Specifies the URI of a font file used by the newly created GlyphTypeface.</param> 
+        /// <param name="styleSimulations">Specifies style simulations to be applied to the newly created GlyphTypeface.</param>
+        /// <param name="fromPublic">Specifies if the call to the constructor is from a public constructor
+        /// or if its from an internal method. For public constructor we demand FileIO for all files whereas
+        /// for internal calls we don't demand in the constructor. </param> 
+        /// <SecurityNote>
+        /// Critical - as the instance of GlyphTypeface created with this constructor can 
+        ///            expose font information for the case where fromPublic is false. 
+        /// </SecurityNote>
+        [SecurityCritical] 
+        internal GlyphTypeface(Uri typefaceSource, StyleSimulations styleSimulations, bool fromPublic)
+        {
+            Initialize(typefaceSource, styleSimulations, fromPublic);
+        } 
+
+        /// <SecurityNote> 
+        /// Critical - this method calls into other critical method. 
+        /// </SecurityNote>
+        [SecurityCritical] 
+        private void Initialize(Uri typefaceSource, StyleSimulations styleSimulations, bool fromPublic)
+        {
+            if (typefaceSource == null)
+                throw new ArgumentNullException("typefaceSource"); 
+
+            if (!typefaceSource.IsAbsoluteUri) 
+                throw new ArgumentException(SR.Get(SRID.UriNotAbsolute), "typefaceSource"); 
+
+            // remember the original Uri that contains face index 
+            _originalUri = new SecurityCriticalDataClass<Uri>(typefaceSource);
+
+            // split the Uri into the font source Uri and face index
+            Uri fontSourceUri; 
+            int faceIndex;
+            Util.SplitFontFaceIndex(typefaceSource, out fontSourceUri, out faceIndex); 
+ 
+            _fileIOPermObj = new SecurityCriticalDataForSet<CodeAccessPermission>(
+                SecurityHelper.CreateUriReadPermission(fontSourceUri) 
+                );
+
+            // This permission demand is here so that untrusted callers are unable to check for file existence using GlyphTypeface ctor.
+            // Sensitive font data is protected by demands as the user tries to access it. 
+            // The demand below is skipped for non-public calls, because in such cases
+            // fonts are exposed as logical fonts to the end user. 
+            if (fromPublic) 
+                DemandPermissionsForFontInformation();
+ 
+            // We skip permission demands for FontSource because the above line already demands them for the right callers.
+            _fontFace = new FontFaceLayoutInfo(new FontSource(fontSourceUri, true), faceIndex);
+            CacheManager.Lookup(_fontFace);
+ 
+            if ((styleSimulations & ~StyleSimulations.BoldItalicSimulation) != 0)
+                throw new InvalidEnumArgumentException("styleSimulations", (int)styleSimulations, typeof(StyleSimulations)); 
+            _styleSimulations = styleSimulations; 
+
+            _initializationState = InitializationState.IsInitialized; // fully initialized 
+        }
+
+    #endregion Constructors
+ 
+        //------------------------------------------------------
+        // 
+        //  Public Methods 
+        //
+        //----------------------------------------------------- 
+
+    #region Public Methods
+
+        /// <summary> 
+        /// Return hash code for this GlyphTypeface.
+        /// </summary> 
+        /// <returns>Hash code.</returns> 
+        /// <SecurityNote>
+        /// Critical - as this accesses _originalUri. 
+        /// Safe - as this only does this to compute the hash code.
+        /// </SecurityNote>
+        [SecurityCritical]
+        public override int GetHashCode() 
+        {
+            CheckInitialized(); 
+            return _originalUri.Value.GetHashCode() ^ (int)StyleSimulations; 
+        }
+ 
+        /// <summary>
+        /// Compares this GlyphTypeface with another object.
+        /// </summary>
+        /// <param name="o">Object to compare with.</param> 
+        /// <returns>Whether this object is equal to the input object.</returns>
+        /// <SecurityNote> 
+        /// Critical - as this accesses _originalUri. 
+        /// Safe - as this only does this to perform a comparison with another object.
+        /// </SecurityNote> 
+        [SecurityCritical]
+        public override bool Equals(object o)
+        {
+            CheckInitialized(); 
+            GlyphTypeface t = o as GlyphTypeface;
+            if (t == null) 
+                return false; 
+
+            return StyleSimulations == t.StyleSimulations 
+                && _originalUri.Value == t._originalUri.Value;
+        }
+
+        /// <summary> 
+        /// Returns a geometry describing the path for a single glyph in the font.
+        /// The path represents the glyph 
+        /// without grid fitting applied for rendering at a specific resolution. 
+        /// </summary>
+        /// <param name="glyphIndex">Index of the glyph to get outline for.</param> 
+        /// <param name="renderingEmSize">Font size in drawing surface units.</param>
+        /// <param name="hintingEmSize">Size to hint for in points.</param>
+        [CLSCompliant(false)] 
+        public Geometry GetGlyphOutline(ushort glyphIndex, double renderingEmSize, double hintingEmSize)
+        { 
+            CheckInitialized(); // This can only be called on fully initialized GlyphTypeface 
+            return ComputeGlyphOutline(glyphIndex, false, renderingEmSize, hintingEmSize);
+        } 
+
+        /// <summary>
+        /// Returns the binary image of font subset.
+        /// </summary> 
+        /// <param name="glyphs">Collection of glyph indices to be included into the subset.</param>
+        /// <returns>Binary image of font subset.</returns> 
+        /// <remarks> 
+        ///     Callers must have UnmanagedCode permission to call this API.
+        ///     Callers must have FileIOPermission or WebPermission to font location to call this API. 
+        /// </remarks>
+        /// <SecurityNote>
+        ///     Critical - returns raw font data.
+        ///     Safe - (1) unmanaged code demand.  This ensures PT callers can't directly access the TrueType subsetter in V1. 
+        ///            (2) fileIO or web permission demand for location of font.  This ensures that even brokered access
+        ///                    via print dialog (which asserts unmanaged code) only succeeds if user has access to font source location. 
+        /// </SecurityNote> 
+        [SecurityCritical]
+        [CLSCompliant(false)] 
+        public byte[] ComputeSubset(ICollection<ushort> glyphs)
+        {
+            SecurityHelper.DemandUnmanagedCode();
+            DemandPermissionsForFontInformation(); 
+            CheckInitialized(); // This can only be called on fully initialized GlyphTypeface
+ 
+            if (glyphs == null) 
+                throw new ArgumentNullException("glyphs");
+ 
+            if (glyphs.Count <= 0)
+                throw new ArgumentException(SR.Get(SRID.CollectionNumberOfElementsMustBeGreaterThanZero), "glyphs");
+
+            if (glyphs.Count > ushort.MaxValue) 
+                throw new ArgumentException(SR.Get(SRID.CollectionNumberOfElementsMustBeLessOrEqualTo, ushort.MaxValue), "glyphs");
+ 
+            UnmanagedMemoryStream pinnedFontSource = FontSource.GetUnmanagedStream(); 
+
+            try 
+            {
+                TrueTypeFontDriver trueTypeDriver = new TrueTypeFontDriver(pinnedFontSource, _originalUri.Value);
+                trueTypeDriver.SetFace(FaceIndex);
+ 
+                return trueTypeDriver.ComputeFontSubset(glyphs);
+            } 
+            catch (SEHException e) 
+            {
+                throw Util.ConvertInPageException(FontSource, e); 
+            }
+            finally
+            {
+                pinnedFontSource.Close(); 
+            }
+        } 
+ 
+        /// <summary>
+        /// Returns a font file stream represented by this GlyphTypeface. 
+        /// </summary>
+        /// <returns>A font file stream represented by this GlyphTypeface.</returns>
+        /// <SecurityNote>
+        ///     Critical - returns raw font data. 
+        ///     Safe - does a demand before it gives out the information asked.
+        /// </SecurityNote> 
+        [SecurityCritical] 
+        public Stream GetFontStream()
+        { 
+            CheckInitialized(); // This can only be called on fully initialized GlyphTypeface
+            DemandPermissionsForFontInformation();
+            return FontSource.GetStream();
+        } 
+
+        /// <summary> 
+        /// Exposed to allow printing code to access GetFontStream() in partial trust 
+        /// </summary>
+        /// <SecurityNote> 
+        ///     Critical - returns a permission allowing access to GetFontStream in partial trust.
+        ///                Caller must make sure there is no font data leak
+        /// </SecurityNote>
+        [FriendAccessAllowed] 
+        internal CodeAccessPermission CriticalFileReadPermission
+        { 
+            [SecurityCritical] 
+            get
+            { 
+                CheckInitialized();
+                return _fileIOPermObj.Value;
+            }
+        } 
+
+        /// <summary> 
+        /// Exposed to allow printing code to access FontUri in partial trust 
+        /// </summary>
+        /// <SecurityNote> 
+        ///     Critical - returns a permission allowing access to FontUri
+        ///                Caller must make sure there is no data leak
+        /// </SecurityNote>
+        [FriendAccessAllowed] 
+        internal CodeAccessPermission CriticalUriDiscoveryPermission
+        { 
+            [SecurityCritical] 
+            get
+            { 
+                CheckInitialized();
+                return SecurityHelper.CreateUriDiscoveryPermission(_originalUri.Value);
+            }
+        } 
+
+    #endregion Public Methods 
+ 
+        //------------------------------------------------------
+        // 
+        //  Public Properties
+        //
+        //------------------------------------------------------
+ 
+    #region Public Properties
+ 
+        /// <summary> 
+        /// Returns the original Uri of this glyph typeface object.
+        /// </summary> 
+        /// <value>The Uri glyph typeface was constructed with.</value>
+        /// <remarks>
+        ///     Callers must have FileIOPermission(FileIOPermissionAccess.PathDiscovery) for the given Uri to call this API.
+        /// </remarks> 
+        /// <SecurityNote>
+        /// Critical - as this obtains Uri that can reveal local file system information. 
+        /// Safe - as this does a discovery demand before it gives out the information asked. 
+        /// </SecurityNote>
+        public Uri FontUri 
+        {
+            [SecurityCritical]
+            get
+            { 
+                CheckInitialized(); // This can only be called on fully initialized GlyphTypeface
+                SecurityHelper.DemandUriDiscoveryPermission(_originalUri.Value); 
+                return _originalUri.Value; 
+            }
+            [SecurityCritical] 
+            set
+            {
+                CheckInitializing(); // This can only be called in initialization
+ 
+                if (value == null)
+                    throw new ArgumentNullException("value"); 
+ 
+                if (!value.IsAbsoluteUri)
+                    throw new ArgumentException(SR.Get(SRID.UriNotAbsolute), "value"); 
+
+                _originalUri = new SecurityCriticalDataClass<Uri>(value);
+            }
+        } 
+
+        /// <summary> 
+        /// This property is indexed by a Culture Identifier. 
+        /// It returns the family name in the specified language, or,
+        /// if the font does not provide a name for the specified language, 
+        /// it returns the family name in English.
+        /// The family name excludes weight, style and stretch.
+        /// </summary>
+        public IDictionary<CultureInfo,string> FamilyNames 
+        {
+            get 
+            { 
+                CheckInitialized(); // This can only be called on fully initialized GlyphTypeface
+                return _fontFace.GetFamilyNameDictionary(); 
+            }
+        }
+
+        /// <summary> 
+        /// This property is indexed by a Culture Identifier.
+        /// It returns the face name in the specified language, or, 
+        /// if the font does not provide a name for the specified language, 
+        /// it returns the face name in English.
+        /// The face name may identify weight, style and/or stretch. 
+        /// </summary>
+        public IDictionary<CultureInfo, string> FaceNames
+        {
+            get 
+            {
+                CheckInitialized(); // This can only be called on fully initialized GlyphTypeface 
+                return _fontFace.GetFaceNameDictionary(); 
+            }
+        } 
+
+        /// <summary>
+        /// This property is indexed by a Culture Identifier.
+        /// It returns the family name in the specified language, or, 
+        /// if the font does not provide a name for the specified language,
+        /// it returns the family name in English. 
+        /// The Win32FamilyName name excludes regular or bold weights and style, 
+        /// but includes other weights and stretch.
+        /// </summary> 
+        public IDictionary<CultureInfo, string> Win32FamilyNames
+        {
+            get
+            { 
+                CheckInitialized(); // This can only be called on fully initialized GlyphTypeface
+                return _fontFace.GetWin32FamilyNameDictionary(); 
+            } 
+        }
+ 
+        /// <summary>
+        /// This property is indexed by a Culture Identifier.
+        /// It returns the face name in the specified language, or,
+        /// if the font does not provide a name for the specified language, 
+        /// it returns the face name in English.
+        /// The face name may identify weight, style and/or stretch. 
+        /// </summary> 
+        IDictionary<XmlLanguage, string> ITypefaceMetrics.AdjustedFaceNames
+        { 
+            get
+            {
+                CheckInitialized(); // This can only be called on fully initialized GlyphTypeface
+                IDictionary<CultureInfo, string> adjustedFaceNames = _fontFace.GetAdjustedFaceNameDictionary(); 
+                IDictionary<XmlLanguage, string> adjustedLanguageFaceNames = new Dictionary<XmlLanguage, string>(adjustedFaceNames.Count);
+ 
+                foreach (KeyValuePair<CultureInfo, string> pair in adjustedFaceNames) 
+                {
+                    adjustedLanguageFaceNames[XmlLanguage.GetLanguage(pair.Key.IetfLanguageTag)] = pair.Value; 
+                }
+
+                if (_styleSimulations != StyleSimulations.None)
+                { 
+                    adjustedLanguageFaceNames = FontDifferentiator.AppendSimulationsToFaceNames(adjustedLanguageFaceNames, _styleSimulations);
+                } 
+                return adjustedLanguageFaceNames; 
+            }
+        } 
+
+        /// <summary>
+        /// This property is indexed by a Culture Identifier.
+        /// It returns the face name in the specified language, or, 
+        /// if the font does not provide a name for the specified language,
+        /// it returns the face name in English. 
+        /// The Win32Face name may identify weights other than regular or bold and/or style, 
+        /// but may not identify stretch or other weights.
+        /// </summary> 
+        public IDictionary<CultureInfo, string> Win32FaceNames
+        {
+            get
+            { 
+                CheckInitialized(); // This can only be called on fully initialized GlyphTypeface
+                return _fontFace.GetWin32FaceNameDictionary(); 
+            } 
+        }
+ 
+        /// <summary>
+        /// This property is indexed by a Culture Identifier.
+        /// Version string in the fonts NAME table.
+        /// Version strings vary significantly in format - to obtain the version 
+        /// as a numeric value use the 'Version' property,
+        /// do not attempt to parse the VersionString. 
+        /// </summary> 
+        /// <SecurityNote>
+        /// Critical - as this accesses _fontFace which can reveal Windows font information. 
+        /// Safe - as this does a demand before it gives out the information asked.
+        /// </SecurityNote>
+        public IDictionary<CultureInfo, string> VersionStrings
+        { 
+            [SecurityCritical]
+            get 
+            { 
+                CheckInitialized(); // This can only be called on fully initialized GlyphTypeface
+                DemandPermissionsForFontInformation(); 
+                return _fontFace.GetVersionStringDictionary();
+            }
+        }
+ 
+        /// <summary>
+        /// This property is indexed by a Culture Identifier. 
+        /// Copyright notice. 
+        /// </summary>
+        /// <SecurityNote> 
+        /// Critical - as this accesses _fontFace which can reveal Windows font information.
+        /// Safe - as this does a demand before it gives out the information asked.
+        /// </SecurityNote>
+        public IDictionary<CultureInfo, string> Copyrights 
+        {
+            [SecurityCritical] 
+            get 
+            {
+                CheckInitialized(); // This can only be called on fully initialized GlyphTypeface 
+                DemandPermissionsForFontInformation();
+                return _fontFace.GetCopyrightDictionary();
+            }
+        } 
+
+        /// <summary> 
+        /// This property is indexed by a Culture Identifier. 
+        /// Manufacturer Name.
+        /// </summary> 
+        /// <SecurityNote>
+        /// Critical - as this accesses _fontFace which can reveal Windows font information.
+        /// Safe - as this does a demand before it gives out the information asked.
+        /// </SecurityNote> 
+        public IDictionary<CultureInfo, string> ManufacturerNames
+        { 
+            [SecurityCritical] 
+            get
+            { 
+                CheckInitialized(); // This can only be called on fully initialized GlyphTypeface
+                DemandPermissionsForFontInformation();
+                return _fontFace.GetManufacturerNameDictionary();
+            } 
+        }
+ 
+        /// <summary> 
+        /// This property is indexed by a Culture Identifier.
+        /// This is used to save any trademark notice/information for this font. 
+        /// Such information should be based on legal advice.
+        /// This is distinctly separate from the copyright.
+        /// </summary>
+        /// <SecurityNote> 
+        /// Critical - as this accesses _fontFace which can reveal Windows font information.
+        /// Safe - as this does a demand before it gives out the information asked. 
+        /// </SecurityNote> 
+        public IDictionary<CultureInfo, string> Trademarks
+        { 
+            [SecurityCritical]
+            get
+            {
+                CheckInitialized(); // This can only be called on fully initialized GlyphTypeface 
+                DemandPermissionsForFontInformation();
+                return _fontFace.GetTrademarkDictionary(); 
+            } 
+        }
+ 
+        /// <summary>
+        /// This property is indexed by a Culture Identifier.
+        /// Name of the designer of the typeface.
+        /// </summary> 
+        /// <SecurityNote>
+        /// Critical - as this accesses _fontFace which can reveal Windows font information. 
+        /// Safe - as this does a demand before it gives out the information asked. 
+        /// </SecurityNote>
+        public IDictionary<CultureInfo, string> DesignerNames 
+        {
+            [SecurityCritical]
+            get
+            { 
+                CheckInitialized(); // This can only be called on fully initialized GlyphTypeface
+                DemandPermissionsForFontInformation(); 
+                return _fontFace.GetDesignerNameDictionary(); 
+            }
+        } 
+
+        /// <summary>
+        /// This property is indexed by a Culture Identifier.
+        /// Description of the typeface. Can contain revision information, 
+        /// usage recommendations, history, features, etc.
+        /// </summary> 
+        /// <SecurityNote> 
+        /// Critical - as this accesses _fontFace which can reveal Windows font information.
+        /// Safe - as this does a demand before it gives out the information asked. 
+        /// </SecurityNote>
+        public IDictionary<CultureInfo, string> Descriptions
+        {
+            [SecurityCritical] 
+            get
+            { 
+                CheckInitialized(); // This can only be called on fully initialized GlyphTypeface 
+                DemandPermissionsForFontInformation();
+                return _fontFace.GetDescriptionDictionary(); 
+            }
+        }
+
+        /// <summary> 
+        /// This property is indexed by a Culture Identifier.
+        /// URL of font vendor (with protocol, e.g., `http://, `ftp://). 
+        /// If a unique serial number is embedded in the URL, 
+        /// it can be used to register the font.
+        /// </summary> 
+        /// <SecurityNote>
+        /// Critical - as this accesses _fontFace which can reveal Windows font information.
+        /// Safe - as this does a demand before it gives out the information asked.
+        /// </SecurityNote> 
+        public IDictionary<CultureInfo, string> VendorUrls
+        { 
+            [SecurityCritical] 
+            get
+            { 
+                CheckInitialized(); // This can only be called on fully initialized GlyphTypeface
+                DemandPermissionsForFontInformation();
+                return _fontFace.GetVendorUrlDictionary();
+            } 
+        }
+ 
+        /// <summary> 
+        /// This property is indexed by a Culture Identifier.
+        /// URL of typeface designer (with protocol, e.g., `http://, `ftp://). 
+        /// </summary>
+        /// <SecurityNote>
+        /// Critical - as this accesses _fontFace which can reveal Windows font information.
+        /// Safe - as this does a demand before it gives out the information asked. 
+        /// </SecurityNote>
+        public IDictionary<CultureInfo, string> DesignerUrls 
+        { 
+            [SecurityCritical]
+            get 
+            {
+                CheckInitialized(); // This can only be called on fully initialized GlyphTypeface
+                DemandPermissionsForFontInformation();
+                return _fontFace.GetDesignerUrlDictionary(); 
+            }
+        } 
+ 
+        /// <summary>
+        /// This property is indexed by a Culture Identifier. 
+        /// Description of how the font may be legally used,
+        /// or different example scenarios for licensed use.
+        /// This field should be written in plain language, not legalese.
+        /// </summary> 
+        /// <SecurityNote>
+        /// Critical - as this accesses _fontFace which can reveal Windows font information. 
+        /// Safe - as this does a demand before it gives out the information asked. 
+        /// </SecurityNote>
+        public IDictionary<CultureInfo, string> LicenseDescriptions 
+        {
+            [SecurityCritical]
+            get
+            { 
+                CheckInitialized(); // This can only be called on fully initialized GlyphTypeface
+                DemandPermissionsForFontInformation(); 
+                return _fontFace.GetLicenseDescriptionDictionary(); 
+            }
+        } 
+
+        /// <summary>
+        /// This property is indexed by a Culture Identifier.
+        /// This can be the font name, or any other text that the designer 
+        /// thinks is the best sample to display the font in.
+        /// </summary> 
+        /// <SecurityNote> 
+        /// Critical - as this accesses _fontFace which can reveal Windows font information.
+        /// Safe - as this does a demand before it gives out the information asked. 
+        /// </SecurityNote>
+        public IDictionary<CultureInfo, string> SampleTexts
+        {
+            [SecurityCritical] 
+            get
+            { 
+                CheckInitialized(); // This can only be called on fully initialized GlyphTypeface 
+                DemandPermissionsForFontInformation();
+                return _fontFace.GetSampleTextDictionary(); 
+            }
+        }
+
+        /// <summary> 
+        /// Returns designed style (regular/italic/oblique) of this font face
+        /// </summary> 
+        /// <value>Designed style of this font face.</value> 
+        public FontStyle Style
+        { 
+            get
+            {
+                CheckInitialized(); // This can only be called on fully initialized GlyphTypeface
+                return _fontFace.Style; 
+            }
+        } 
+ 
+        /// <summary>
+        /// Returns designed weight of this font face. 
+        /// </summary>
+        /// <value>Designed weight of this font face.</value>
+        public FontWeight Weight
+        { 
+            get
+            { 
+                CheckInitialized(); // This can only be called on fully initialized GlyphTypeface 
+                return _fontFace.Weight;
+            } 
+        }
+
+        /// <summary>
+        /// Returns designed stretch of this font face. 
+        /// </summary>
+        /// <value>Designed stretch of this font face.</value> 
+        public FontStretch Stretch 
+        {
+            get 
+            {
+                CheckInitialized(); // This can only be called on fully initialized GlyphTypeface
+                return _fontFace.Stretch;
+            } 
+        }
+ 
+        /// <summary> 
+        /// Font face version interpreted from the font's 'NAME' table.
+        /// </summary> 
+        /// <SecurityNote>
+        /// Critical - as this accesses _fontFace which can reveal Windows font information.
+        /// Safe - as this does a demand before it gives out the information asked.
+        /// </SecurityNote> 
+        public double Version
+        { 
+            [SecurityCritical] 
+            get
+            { 
+                CheckInitialized(); // This can only be called on fully initialized GlyphTypeface
+                DemandPermissionsForFontInformation();
+                return _fontFace.Version;
+            } 
+        }
+ 
+        /// <summary> 
+        /// Height of character cell relative to em size.
+        /// </summary> 
+        public double Height
+        {
+            get
+            { 
+                CheckInitialized(); // This can only be called on fully initialized GlyphTypeface
+                return (double)(_fontFace.DesignCellAscent + _fontFace.DesignCellDescent) / DesignEmHeight; 
+            } 
+        }
+ 
+        /// <summary>
+        /// Distance from cell top to English baseline relative to em size.
+        /// </summary>
+        public double Baseline 
+        {
+            get 
+            { 
+                CheckInitialized(); // This can only be called on fully initialized GlyphTypeface
+                return (double)_fontFace.DesignCellAscent / DesignEmHeight; 
+            }
+        }
+
+        /// <summary> 
+        /// Distance from baseline to top of English capital, relative to em size.
+        /// </summary> 
+        public double CapsHeight 
+        {
+            get 
+            {
+                CheckInitialized(); // This can only be called on fully initialized GlyphTypeface
+                return (double)_fontFace.CapsHeight / DesignEmHeight;
+            } 
+        }
+ 
+        /// <summary> 
+        /// Western x-height relative to em size.
+        /// </summary> 
+        public double XHeight
+        {
+            get
+            { 
+                CheckInitialized(); // This can only be called on fully initialized GlyphTypeface
+                return (double)_fontFace.xHeight / DesignEmHeight; 
+            } 
+        }
+ 
+        /// <summary>
+        /// Returns true if this font does not conform to Unicode encoding:
+        /// it may be considered as a simple collection of symbols indexed by a codepoint.
+        /// </summary> 
+        public bool Symbol
+        { 
+            get 
+            {
+                CheckInitialized(); // This can only be called on fully initialized GlyphTypeface 
+                return _fontFace.Symbol;
+            }
+        }
+ 
+        /// <summary>
+        /// Position of underline relative to baseline relative to em size. 
+        /// The value is usually negative, to place the underline below the baseline. 
+        /// </summary>
+        public double UnderlinePosition 
+        {
+            get
+            {
+                CheckInitialized(); // This can only be called on fully initialized GlyphTypeface 
+                return (double)_fontFace.UnderlinePosition / DesignEmHeight;
+            } 
+        } 
+
+        /// <summary> 
+        /// Thickness of underline relative to em size.
+        /// </summary>
+        public double UnderlineThickness
+        { 
+            get
+            { 
+                CheckInitialized(); // This can only be called on fully initialized GlyphTypeface 
+                return (double)_fontFace.UnderlineThickness / DesignEmHeight;
+            } 
+        }
+
+        /// <summary>
+        /// Position of strikeThrough relative to baseline relative to em size. 
+        /// The value is usually positive, to place the Strikethrough above the baseline.
+        /// </summary> 
+        public double StrikethroughPosition 
+        {
+            get 
+            {
+                CheckInitialized(); // This can only be called on fully initialized GlyphTypeface
+                return (double)_fontFace.StrikethroughPosition / DesignEmHeight;
+            } 
+        }
+ 
+        /// <summary> 
+        /// Thickness of Strikethrough relative to em size.
+        /// </summary> 
+        public double StrikethroughThickness
+        {
+            get
+            { 
+                CheckInitialized(); // This can only be called on fully initialized GlyphTypeface
+                return (double)_fontFace.StrikethroughThickness / DesignEmHeight; 
+            } 
+        }
+ 
+        /// <summary>
+        /// EmbeddingRights property describes font embedding permissions
+        /// specified in this glyph typeface.
+        /// </summary> 
+        /// <SecurityNote>
+        /// Critical - as this accesses _fontFace which can reveal Windows font information. 
+        /// Safe - as this does a demand before it gives out the information asked. 
+        /// </SecurityNote>
+        public FontEmbeddingRight EmbeddingRights 
+        {
+            [SecurityCritical]
+            get
+            { 
+                CheckInitialized(); // This can only be called on fully initialized GlyphTypeface
+                DemandPermissionsForFontInformation(); 
+                return _fontFace.EmbeddingRights; 
+            }
+        } 
+
+    #region ITypefaceMetrics implementation
+
+        /// <summary> 
+        /// Distance from baseline to top of English capital, relative to em size.
+        /// </summary> 
+        double ITypefaceMetrics.CapsHeight 
+        {
+            get 
+            {
+                return CapsHeight;
+            }
+        } 
+
+        /// <summary> 
+        /// Western x-height relative to em size. 
+        /// </summary>
+        double ITypefaceMetrics.XHeight 
+        {
+            get
+            {
+                return XHeight; 
+            }
+        } 
+ 
+        /// <summary>
+        /// Returns true if this font does not conform to Unicode encoding: 
+        /// it may be considered as a simple collection of symbols indexed by a codepoint.
+        /// </summary>
+        bool ITypefaceMetrics.Symbol
+        { 
+            get
+            { 
+                return Symbol; 
+            }
+        } 
+
+        /// <summary>
+        /// Position of underline relative to baseline relative to em size.
+        /// The value is usually negative, to place the underline below the baseline. 
+        /// </summary>
+        double ITypefaceMetrics.UnderlinePosition 
+        { 
+            get
+            { 
+                return UnderlinePosition;
+            }
+        }
+ 
+        /// <summary>
+        /// Thickness of underline relative to em size. 
+        /// </summary> 
+        double ITypefaceMetrics.UnderlineThickness
+        { 
+            get
+            {
+                return UnderlineThickness;
+            } 
+        }
+ 
+        /// <summary> 
+        /// Position of strikeThrough relative to baseline relative to em size.
+        /// The value is usually positive, to place the Strikethrough above the baseline. 
+        /// </summary>
+        double ITypefaceMetrics.StrikethroughPosition
+        {
+            get 
+            {
+                return StrikethroughPosition; 
+            } 
+        }
+ 
+        /// <summary>
+        /// Thickness of Strikethrough relative to em size.
+        /// </summary>
+        double ITypefaceMetrics.StrikethroughThickness 
+        {
+            get 
+            { 
+                return StrikethroughThickness;
+            } 
+        }
+
+    #endregion
+ 
+
+        // The next several properties return non CLS-compliant types.  This is 
+        // tracked by bug 1792236.  For now, suppress the compiler warning. 
+        //
+#pragma warning disable 3003 
+
+        /// <summary>
+        /// Returns advance width for a given glyph.
+        /// </summary> 
+        public IDictionary<ushort, double> AdvanceWidths
+        { 
+            get 
+            {
+                CheckInitialized(); // This can only be called on fully initialized GlyphTypeface 
+                return new GlyphIndexer(this.GetAdvanceWidth, _fontFace.GlyphCount);
+            }
+        }
+ 
+        /// <summary>
+        /// Returns Advance height for a given glyph (Used for example in vertical layout). 
+        /// </summary> 
+        public IDictionary<ushort, double> AdvanceHeights
+        { 
+            get
+            {
+                CheckInitialized(); // This can only be called on fully initialized GlyphTypeface
+                return new GlyphIndexer(this.GetAdvanceHeight, _fontFace.GlyphCount); 
+            }
+        } 
+ 
+        /// <summary>
+        /// Distance from leading end of advance vector to left edge of black box. 
+        /// Positive when left edge of black box is within the alignment rectangle
+        /// defined by the advance width and font cell height.
+        /// Negative when left edge of black box overhangs the alignment rectangle.
+        /// </summary> 
+        public IDictionary<ushort, double> LeftSideBearings
+        { 
+            get 
+            {
+                CheckInitialized(); // This can only be called on fully initialized GlyphTypeface 
+                return new GlyphIndexer(this.GetLeftSidebearing, _fontFace.GlyphCount);
+            }
+        }
+ 
+        /// <summary>
+        /// Distance from right edge of black box to right end of advance vector. 
+        /// Positive when trailing edge of black box is within the alignment rectangle 
+        /// defined by the advance width and font cell height.
+        /// Negative when right edge of black box overhangs the alignment rectangle. 
+        /// </summary>
+        public IDictionary<ushort, double> RightSideBearings
+        {
+            get 
+            {
+                CheckInitialized(); // This can only be called on fully initialized GlyphTypeface 
+                return new GlyphIndexer(this.GetRightSidebearing, _fontFace.GlyphCount); 
+            }
+        } 
+
+        /// <summary>
+        /// Distance from top end of (vertical) advance vector to top edge of black box.
+        /// Positive when top edge of black box is within the alignment rectangle 
+        /// defined by the advance height and font cell height.
+        /// (The font cell height is a horizontal dimension in vertical layout). 
+        /// Negative when top edge of black box overhangs the alignment rectangle. 
+        /// </summary>
+        public IDictionary<ushort, double> TopSideBearings 
+        {
+            get
+            {
+                CheckInitialized(); // This can only be called on fully initialized GlyphTypeface 
+                return new GlyphIndexer(this.GetTopSidebearing, _fontFace.GlyphCount);
+            } 
+        } 
+
+        /// <summary> 
+        /// Distance from bottom edge of black box to bottom end of advance vector.
+        /// Positive when bottom edge of black box is within the alignment rectangle
+        /// defined by the advance width and font cell height.
+        /// (The font cell height is a horizontal dimension in vertical layout). 
+        /// Negative when bottom edge of black box overhangs the alignment rectangle.
+        /// </summary> 
+        public IDictionary<ushort, double> BottomSideBearings 
+        {
+            get 
+            {
+                CheckInitialized(); // This can only be called on fully initialized GlyphTypeface
+                return new GlyphIndexer(this.GetBottomSidebearing, _fontFace.GlyphCount);
+            } 
+        }
+ 
+        /// <summary> 
+        /// Offset down from horizontal Western baseline to bottom  of glyph black box.
+        /// </summary> 
+        public IDictionary<ushort, double> DistancesFromHorizontalBaselineToBlackBoxBottom
+        {
+            get
+            { 
+                CheckInitialized(); // This can only be called on fully initialized GlyphTypeface
+                return new GlyphIndexer(this.GetBaseline, _fontFace.GlyphCount); 
+            } 
+        }
+ 
+        /// <summary>
+        /// Returns nominal mapping of Unicode codepoint to glyph index as defined by the font 'CMAP' table.
+        /// </summary>
+        /// <SecurityNote> 
+        ///   Critical: May potentially leak a writeable cmap.
+        ///   Safe: The cmap IDictionary exposure is read only. 
+        ///  </SecurityNote> 
+        public IDictionary<int, ushort> CharacterToGlyphMap
+        { 
+            [SecurityCritical]
+            get
+            {
+                CheckInitialized(); // This can only be called on fully initialized GlyphTypeface 
+                return _fontFace.CharacterMap;
+            } 
+        } 
+
+#pragma warning restore 3003 
+
+        /// <summary>
+        /// Returns algorithmic font style simulations to be applied to the GlyphTypeface.
+        /// </summary> 
+        public StyleSimulations StyleSimulations
+        { 
+            get 
+            {
+                CheckInitialized(); // This can only be called on fully initialized GlyphTypeface 
+                return _styleSimulations;
+            }
+            set
+            { 
+                CheckInitializing();
+                _styleSimulations = value; 
+            } 
+        }
+ 
+        /// <summary>
+        /// Obtains the number of glyphs in the glyph typeface.
+        /// </summary>
+        /// <value>The number of glyphs in the glyph typeface.</value> 
+        public int GlyphCount
+        { 
+            get 
+            {
+                CheckInitialized(); // This can only be called on fully initialized GlyphTypeface 
+                return _fontFace.GlyphCount;
+            }
+        }
+ 
+    #endregion Public Properties
+ 
+        //----------------------------------------------------- 
+        //
+        //  Internal Methods 
+        //
+        //------------------------------------------------------
+
+    #region Internal Methods 
+
+        /// <summary> 
+        /// Returns the nominal advance width for a glyph. 
+        /// </summary>
+        /// <param name="glyph">Glyph index in the font.</param> 
+        /// <returns>The nominal advance width for the glyph relative to the em size of the font.</returns>
+        /// <SecurityNote>
+        /// Critical - as this has unsafe block.
+        /// Safe - as this only gives width information which is safe to give out. 
+        /// </SecurityNote>
+        [SecurityCritical, SecurityTreatAsSafe] 
+        internal double GetAdvanceWidth(ushort glyph) 
+        {
+            CheckInitialized(); // This can only be called on fully initialized GlyphTypeface 
+
+            // We manually expand GetGlyphMetrics call because GetAdvanceWidth is a very frequently used function.
+            // When we get to using GetAdvanceHeight for vertical writing, we need to consider doing the same optimization there.
+            unsafe 
+            {
+                FontFaceLayoutInfo.GlyphMetrics * cachedGlyphMetrics = _fontFace.Metrics(glyph); 
+ 
+                double aw = (double)cachedGlyphMetrics->advanceWidth / DesignEmHeight;
+ 
+                if ((_styleSimulations & StyleSimulations.BoldSimulation) != 0)
+                {
+                    // Bold simulation increases advance width and advance height by 2% of em size,
+                    // except for glyphs that are empty or have zero advance widths. 
+                    // So, we compensate for the simulation when aw != 0 && left < right && ah != 0 && bottom > top
+                    if (cachedGlyphMetrics->advanceWidth != 0 && 
+                        cachedGlyphMetrics->lsb < cachedGlyphMetrics->advanceWidth - cachedGlyphMetrics->rsb && 
+                        cachedGlyphMetrics->advanceHeight != 0 &&
+                        cachedGlyphMetrics->advanceHeight - cachedGlyphMetrics->tsb - cachedGlyphMetrics->bsb > 0) 
+                    {
+                        aw += 0.02;
+                    }
+                } 
+                return aw;
+            } 
+        } 
+
+        /// <summary> 
+        /// Returns the nominal advance width for a glyph in font design units.
+        /// </summary>
+        /// <param name="glyph">Glyph index in the font.</param>
+        /// <returns>The nominal advance width for the glyph in font design units.</returns> 
+        internal double GetAdvanceWidthInDesignUnits(ushort glyph)
+        { 
+            return GetAdvanceWidth(glyph) * DesignEmHeight; 
+        }
+ 
+
+        /// <SecurityNote>
+        /// This function will demand appropriate permissions depending on what
+        /// the source of the font information is.  The value of _fileIOPermObj 
+        /// is set correctly whenever _originalUri gets set.
+        /// </SecurityNote> 
+        internal void DemandPermissionsForFontInformation() 
+        {
+            if (_fileIOPermObj.Value != null) 
+            {
+                _fileIOPermObj.Value.Demand();
+            }
+        } 
+
+        private double GetAdvanceHeight(ushort glyph) 
+        { 
+            double aw, ah, lsb, rsb, tsb, bsb, baseline;
+            GetGlyphMetrics( 
+                glyph,
+                1.0,
+                out aw,
+                out ah, 
+                out lsb,
+                out rsb, 
+                out tsb, 
+                out bsb,
+                out baseline 
+            );
+            return ah;
+        }
+ 
+        private double GetLeftSidebearing(ushort glyph)
+        { 
+            return (double)_fontFace.GetLeftSidebearing(glyph) / DesignEmHeight; 
+        }
+ 
+        private double GetRightSidebearing(ushort glyph)
+        {
+            return (double)_fontFace.GetRightSidebearing(glyph) / DesignEmHeight;
+        } 
+
+        private double GetTopSidebearing(ushort glyph) 
+        { 
+            return (double)_fontFace.GetTopSidebearing(glyph) / DesignEmHeight;
+        } 
+
+        private double GetBottomSidebearing(ushort glyph)
+        {
+            return (double)_fontFace.GetBottomSidebearing(glyph) / DesignEmHeight; 
+        }
+ 
+        private double GetBaseline(ushort glyph) 
+        {
+            return (double)_fontFace.GetBaseline(glyph) / DesignEmHeight; 
+        }
+
+        /// <summary>
+        /// Optimized version of obtaining all of glyph metrics from font cache at once 
+        /// without repeated checks and divisions.
+        /// </summary> 
+        /// <SecurityNote> 
+        /// Critical - as this uses unsafe code.
+        /// Safe - as this only gives information which is safe to give out. 
+        /// </SecurityNote>
+        [SecurityCritical, SecurityTreatAsSafe]
+        internal void GetGlyphMetrics(
+            ushort      glyph, 
+            double      renderingEmSize,
+            out double  aw, 
+            out double  ah, 
+            out double  lsb,
+            out double  rsb, 
+            out double  tsb,
+            out double  bsb,
+            out double  baseline
+            ) 
+        {
+            CheckInitialized(); // This can only be called on fully initialized GlyphTypeface 
+ 
+            unsafe
+            { 
+                FontFaceLayoutInfo.GlyphMetrics * cachedGlyphMetrics = _fontFace.Metrics(glyph);
+
+                double designToEm = renderingEmSize / DesignEmHeight;
+ 
+                aw = designToEm * cachedGlyphMetrics->advanceWidth;
+                ah = designToEm * cachedGlyphMetrics->advanceHeight; 
+                lsb = designToEm * cachedGlyphMetrics->lsb; 
+                rsb = designToEm * cachedGlyphMetrics->rsb;
+                tsb = designToEm * cachedGlyphMetrics->tsb; 
+                bsb = designToEm * cachedGlyphMetrics->bsb;
+                baseline = designToEm * cachedGlyphMetrics->baseline;
+
+                if ((_styleSimulations & StyleSimulations.BoldSimulation) != 0) 
+                {
+                    // Bold simulation increases advance width and advance height by 2% of em size, 
+                    // except for glyphs that are empty or have zero advance widths. 
+                    // So, we compensate for the simulation when aw != 0 && left < right && ah != 0 && bottom > top
+                    if (cachedGlyphMetrics->advanceWidth != 0 && 
+                        cachedGlyphMetrics->lsb < cachedGlyphMetrics->advanceWidth - cachedGlyphMetrics->rsb &&
+                        cachedGlyphMetrics->advanceHeight != 0 &&
+                        cachedGlyphMetrics->advanceHeight - cachedGlyphMetrics->tsb - cachedGlyphMetrics->bsb > 0)
+                    { 
+                        aw += 0.02 * renderingEmSize;
+                        ah += 0.02 * renderingEmSize; 
+                    } 
+                }
+            } 
+        }
+
+        /// <summary>
+        /// Returns a geometry describing the path for a single glyph in the font. 
+        /// The path represents the glyph
+        /// without grid fitting applied for rendering at a specific resolution. 
+        /// </summary> 
+        /// <param name="glyphIndex">Index of the glyph to get outline for.</param>
+        /// <param name="sideways">Specifies whether the glyph should be rotated sideways.</param> 
+        /// <param name="renderingEmSize">Font size in drawing surface units.</param>
+        /// <param name="hintingEmSize">Size to hint for in points.</param>
+        /// <returns>Geometry containing glyph outline.</returns>
+        /// <SecurityCritical> 
+        /// Critical - as this calls GetGlyphs() which is critical.
+        /// Safe - as this doesn't expose font information but just gives out a Geometry. 
+        /// </SecurityCritical> 
+        [SecurityCritical, SecurityTreatAsSafe]
+        internal Geometry ComputeGlyphOutline(ushort glyphIndex, bool sideways, double renderingEmSize, double hintingEmSize) 
+        {
+            CheckInitialized(); // This can only be called on fully initialized GlyphTypeface
+            using (GlyphPathElement pathElement = new GlyphPathElement(
+                _fontFace.FaceIndex, 
+                _fontFace.FontSource,
+                GetRenderingFlags(sideways), 
+                DesignEmHeight 
+            ))
+            { 
+                PathGeometry pathGeometry;
+                unsafe
+                {
+                    void*[] glyphOutlines = new void*[1]; 
+                    FontCacheAccessor fontCacheAccessor = new FontCacheAccessor();
+                    ushort[] glyphIndices = new ushort[1] { glyphIndex }; 
+                    fontCacheAccessor.GetGlyphs( 
+                        pathElement,
+                        glyphIndices, 
+                        glyphOutlines
+                    );
+
+                    void * outline = glyphOutlines[0]; 
+
+                    Debug.Assert(outline != null); 
+ 
+                    if (FontTechnology == FontTechnology.PostscriptOpenType)
+                        ConvertPostscriptOutline(outline, renderingEmSize, sideways, out pathGeometry); 
+                    else
+                        ConvertTrueTypeOutline(outline, renderingEmSize, sideways, out pathGeometry);
+
+                    // Make sure fontCacheAccessor doesn't go out of scope before the outlines get converted. 
+                    GC.KeepAlive(fontCacheAccessor);
+                } 
+ 
+                // Make sure to always return Geometry.Empty from public methods for empty geometries.
+                if (pathGeometry == null || pathGeometry.IsEmpty()) 
+                    return Geometry.Empty;
+                return pathGeometry;
+            }
+        } 
+
+        /// <SecurityNote> 
+        /// Critical - unsafe code, accepts pointer parameters, etc. 
+        /// </SecurityNote>
+        [SecurityCritical] 
+        private unsafe void ConvertTrueTypeOutline(void* trueTypeOutline, double renderingEmSize, bool sideways, out PathGeometry pathGeometry)
+        {
+            GlyphPathData * outline = (GlyphPathData *)trueTypeOutline;
+ 
+            // scale factor from design units to user coordinate system
+ 
+            double designToUserScale = renderingEmSize / DesignEmHeight; 
+            Matrix designToUser = new Matrix(designToUserScale, 0, 0, -designToUserScale, 0, 0);
+            if (sideways) 
+            {
+                designToUser.Rotate(-90.0);
+                designToUser.Translate(outline->verOriginY * designToUserScale, outline->verOriginX * designToUserScale);
+            } 
+
+            ushort* endp = GlyphPathData.EndPointNumbers(outline); 
+            short* x = GlyphPathData.X(outline); 
+            short* y = GlyphPathData.Y(outline);
+            byte* flags = GlyphPathData.Flags(outline); 
+
+            // k is the index of the first point of the current contour
+            int k = 0;
+ 
+            pathGeometry = null;
+ 
+            // j is the index of the current contour 
+            for (int j = 0; j < outline->numberOfContours; ++j)
+            { 
+                int lastPointIndex = endp[j];
+                if (lastPointIndex <= k)
+                {
+                    k = lastPointIndex + 1; 
+                    continue; //  empty contour
+                } 
+ 
+                Point startPoint;
+ 
+                PathFigure figure = new PathFigure();
+
+                // The first point on the curve
+                if (OnCurve(flags[k])) 
+                {
+                    // Easy case 
+                    startPoint = designToUser.Transform(new Point(x[k], y[k])); 
+                    ++k;
+                } 
+                else
+                {
+                    // Is last contour point on the curve
+                    if (OnCurve(flags[lastPointIndex])) 
+                    {
+                        // Make the last point the first point and decrement the last point 
+                        startPoint = designToUser.Transform(new Point(x[lastPointIndex], y[lastPointIndex])); 
+                        --lastPointIndex;
+                    } 
+                    else
+                    {
+                        // First and last point are off the countour, fake a mid point
+                        Point firstPoint = designToUser.Transform(new Point(x[k], y[k])); 
+                        Point lastPoint = designToUser.Transform(new Point(x[lastPointIndex], y[lastPointIndex]));
+                        startPoint = new Point( 
+                            (firstPoint.X + lastPoint.X) / 2, 
+                            (firstPoint.Y + lastPoint.Y) / 2
+                        ); 
+                    }
+                }
+
+                figure.StartPoint = startPoint; 
+
+                bool inBezier = false; 
+                Point bezierB = new Point(); 
+                while (k <= lastPointIndex)
+                { 
+                    Point currentPoint = designToUser.Transform(new Point(x[k], y[k]));
+
+                    if (OnCurve(flags[k]))
+                    { 
+                        if (!inBezier)
+                        { 
+                            figure.Segments.Add(new LineSegment(currentPoint, true)); 
+                        }
+                        else 
+                        {
+                            figure.Segments.Add(new QuadraticBezierSegment(bezierB, currentPoint, true));
+                            inBezier = false;
+                        } 
+                    }
+                    else 
+                    { 
+                        if (inBezier)
+                        { 
+                            figure.Segments.Add(new QuadraticBezierSegment(
+                                bezierB,
+                                new Point(
+                                    (bezierB.X + currentPoint.X) / 2, 
+                                    (bezierB.Y + currentPoint.Y) / 2
+                                ), 
+                                true) 
+                            );
+                        } 
+                        inBezier = true;
+                        bezierB = currentPoint;
+                    }
+                    ++k; 
+                }
+ 
+                // explicitly set k to the start point of the next contour 
+                // since in some cases lastPointIndex is not equal to endp[j]
+                k = endp[j] + 1; 
+
+                // close the figure, assume start point is always on curve
+                if (inBezier)
+                { 
+                    figure.Segments.Add(new QuadraticBezierSegment(bezierB, startPoint, true));
+                } 
+ 
+                figure.IsClosed = true;
+ 
+                if (pathGeometry == null)
+                {
+                    pathGeometry = new PathGeometry();
+                    pathGeometry.FillRule = FillRule.Nonzero; 
+                }
+ 
+                pathGeometry.Figures.Add(figure); 
+            }
+        } 
+
+        /// <SecurityNote>
+        /// Critical - unsafe code, accepts pointer parameters, etc.
+        /// </SecurityNote> 
+        [SecurityCritical]
+        private unsafe void ConvertPostscriptOutline(void * outline, double renderingEmSize, bool sideways, out PathGeometry pathGeometry) 
+        { 
+            int * postscriptOutline = (int *)outline;
+ 
+            // scale factor from design units to user coordinate system
+
+            double designToUserScale = renderingEmSize / DesignEmHeight;
+            Matrix designToUser = new Matrix(designToUserScale, 0, 0, -designToUserScale, 0, 0); 
+            if (sideways)
+            { 
+                int verOriginX = postscriptOutline[0]; 
+                int verOriginY = postscriptOutline[1];
+ 
+                designToUser.Rotate(-90.0);
+                designToUser.Translate(verOriginY * designToUserScale, verOriginX * designToUserScale);
+            }
+ 
+            // Skip vertical origin and length to get to the actual contour data.
+            int * p = postscriptOutline + 3; 
+            Debug.Assert(postscriptOutline[2] % sizeof(int) == 0); 
+            int * end = p + (postscriptOutline[2] / sizeof(int));
+ 
+            pathGeometry = null;
+
+            // Current figure.
+            PathFigure figure = null; 
+
+            for (;;) 
+            { 
+                if (p >= end)
+                    break; 
+
+                int tokenValue = *p;
+
+                switch ((OutlineTokenType)tokenValue) 
+                {
+                case OutlineTokenType.MoveTo: 
+                    { 
+                        ++p;
+                        if (p + 1 >= end) 
+                            throw new FileFormatException(_originalUri.Value);
+
+                        Point point = designToUser.Transform(
+                            new Point(p[0] * CFFConversionFactor, p[1] * CFFConversionFactor) 
+                            );
+ 
+                        if (figure == null) 
+                            figure = new PathFigure();
+ 
+                        figure.StartPoint = point;
+
+                        p += 2;
+                        break; 
+                    }
+ 
+                case OutlineTokenType.LineTo: 
+                    {
+                        ++p; 
+                        if (p + 1 >= end)
+                            throw new FileFormatException(_originalUri.Value);
+
+                        Point point = designToUser.Transform( 
+                            new Point(p[0] * CFFConversionFactor, p[1] * CFFConversionFactor)
+                            ); 
+ 
+                        if (figure == null)
+                            throw new FileFormatException(_originalUri.Value); 
+
+                        figure.Segments.Add(new LineSegment(point, true));
+
+                        p += 2; 
+                        break;
+                    } 
+ 
+                case OutlineTokenType.CurveTo:
+                    { 
+                        ++p;
+                        if (p + 5 >= end)
+                            throw new FileFormatException(_originalUri.Value);
+ 
+                        Point point0 = designToUser.Transform(
+                            new Point(p[0] * CFFConversionFactor, p[1] * CFFConversionFactor) 
+                            ); 
+                        Point point1 = designToUser.Transform(
+                            new Point(p[2] * CFFConversionFactor, p[3] * CFFConversionFactor) 
+                            );
+                        Point point2 = designToUser.Transform(
+                            new Point(p[4] * CFFConversionFactor, p[5] * CFFConversionFactor)
+                            ); 
+
+                        if (figure == null) 
+                            throw new FileFormatException(_originalUri.Value); 
+
+                        figure.Segments.Add(new BezierSegment(point0, point1, point2, true)); 
+                        p += 6;
+                        break;
+                    }
+ 
+                case OutlineTokenType.ClosePath:
+                    if (figure == null) 
+                        throw new FileFormatException(_originalUri.Value); 
+
+                    figure.IsClosed = true; 
+
+                    if (pathGeometry == null)
+                    {
+                        pathGeometry = new PathGeometry(); 
+                        pathGeometry.FillRule = FillRule.Nonzero;
+                    } 
+ 
+                    pathGeometry.Figures.Add(figure);
+                    figure = null; 
+                    ++p;
+                    break;
+
+                default: 
+                    throw new FileFormatException(_originalUri.Value);
+                } 
+            } 
+        }
+ 
+
+        /// <summary>
+        /// Get advance widths of unshaped characters
+        /// </summary> 
+        /// <param name="unsafeCharString">character string</param>
+        /// <param name="stringLength">character length</param> 
+        /// <param name="emSize">character em size</param> 
+        /// <param name="advanceWidthsUnshaped">unshaped advance widths </param>
+        /// <param name="nullFont">true if all characters map to missing glyph</param> 
+        /// <returns>array of character advance widths</returns>
+        /// <SecurityNote>
+        /// Critical - takes unsafe char string and returns information in an unsafe int array
+        /// </SecurityNote> 
+        [SecurityCritical]
+        internal unsafe void GetAdvanceWidthsUnshaped( 
+            char* unsafeCharString, 
+            int stringLength,
+            double emSize, 
+            int* advanceWidthsUnshaped,
+            bool nullFont
+            )
+        { 
+            CheckInitialized(); // This can only be called on fully initialized GlyphTypeface
+            Invariant.Assert(stringLength > 0); 
+ 
+            if (!nullFont)
+            { 
+                IDictionary<int, ushort> cmap = CharacterToGlyphMap;
+                for (int i = 0; i < stringLength; i++)
+                {
+                    ushort glyphIndex; 
+                    cmap.TryGetValue(unsafeCharString[i], out glyphIndex);
+                    advanceWidthsUnshaped[i] = (int)Math.Round(emSize * GetAdvanceWidth(glyphIndex)); 
+                } 
+            }
+            else 
+            {
+                int missingGlyphWidth = (int)Math.Round(emSize * GetAdvanceWidth(0));
+                for (int i = 0; i < stringLength; i++)
+                { 
+                    advanceWidthsUnshaped[i] = missingGlyphWidth;
+                } 
+            } 
+        }
+ 
+        /// <summary>
+        /// Compute an unshaped glyphrun object from specified character-based info
+        /// </summary>
+        internal GlyphRun ComputeUnshapedGlyphRun( 
+            Point origin,
+            CharacterBufferRange charBufferRange, 
+            IList<double> charWidths, 
+            double emSize,
+            double emHintingSize, 
+            bool nullGlyph,
+            CultureInfo cultureInfo,
+            string deviceFontName
+            ) 
+        {
+            Debug.Assert(charBufferRange.Length > 0); 
+ 
+            CheckInitialized(); // This can only be called on fully initialized GlyphTypeface
+ 
+            ushort[] nominalGlyphs = new ushort[charBufferRange.Length];
+
+
+            // compute glyph positions 
+
+            if (nullGlyph) 
+            { 
+                for (int i = 0; i < charBufferRange.Length; i++)
+                { 
+                    nominalGlyphs[i] = 0;
+                }
+            }
+            else 
+            {
+                IDictionary<int, ushort> cmap = CharacterToGlyphMap; 
+ 
+                for (int i = 0; i < charBufferRange.Length; i++)
+                { 
+                    ushort glyphIndex;
+                    cmap.TryGetValue(charBufferRange[i], out glyphIndex);
+                    nominalGlyphs[i] = glyphIndex;
+                } 
+            }
+ 
+            return GlyphRun.TryCreate( 
+                this,
+                0,      // bidiLevel 
+                false,  // sideway
+                emSize,
+                nominalGlyphs,
+                origin, 
+                charWidths,
+                null,   // glyphOffsets 
+                new PartialList<char>(charBufferRange.CharacterBuffer, charBufferRange.OffsetToFirstChar, charBufferRange.Length), 
+                deviceFontName,   // device font
+                null,   // 1:1 mapping 
+                null,   // caret stops at every codepoint
+                XmlLanguage.GetLanguage(cultureInfo.IetfLanguageTag)
+                );
+        } 
+
+ 
+    #endregion Internal Methods 
+
+        //----------------------------------------------------- 
+        //
+        //  Internal Properties
+        //
+        //----------------------------------------------------- 
+
+    #region Internal Properties 
+ 
+        internal FontSource FontSource
+        { 
+            get
+            {
+                CheckInitialized(); // This can only be called on fully initialized GlyphTypeface
+                return _fontFace.FontSource; 
+            }
+        } 
+ 
+        /// <summary>
+        /// 0 for TTF files 
+        /// Face index within TrueType font collection for TTC files
+        /// </summary>
+        internal int FaceIndex
+        { 
+            get
+            { 
+                CheckInitialized(); // This can only be called on fully initialized GlyphTypeface 
+                return _fontFace.FaceIndex;
+            } 
+        }
+
+        internal FontFaceLayoutInfo FontFaceLayoutInfo
+        { 
+            get
+            { 
+                CheckInitialized(); // This can only be called on fully initialized GlyphTypeface 
+                return _fontFace;
+            } 
+        }
+
+        internal ushort BlankGlyphIndex
+        { 
+            get
+            { 
+                CheckInitialized(); // This can only be called on fully initialized GlyphTypeface 
+                return _fontFace.BlankGlyph;
+            } 
+        }
+
+        internal FontFaceLayoutInfo.RenderingHints RenderingHints
+        { 
+            get
+            { 
+                CheckInitialized(); // This can only be called on fully initialized GlyphTypeface 
+                return _fontFace.FontRenderingHints;
+            } 
+        }
+
+        internal FontTechnology FontTechnology
+        { 
+            get
+            { 
+                CheckInitialized(); // This can only be called on fully initialized GlyphTypeface 
+                return _fontFace.FontTechnology;
+            } 
+        }
+
+        internal short FontContrastAdjustment
+        { 
+            get
+            { 
+                CheckInitialized(); // This can only be called on fully initialized GlyphTypeface 
+                Debug.Assert(-3 <= _fontFace.FontContrastAdjustment && _fontFace.FontContrastAdjustment <= 4);
+                return _fontFace.FontContrastAdjustment; 
+            }
+        }
+
+        internal ushort DesignEmHeight 
+        {
+            get 
+            { 
+                CheckInitialized(); // This can only be called on fully initialized GlyphTypeface
+                return _fontFace.DesignEmHeight; 
+            }
+        }
+
+    #endregion Internal Properties 
+
+        //----------------------------------------------------- 
+        // 
+        //  Private Methods
+        // 
+        //------------------------------------------------------
+
+    #region Private Methods
+ 
+        private static bool OnCurve(byte flag)
+        { 
+            return (flag & 0x01) != 0; 
+        }
+ 
+        private ushort GetRenderingFlags(bool sideways)
+        {
+            ushort renderingFlags = 0;
+            if ((_styleSimulations & StyleSimulations.BoldSimulation) != 0) 
+                renderingFlags |= (ushort)RenderingFlags.BoldSimulation;
+            if ((_styleSimulations & StyleSimulations.ItalicSimulation) != 0) 
+            { 
+                renderingFlags |= (ushort)RenderingFlags.ItalicSimulation;
+                if (sideways) 
+                    renderingFlags |= (ushort)RenderingFlags.SidewaysItalicSimulation;
+            }
+            if (FontTechnology != FontTechnology.PostscriptOpenType)
+                renderingFlags |= (ushort)MIL_GLYPHRUN_FLAGS.MilGlyphRunIsTrueType; 
+            return renderingFlags;
+        } 
+ 
+    #endregion Private Methods
+ 
+    #region ISupportInitialize interface
+
+        void ISupportInitialize.BeginInit()
+        { 
+            if (_initializationState == InitializationState.IsInitialized)
+            { 
+                // Cannont initialize a GlyphRun this is completely initialized. 
+                throw new InvalidOperationException(SR.Get(SRID.OnlyOneInitialization));
+            } 
+
+            if (_initializationState == InitializationState.IsInitializing)
+            {
+                // Cannot initialize a GlyphRun this already being initialized. 
+                throw new InvalidOperationException(SR.Get(SRID.InInitialization));
+            } 
+ 
+            _initializationState = InitializationState.IsInitializing;
+        } 
+
+        /// <SecurityNote>
+        /// Critical - this method calls into critical method.
+        /// </SecurityNote> 
+        [SecurityCritical]
+        void ISupportInitialize.EndInit() 
+        { 
+            if (_initializationState != InitializationState.IsInitializing)
+            { 
+                // Cannot EndInit a GlyphRun that is not being initialized.
+                throw new InvalidOperationException(SR.Get(SRID.NotInInitialization));
+            }
+ 
+            Initialize(
+                (_originalUri == null ? null : _originalUri.Value), 
+                 _styleSimulations, 
+                 true
+                 ); 
+        }
+
+        private void CheckInitialized()
+        { 
+            if (_initializationState != InitializationState.IsInitialized)
+            { 
+                throw new InvalidOperationException(SR.Get(SRID.InitializationIncomplete)); 
+            }
+        } 
+
+        private void CheckInitializing()
+        {
+            if (_initializationState != InitializationState.IsInitializing) 
+            {
+                throw new InvalidOperationException(SR.Get(SRID.NotInInitialization)); 
+            } 
+        }
+ 
+    #endregion
+
+        //-----------------------------------------------------
+        // 
+        //  Private Nested Classes
+        // 
+        //------------------------------------------------------ 
+
+    #region Private Nested Classes 
+
+        private delegate double GlyphAccessor(ushort glyphIndex);
+
+        /// <summary> 
+        /// This class is a helper to implement named indexers
+        /// for glyph metrics. 
+        /// </summary> 
+        private class GlyphIndexer : IDictionary<ushort, double>
+        { 
+            internal GlyphIndexer(GlyphAccessor accessor, ushort numberOfGlyphs)
+            {
+                _accessor = accessor;
+                _numberOfGlyphs = numberOfGlyphs; 
+            }
+ 
+    #region IDictionary<ushort,double> Members 
+
+            public void Add(ushort key, double value) 
+            {
+                throw new NotSupportedException();
+            }
+ 
+            public bool ContainsKey(ushort key)
+            { 
+                return (key < _numberOfGlyphs); 
+            }
+ 
+            public ICollection<ushort> Keys
+            {
+                get { return new SequentialUshortCollection(_numberOfGlyphs); }
+            } 
+
+            public bool Remove(ushort key) 
+            { 
+                throw new NotSupportedException();
+            } 
+
+            public bool TryGetValue(ushort key, out double value)
+            {
+                if (ContainsKey(key)) 
+                {
+                    value = this[key]; 
+                    return true; 
+                }
+                else 
+                {
+                    value = new double();
+                    return false;
+                } 
+            }
+ 
+            public ICollection<double> Values 
+            {
+                get { return new ValueCollection(this); } 
+            }
+
+            public double this[ushort key]
+            { 
+                get
+                { 
+                    return _accessor(key); 
+                }
+                set 
+                {
+                    throw new NotSupportedException();
+                }
+            } 
+
+    #endregion 
+ 
+    #region ICollection<KeyValuePair<ushort,double>> Members
+ 
+            public void Add(KeyValuePair<ushort, double> item)
+            {
+                throw new NotSupportedException();
+            } 
+
+            public void Clear() 
+            { 
+                throw new NotSupportedException();
+            } 
+
+            public bool Contains(KeyValuePair<ushort, double> item)
+            {
+                return ContainsKey(item.Key); 
+            }
+ 
+            public void CopyTo(KeyValuePair<ushort, double>[] array, int arrayIndex) 
+            {
+                if (array == null) 
+                {
+                    throw new ArgumentNullException("array");
+                }
+ 
+                if (array.Rank != 1)
+                { 
+                    throw new ArgumentException(SR.Get(SRID.Collection_BadRank)); 
+                }
+ 
+                // The extra "arrayIndex >= array.Length" check in because even if _collection.Count
+                // is 0 the index is not allowed to be equal or greater than the length
+                // (from the MSDN ICollection docs)
+                if (arrayIndex < 0 || arrayIndex >= array.Length || (arrayIndex + Count) > array.Length) 
+                {
+                    throw new ArgumentOutOfRangeException("arrayIndex"); 
+                } 
+
+                for (ushort i = 0; i < Count; ++i) 
+                    array[arrayIndex + i] = new KeyValuePair<ushort, double>(i, this[i]);
+            }
+
+            public int Count 
+            {
+                get { return _numberOfGlyphs; } 
+            } 
+
+            public bool IsReadOnly 
+            {
+                get { return true; }
+            }
+ 
+            public bool Remove(KeyValuePair<ushort, double> item)
+            { 
+                throw new NotSupportedException(); 
+            }
+ 
+    #endregion
+
+    #region IEnumerable<KeyValuePair<ushort,double>> Members
+ 
+            public IEnumerator<KeyValuePair<ushort, double>> GetEnumerator()
+            { 
+                for (ushort i = 0; i < Count; ++i) 
+                    yield return new KeyValuePair<ushort, double>(i, this[i]);
+            } 
+
+    #endregion
+
+    #region IEnumerable Members 
+
+            IEnumerator IEnumerable.GetEnumerator() 
+            { 
+                return ((IEnumerable<KeyValuePair<ushort, double>>)this).GetEnumerator();
+            } 
+
+    #endregion
+
+            private class ValueCollection : ICollection<double> 
+            {
+                public ValueCollection(GlyphIndexer glyphIndexer) 
+                { 
+                    _glyphIndexer = glyphIndexer;
+                } 
+
+    #region ICollection<double> Members
+
+                public void Add(double item) 
+                {
+                    throw new NotSupportedException(); 
+                } 
+
+                public void Clear() 
+                {
+                    throw new NotSupportedException();
+                }
+ 
+                public bool Contains(double item)
+                { 
+                    foreach (double d in this) 
+                    {
+                        if (d == item) 
+                            return true;
+                    }
+                    return false;
+                } 
+
+                public void CopyTo(double[] array, int arrayIndex) 
+                { 
+                    if (array == null)
+                    { 
+                        throw new ArgumentNullException("array");
+                    }
+
+                    if (array.Rank != 1) 
+                    {
+                        throw new ArgumentException(SR.Get(SRID.Collection_BadRank)); 
+                    } 
+
+                    // The extra "arrayIndex >= array.Length" check in because even if _collection.Count 
+                    // is 0 the index is not allowed to be equal or greater than the length
+                    // (from the MSDN ICollection docs)
+                    if (arrayIndex < 0 || arrayIndex >= array.Length || (arrayIndex + Count) > array.Length)
+                    { 
+                        throw new ArgumentOutOfRangeException("arrayIndex");
+                    } 
+ 
+                    for (ushort i = 0; i < Count; ++i)
+                        array[arrayIndex + i] = _glyphIndexer[i]; 
+                }
+
+                public int Count
+                { 
+                    get { return _glyphIndexer._numberOfGlyphs; }
+                } 
+ 
+                public bool IsReadOnly
+                { 
+                    get { return true; }
+                }
+
+                public bool Remove(double item) 
+                {
+                    throw new NotSupportedException(); 
+                } 
+
+    #endregion 
+
+    #region IEnumerable<double> Members
+
+                public IEnumerator<double> GetEnumerator() 
+                {
+                    for (ushort i = 0; i < Count; ++i) 
+                        yield return _glyphIndexer[i]; 
+                }
+ 
+    #endregion
+
+    #region IEnumerable Members
+ 
+                IEnumerator IEnumerable.GetEnumerator()
+                { 
+                    return ((IEnumerable<double>)this).GetEnumerator(); 
+                }
+ 
+    #endregion
+
+                private GlyphIndexer _glyphIndexer;
+            } 
+
+            private GlyphAccessor _accessor; 
+            private ushort _numberOfGlyphs; 
+        }
+ 
+    #endregion Private Nested Classes
+
+        //------------------------------------------------------
+        // 
+        //  Private Fields
+        // 
+        //----------------------------------------------------- 
+
+    #region Private Fields 
+
+        private FontFaceLayoutInfo  _fontFace;
+
+        private StyleSimulations    _styleSimulations; 
+
+        /// <summary> 
+        /// The Uri that was passed in to constructor. 
+        /// </summary>
+        /// <SecurityNote> 
+        ///     This is critical as we do a demand based on this value public functions.
+        ///     Only setting this Uri is critical, getting is fine.  Hence using the
+        ///     SecurityCriticalDataForSet object.  Note that the object itself does not
+        ///     need to be Critical, it's just setting it that makes it Critical. 
+        /// </SecurityNote>
+        private SecurityCriticalDataClass<Uri> _originalUri; 
+ 
+        /// <SecurityNote>
+        /// Critical - as this object controls the Demand that'll be made before accessssing the 
+        ///            security sensitive contents of the font file.  This also only Critical
+        ///            for set.  This should be correctly whenever _originalUri is set.
+        ///
+        /// Caching object for perf reasons. 
+        /// </SecurityNote>
+        private SecurityCriticalDataForSet<CodeAccessPermission> _fileIOPermObj; 
+ 
+        private const double CFFConversionFactor = 1.0 / 65536.0;
+ 
+        private InitializationState _initializationState;
+
+        /// <summary>
+        /// Initialization states of GlyphTypeface object. 
+        /// </summary>
+        private enum InitializationState 
+        { 
+            /// <summary>
+            /// The state in which the GlyphTypeface has not been initialized. 
+            /// At this state, all operations on the object would cause InvalidOperationException.
+            /// The object can only transit to 'IsInitializing' state with BeginInit() call.
+            /// </summary>
+            Uninitialized, 
+
+            /// <summary> 
+            /// The state in which the GlyphTypeface is being initialized. At this state, user can 
+            /// set values into the required properties. The object can only transit to 'IsInitialized' state
+            /// with EndInit() call. 
+            /// </summary>
+            IsInitializing,
+
+            /// <summary> 
+            /// The state in which the GlyphTypeface object is fully initialized. At this state the object
+            /// is fully functional. There is no valid transition out of the state. 
+            /// </summary> 
+            IsInitialized,
+        } 
+
+    #endregion Private Fields
+#endif
+  }
+}
diff --git a/lib/PdfSharp/PdfSharp.Drawing/XGraphics.cs b/lib/PdfSharp/PdfSharp.Drawing/XGraphics.cs
index 41d1e6c..ca01cb6 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/XGraphics.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/XGraphics.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -38,6 +38,7 @@ using System.Drawing.Imaging;
 #endif
 #if WPF
 using System.Windows;
+using System.Windows.Controls;
 using System.Windows.Media;
 #endif
 using PdfSharp.Internal;
@@ -45,6 +46,7 @@ using PdfSharp.Pdf;
 using PdfSharp.Drawing.Pdf;
 using PdfSharp.Pdf.Advanced;
 
+// ReSharper disable RedundantNameQualifier
 namespace PdfSharp.Drawing
 {
   /// <summary>
@@ -92,6 +94,10 @@ namespace PdfSharp.Drawing
           this.pageSizePoints = new XSize(XUnit.FromCentimeter(size.width), XUnit.FromCentimeter(size.height));
           break;
 
+        case XGraphicsUnit.Presentation:
+          this.pageSizePoints = new XSize(XUnit.FromPresentation(size.width), XUnit.FromPresentation(size.height));
+          break;
+
         default:
           throw new NotImplementedException("unit");
       }
@@ -101,7 +107,7 @@ namespace PdfSharp.Drawing
     }
 #endif
 
-#if WPF
+#if WPF && !SILVERLIGHT
     /// <summary>
     /// Initializes a new instance of the XGraphics class.
     /// </summary>
@@ -142,6 +148,63 @@ namespace PdfSharp.Drawing
           this.pageSizePoints = new XSize(XUnit.FromCentimeter(size.width), XUnit.FromCentimeter(size.height));
           break;
 
+        case XGraphicsUnit.Presentation:
+          this.pageSizePoints = new XSize(XUnit.FromPresentation(size.width), XUnit.FromPresentation(size.height));
+          break;
+
+        default:
+          throw new NotImplementedException("unit");
+      }
+
+      this.pageDirection = pageDirection;
+      Initialize();
+    }
+#endif
+
+#if SILVERLIGHT
+    /// <summary>
+    /// Initializes a new instance of the XGraphics class.
+    /// </summary>
+    /// <param name="canvas">The canvas.</param>
+    /// <param name="size">The size.</param>
+    /// <param name="pageUnit">The page unit.</param>
+    /// <param name="pageDirection">The page direction.</param>
+    XGraphics(Canvas canvas, XSize size, XGraphicsUnit pageUnit, XPageDirection pageDirection)
+    {
+      //throw new ArgumentNullException("canvas");
+      if (canvas == null)
+        canvas = new Canvas();
+
+      this.dc = new DrawingContext(canvas);
+
+      this.gsStack = new GraphicsStateStack(this);
+      this.targetContext = XGraphicTargetContext.WPF;
+
+      this.drawGraphics = true;
+      this.pageSize = new XSize(size.width, size.height);
+      this.pageUnit = pageUnit;
+      switch (pageUnit)
+      {
+        case XGraphicsUnit.Point:
+          this.pageSizePoints = new XSize(size.width, size.height);
+          break;
+
+        case XGraphicsUnit.Inch:
+          this.pageSizePoints = new XSize(XUnit.FromInch(size.width), XUnit.FromInch(size.height));
+          break;
+
+        case XGraphicsUnit.Millimeter:
+          this.pageSizePoints = new XSize(XUnit.FromMillimeter(size.width), XUnit.FromMillimeter(size.height));
+          break;
+
+        case XGraphicsUnit.Centimeter:
+          this.pageSizePoints = new XSize(XUnit.FromCentimeter(size.width), XUnit.FromCentimeter(size.height));
+          break;
+
+        case XGraphicsUnit.Presentation:
+          this.pageSizePoints = new XSize(XUnit.FromPresentation(size.width), XUnit.FromPresentation(size.height));
+          break;
+
         default:
           throw new NotImplementedException("unit");
       }
@@ -187,17 +250,21 @@ namespace PdfSharp.Drawing
       page.RenderContent = content;
 
 #if GDI
-      // HACK: 
+      // HACK: This does not work with MediumTrust
       this.gfx = Graphics.FromHwnd(IntPtr.Zero);
       this.targetContext = XGraphicTargetContext.GDI;
       //Bitmap bm = new Bitmap(10, 10);
       //this.gfx = Graphics.FromImage(bm);
 #endif
-#if WPF
+#if WPF && !SILVERLIGHT
       this.dv = new DrawingVisual();
       this.dc = this.dv.RenderOpen();
       this.targetContext = XGraphicTargetContext.WPF;
 #endif
+#if SILVERLIGHT
+      this.dc = new DrawingContext(new Canvas());
+      this.targetContext = XGraphicTargetContext.WPF;
+#endif
 #if GDI && WPF
       this.targetContext = PdfSharp.Internal.TargetContextHelper.TargetContext;
 #endif
@@ -221,6 +288,10 @@ namespace PdfSharp.Drawing
           this.pageSize = new XSize(XUnit.FromPoint(page.Width).Centimeter, XUnit.FromPoint(page.Height).Centimeter);
           break;
 
+        case XGraphicsUnit.Presentation:
+          this.pageSize = new XSize(XUnit.FromPoint(page.Width).Presentation, XUnit.FromPoint(page.Height).Presentation);
+          break;
+
         default:
           throw new NotImplementedException("unit");
       }
@@ -317,6 +388,7 @@ namespace PdfSharp.Drawing
 #endif
 #if WPF && !GDI
       this.targetContext = XGraphicTargetContext.WPF;
+#if !SILVERLIGHT
       // If form.Owner is null create a meta file.
       if (form.Owner == null)
       {
@@ -333,6 +405,10 @@ namespace PdfSharp.Drawing
         this.renderer = new PdfSharp.Drawing.Pdf.XGraphicsPdfRenderer(form, this);
       this.pageSize = form.Size;
       Initialize();
+#else
+      throw new NotImplementedException(); // AGHACK
+      //Initialize();
+#endif
 #endif
     }
 
@@ -346,9 +422,12 @@ namespace PdfSharp.Drawing
 #if GDI
       gfx = new XGraphics((System.Drawing.Graphics)null, size, pageUnit, pageDirection);
 #endif
-#if WPF
+#if WPF && !SILVERLIGHT
       gfx = new XGraphics((System.Windows.Media.DrawingContext)null, size, pageUnit, pageDirection);
 #endif
+#if SILVERLIGHT
+      gfx = new XGraphics(new Canvas(), size, pageUnit, pageDirection);
+#endif
       return gfx;
     }
 
@@ -390,7 +469,7 @@ namespace PdfSharp.Drawing
     //}
 #endif
 
-#if WPF
+#if WPF && !SILVERLIGHT
     /// <summary>
     /// Creates a new instance of the XGraphics class from a System.Windows.Media.DrawingContext object.
     /// </summary>
@@ -400,6 +479,16 @@ namespace PdfSharp.Drawing
     }
 #endif
 
+#if SILVERLIGHT
+    /// <summary>
+    /// Creates a new instance of the XGraphics class from a System.Windows.Media.DrawingContext object.
+    /// </summary>
+    public static XGraphics FromCanvas(Canvas canvas, XSize size, XGraphicsUnit unit)
+    {
+      return new XGraphics(canvas, size, unit, XPageDirection.Downwards);
+    }
+#endif
+
     /// <summary>
     /// Creates a new instance of the XGraphics class from a PdfSharp.Pdf.PdfPage object.
     /// </summary>
@@ -484,7 +573,7 @@ namespace PdfSharp.Drawing
     void Initialize()
     {
       this.pageOrigin = new XPoint();
-      XMatrix matrix = XMatrix.Identity;
+      XMatrix matrix = new XMatrix();  //XMatrix.Identity;
 
       double pageHeight = this.pageSize.height;
       PdfPage targetPage = PdfPage;
@@ -549,13 +638,18 @@ namespace PdfSharp.Drawing
           }
           if (!matrix.IsIdentity)
           {
+#if !SILVERLIGHT
             MatrixTransform transform = new MatrixTransform((System.Windows.Media.Matrix)matrix);
             dc.PushTransform(transform);
+#else
+            MatrixTransform transform2 = new MatrixTransform();
+            transform2.Matrix = (System.Windows.Media.Matrix)matrix;
+            dc.PushTransform(transform2);
+#endif
           }
         }
       }
 #endif
-
       if (this.pageDirection == XPageDirection.Upwards)
         matrix.Prepend(new XMatrix(1, 0, 0, -1, 0, pageHeight));
 
@@ -563,7 +657,7 @@ namespace PdfSharp.Drawing
         matrix.TranslatePrepend(trimOffset.x, trimOffset.y);
 
       this.defaultViewMatrix = matrix;
-      this.transform = XMatrix.Identity;
+      this.transform = new XMatrix();  //XMatrix.Identity;
     }
 
     /// <summary>
@@ -600,7 +694,9 @@ namespace PdfSharp.Drawing
         if (this.dc != null)
         {
           this.dc.Close();
+#if !SILVERLIGHT
           this.dv = null;
+#endif
         }
 #endif
         this.drawGraphics = false;
@@ -872,7 +968,16 @@ namespace PdfSharp.Drawing
 #if WPF
         if (this.targetContext == XGraphicTargetContext.WPF)
         {
+#if !SILVERLIGHT
           PolyLineSegment seg = new PolyLineSegment(XGraphics.MakePointArray(points), true);
+#else
+          Point[] pts = XGraphics.MakePointArray(points);
+          PointCollection collection = new PointCollection();
+          foreach (Point point in pts)
+            collection.Add(point);
+          PolyLineSegment seg = new PolyLineSegment();
+          seg.Points = collection;
+#endif
           PathFigure figure = new PathFigure();
           figure.StartPoint = new System.Windows.Point(points[0].x, points[0].y);
           figure.Segments.Add(seg);
@@ -969,6 +1074,7 @@ namespace PdfSharp.Drawing
 #if WPF
         if (this.targetContext == XGraphicTargetContext.WPF)
         {
+#if !SILVERLIGHT
           BezierSegment seg = new BezierSegment(new System.Windows.Point(x2, y2), new System.Windows.Point(x3, y3), new System.Windows.Point(x4, y4), true);
           PathFigure figure = new PathFigure();
           figure.StartPoint = new System.Windows.Point(x1, y1);
@@ -976,6 +1082,9 @@ namespace PdfSharp.Drawing
           PathGeometry geo = new PathGeometry();
           geo.Figures.Add(figure);
           this.dc.DrawGeometry(null, pen.RealizeWpfPen(), geo);
+#else
+          // AGHACK
+#endif
         }
 #endif
       }
@@ -1042,6 +1151,7 @@ namespace PdfSharp.Drawing
 #if WPF
         if (this.targetContext == XGraphicTargetContext.WPF)
         {
+#if !SILVERLIGHT
           PathFigure figure = new PathFigure();
           figure.StartPoint = new System.Windows.Point(points[0].x, points[0].y);
           for (int idx = 1; idx < count; idx += 3)
@@ -1055,6 +1165,9 @@ namespace PdfSharp.Drawing
           PathGeometry geo = new PathGeometry();
           geo.Figures.Add(figure);
           this.dc.DrawGeometry(null, pen.RealizeWpfPen(), geo);
+#else
+          // AGHACK
+#endif
         }
 #endif
       }
@@ -1321,7 +1434,9 @@ namespace PdfSharp.Drawing
 #endif
 #if WPF
         if (this.targetContext == XGraphicTargetContext.WPF)
+        {
           this.dc.DrawRectangle(null, pen.RealizeWpfPen(), new Rect(x, y, width, height));
+        }
 #endif
       }
 
@@ -2123,7 +2238,6 @@ namespace PdfSharp.Drawing
 #if WPF
         if (this.targetContext == XGraphicTargetContext.WPF)
         {
-          System.Windows.Point[] p = MakePointArray(points);
           this.dc.DrawGeometry(null, pen.RealizeWpfPen(), GeometryHelper.CreatePolygonGeometry(MakePointArray(points), XFillMode.Alternate, true));
         }
 #endif
@@ -2186,7 +2300,6 @@ namespace PdfSharp.Drawing
 #if WPF
         if (this.targetContext == XGraphicTargetContext.WPF)
         {
-          System.Windows.Point[] p = MakePointArray(points);
           this.dc.DrawGeometry(brush.RealizeWpfBrush(), null, GeometryHelper.CreatePolygonGeometry(MakePointArray(points), fillmode, true));
         }
 #endif
@@ -2448,6 +2561,7 @@ namespace PdfSharp.Drawing
 #if WPF
         if (this.targetContext == XGraphicTargetContext.WPF)
         {
+#if !SILVERLIGHT
           System.Windows.Media.Brush wpfBrush = brush != null ? brush.RealizeWpfBrush() : null;
           System.Windows.Media.Pen wpfPen = pen != null ? pen.RealizeWpfPen() : null;
           System.Windows.Point center = new System.Windows.Point(x + width / 2, y + height / 2);
@@ -2461,6 +2575,9 @@ namespace PdfSharp.Drawing
           PathGeometry geo = new PathGeometry();
           geo.Figures.Add(figure);
           this.dc.DrawGeometry(wpfBrush, wpfPen, geo);
+#else
+          // AGHACK
+#endif
         }
 #endif
       }
@@ -2823,6 +2940,7 @@ namespace PdfSharp.Drawing
 #if WPF
         if (this.targetContext == XGraphicTargetContext.WPF)
         {
+#if !SILVERLIGHT
           tension /= 3; // Simply tried out. Not proofed why it is correct.
 
           PathFigure figure = new PathFigure();
@@ -2846,6 +2964,9 @@ namespace PdfSharp.Drawing
           System.Windows.Media.Brush wpfBrush = brush != null ? brush.RealizeWpfBrush() : null;
           System.Windows.Media.Pen wpfPen = pen != null ? pen.RealizeWpfPen() : null;
           this.dc.DrawGeometry(wpfBrush, wpfPen, geo);
+#else
+          // AGHACK
+#endif
         }
 #endif
       }
@@ -3037,13 +3158,13 @@ namespace PdfSharp.Drawing
     public void DrawString(string text, XFont font, XBrush brush, XRect layoutRectangle, XStringFormat format)
     {
       if (text == null)
-        throw new ArgumentNullException("s");
+        throw new ArgumentNullException("text");
       if (font == null)
         throw new ArgumentNullException("font");
       if (brush == null)
         throw new ArgumentNullException("brush");
 
-      if (format.LineAlignment == XLineAlignment.BaseLine && layoutRectangle.Height != 0)
+      if (format != null && format.LineAlignment == XLineAlignment.BaseLine && layoutRectangle.Height != 0)
         throw new InvalidOperationException("DrawString: With XLineAlignment.BaseLine the height of the layout rectangle must be 0.");
 
       if (text.Length == 0)
@@ -3075,6 +3196,7 @@ namespace PdfSharp.Drawing
 #if WPF
         if (this.targetContext == XGraphicTargetContext.WPF)
         {
+#if !SILVERLIGHT
           double x = layoutRectangle.X;
           double y = layoutRectangle.Y;
 
@@ -3087,8 +3209,9 @@ namespace PdfSharp.Drawing
           bool strikeout = (font.Style & XFontStyle.Strikeout) != 0;
           bool underline = (font.Style & XFontStyle.Underline) != 0;
 
-          FormattedText formattedText = new FormattedText(text, new CultureInfo("en-us"), // WPFHACK
-            FlowDirection.LeftToRight, font.typeface, font.Size, brush.RealizeWpfBrush());
+          //FormattedText formattedText = new FormattedText(text, new CultureInfo("en-us"), // WPFHACK
+          //  FlowDirection.LeftToRight, font.typeface, font.Size, brush.RealizeWpfBrush());
+          FormattedText formattedText = FontHelper.CreateFormattedText(text, font.typeface, font.Size, brush.RealizeWpfBrush());
 
           //formattedText.SetTextDecorations(TextDecorations.OverLine);
           switch (format.Alignment)
@@ -3133,7 +3256,7 @@ namespace PdfSharp.Drawing
           }
           else
           {
-            // TODOWPF
+            // TODOWPF: make unit test
             switch (format.LineAlignment)
             {
               case XLineAlignment.Near:
@@ -3181,9 +3304,11 @@ namespace PdfSharp.Drawing
             //DrawRectangle(null, brush, x, y - strikeoutPosition - strikeoutSize, width, strikeoutSize);
           }
 
-
           //this.dc.DrawText(formattedText, layoutRectangle.Location.ToPoint());
           this.dc.DrawText(formattedText, new System.Windows.Point(x, y));
+#else
+          dc.DrawString(this, text, font, brush, layoutRectangle, format);
+#endif
         }
 #endif
       }
@@ -3211,9 +3336,15 @@ namespace PdfSharp.Drawing
       return XSize.FromSizeF(this.gfx.MeasureString(text, font.RealizeGdiFont(), new PointF(0, 0), stringFormat.RealizeGdiStringFormat()));
 #endif
 #if WPF && !GDI
-      FormattedText formattedText = new FormattedText(text, new CultureInfo("en-us"),
-        FlowDirection.LeftToRight, font.typeface, font.Height, System.Windows.Media.Brushes.Black);
+#if !SILVERLIGHT
+      //FormattedText formattedText = new FormattedText(text, new CultureInfo("en-us"),
+      //  FlowDirection.LeftToRight, font.typeface, font.Size, System.Windows.Media.Brushes.Black);
+      FormattedText formattedText = FontHelper.CreateFormattedText(text, font.typeface, font.Size, System.Windows.Media.Brushes.Black);
       return new XSize(formattedText.WidthIncludingTrailingWhitespace, formattedText.Height);
+#else
+      return dc.MeasureString(this, text, font, stringFormat);
+#endif
+
 #endif
 #if WPF && GDI
       if (this.targetContext == XGraphicTargetContext.GDI)
@@ -3227,8 +3358,10 @@ namespace PdfSharp.Drawing
       if (this.targetContext == XGraphicTargetContext.WPF)
       {
         //double h = font.Height;
-        FormattedText formattedText = new FormattedText(text, new CultureInfo("en-us"),
-          FlowDirection.LeftToRight, font.typeface, font.Size, System.Windows.Media.Brushes.Black);
+        //FormattedText formattedText = new FormattedText(text, new CultureInfo("en-us"),
+        //  FlowDirection.LeftToRight, font.typeface, font.Size, System.Windows.Media.Brushes.Black);
+        FormattedText formattedText = FontHelper.CreateFormattedText(text, font.typeface, font.Size, System.Windows.Media.Brushes.Black);
+
         XSize wpfSize = new XSize(formattedText.WidthIncludingTrailingWhitespace, formattedText.Height);
 #if DEBUG
         Debug.WriteLine(wpfSize);
@@ -3354,26 +3487,11 @@ namespace PdfSharp.Drawing
         {
           if (image.wpfImage != null)
           {
-            //InterpolationMode interpolationMode = InterpolationMode.Invalid;
-            //if (!image.Interpolate)
-            //{
-            //  interpolationMode = gfx.InterpolationMode;
-            //  //gfx.InterpolationMode = InterpolationMode.NearestNeighbor;
-            //}
-
             this.dc.DrawImage(image.wpfImage, new Rect(x, y, image.PointWidth, image.PointHeight));
-
-            //if (!image.Interpolate)
-            //  gfx.InterpolationMode = interpolationMode;
           }
           else
           {
             DrawMissingImageRect(new XRect(x, y, width, height));
-            //Rect rect = new Rect(x, y, width, height);
-            //System.Windows.Media.Pen pen = new System.Windows.Media.Pen(System.Windows.Media.Brushes.Red, 1);
-            //this.dc.DrawRectangle(null, pen, new Rect(x, y, width, height));
-            //this.dc.DrawLine(pen, new System.Windows.Point(x, y), new System.Windows.Point(x + width, y + height));
-            //this.dc.DrawLine(pen, new System.Windows.Point(x + width, y), new System.Windows.Point(x, y + height));
           }
         }
 #endif
@@ -3588,7 +3706,27 @@ namespace PdfSharp.Drawing
 #if WPF
         if (this.targetContext == XGraphicTargetContext.WPF)
         {
-          throw new NotImplementedException("TODO");
+          if (image.wpfImage != null)
+          {
+            //InterpolationMode interpolationMode = InterpolationMode.Invalid;
+            //if (!image.Interpolate)
+            //{
+            //  interpolationMode = gfx.InterpolationMode;
+            //  //gfx.InterpolationMode = InterpolationMode.NearestNeighbor;
+            //}
+
+            // HACK: srcRect is ignored
+            double x = destRect.x;
+            double y = destRect.y;
+            this.dc.DrawImage(image.wpfImage, new System.Windows.Rect(destRect.x, destRect.y, destRect.width, destRect.height));
+
+            //if (!image.Interpolate)
+            //  gfx.InterpolationMode = interpolationMode;
+          }
+          else
+          {
+            DrawMissingImageRect(destRect);
+          }
         }
 #endif
       }
@@ -3623,7 +3761,11 @@ namespace PdfSharp.Drawing
         double y = rect.y;
         double width = rect.width;
         double height = rect.height;
+#if !SILVERLIGHT
         System.Windows.Media.Pen pen = new System.Windows.Media.Pen(System.Windows.Media.Brushes.Red, 1);
+#else
+        System.Windows.Media.Pen pen = new System.Windows.Media.Pen(new SolidColorBrush(Colors.Red), 1);
+#endif
         this.dc.DrawRectangle(null, pen, new Rect(x, y, width, height));
         this.dc.DrawLine(pen, new System.Windows.Point(x, y), new System.Windows.Point(x + width, y + height));
         this.dc.DrawLine(pen, new System.Windows.Point(x + width, y), new System.Windows.Point(x, y + height));
@@ -3632,24 +3774,24 @@ namespace PdfSharp.Drawing
     }
 
     /// <summary>
-    /// Checks whether drawing is allowed and disposes the XGraphics object, if neccessary.
+    /// Checks whether drawing is allowed and disposes the XGraphics object, if necessary.
     /// </summary>
     void CheckXPdfFormConsistence(XImage image)
     {
-      XForm form = image as XForm;
+      XForm xForm = image as XForm;
       XGraphicsPdfRenderer renderer;
-      if (form != null)
+      if (xForm != null)
       {
         // Force disposing of XGraphics that draws the content
-        form.Finish();
+        xForm.Finish();
 
         if (this.renderer != null && (renderer = this.renderer as XGraphicsPdfRenderer) != null)
         {
-          if (form.Owner != null && form.Owner != ((XGraphicsPdfRenderer)this.renderer).Owner)
+          if (xForm.Owner != null && xForm.Owner != ((XGraphicsPdfRenderer)this.renderer).Owner)
             throw new InvalidOperationException(
               "A XPdfForm object is always bound to the document it was created for and cannot be drawn in the context of another document.");
 
-          if (form == ((XGraphicsPdfRenderer)this.renderer).form)
+          if (xForm == ((XGraphicsPdfRenderer)this.renderer).form)
             throw new InvalidOperationException(
               "A XPdfForm cannot be drawn on itself.");
         }
@@ -3835,7 +3977,7 @@ namespace PdfSharp.Drawing
     }
 
     /// <summary>
-    /// Restores the state of this XGraphics object to the state before the most resently call of Save.
+    /// Restores the state of this XGraphics object to the state before the most recently call of Save.
     /// </summary>
     public void Restore()
     {
@@ -3913,7 +4055,7 @@ namespace PdfSharp.Drawing
       if (this.renderer != null)
         this.renderer.BeginContainer(xContainer, dstrect, srcrect, unit);
 
-      XMatrix matrix = XMatrix.Identity;
+      XMatrix matrix = new XMatrix();  //XMatrix.Identity;
 #if true
       double scaleX = dstrect.Width / srcrect.Width;
       double scaleY = dstrect.Height / srcrect.Height;
@@ -4030,7 +4172,7 @@ namespace PdfSharp.Drawing
     /// </summary>
     public void TranslateTransform(double dx, double dy)
     {
-      XMatrix matrix = XMatrix.Identity;
+      XMatrix matrix = new XMatrix();  //XMatrix.Identity;
       matrix.TranslatePrepend(dx, dy);
       AddTransform(matrix, XMatrixOrder.Prepend);
     }
@@ -4044,7 +4186,7 @@ namespace PdfSharp.Drawing
       //XMatrix matrix = this.transform;
       //matrix.Translate(dx, dy, order);
       //Transform = matrix;
-      XMatrix matrix = XMatrix.Identity;
+      XMatrix matrix = new XMatrix();  //XMatrix.Identity;
       matrix.TranslatePrepend(dx, dy);
       AddTransform(matrix, order);
     }
@@ -4056,7 +4198,7 @@ namespace PdfSharp.Drawing
     public void ScaleTransform(double scaleX, double scaleY)
     {
       //ScaleTransform(scaleX, scaleY, XMatrixOrder.Prepend);
-      XMatrix matrix = XMatrix.Identity;
+      XMatrix matrix = new XMatrix();  //XMatrix.Identity;
       matrix.ScalePrepend(scaleX, scaleY);
       AddTransform(matrix, XMatrixOrder.Prepend);
     }
@@ -4070,7 +4212,7 @@ namespace PdfSharp.Drawing
       //XMatrix matrix = this.transform;
       //matrix.Scale(scaleX, scaleY, order);
       //Transform = matrix;
-      XMatrix matrix = XMatrix.Identity;
+      XMatrix matrix = new XMatrix();  //XMatrix.Identity;
       matrix.ScalePrepend(scaleX, scaleY);
       AddTransform(matrix, order);
     }
@@ -4082,7 +4224,7 @@ namespace PdfSharp.Drawing
     public void ScaleTransform(double scaleXY)
     {
       //ScaleTransform(scaleXY, scaleXY, XMatrixOrder.Prepend);
-      XMatrix matrix = XMatrix.Identity;
+      XMatrix matrix = new XMatrix();  //XMatrix.Identity;
       matrix.ScalePrepend(scaleXY, scaleXY);
       AddTransform(matrix, XMatrixOrder.Prepend);
     }
@@ -4096,7 +4238,7 @@ namespace PdfSharp.Drawing
       //XMatrix matrix = this.transform;
       //matrix.Scale(scaleXY, scaleXY, order);
       //Transform = matrix;
-      XMatrix matrix = XMatrix.Identity;
+      XMatrix matrix = new XMatrix();  //XMatrix.Identity;
       matrix.ScalePrepend(scaleXY, scaleXY);
       AddTransform(matrix, order);
     }
@@ -4108,7 +4250,7 @@ namespace PdfSharp.Drawing
     public void RotateTransform(double angle)
     {
       //RotateTransform(angle, XMatrixOrder.Prepend);
-      XMatrix matrix = XMatrix.Identity;
+      XMatrix matrix = new XMatrix();  //XMatrix.Identity;
       matrix.RotatePrepend(angle);
       AddTransform(matrix, XMatrixOrder.Prepend);
     }
@@ -4122,7 +4264,7 @@ namespace PdfSharp.Drawing
       //XMatrix matrix = this.transform;
       //matrix.Rotate(angle, order);
       //Transform = matrix;
-      XMatrix matrix = XMatrix.Identity;
+      XMatrix matrix = new XMatrix();  //XMatrix.Identity;
       matrix.RotatePrepend(angle);
       AddTransform(matrix, order);
     }
@@ -4134,7 +4276,7 @@ namespace PdfSharp.Drawing
     public void RotateAtTransform(double angle, XPoint point)
     {
       //RotateAtTransform(angle, point, XMatrixOrder.Prepend);
-      XMatrix matrix = XMatrix.Identity;
+      XMatrix matrix = new XMatrix();  //XMatrix.Identity;
       matrix.RotateAtPrepend(angle, point);
       AddTransform(matrix, XMatrixOrder.Prepend);
     }
@@ -4148,7 +4290,7 @@ namespace PdfSharp.Drawing
       //XMatrix matrix = this.transform;
       //matrix.RotateAt(angle, point, order);
       //Transform = matrix;
-      XMatrix matrix = XMatrix.Identity;
+      XMatrix matrix = new XMatrix();  //XMatrix.Identity;
       matrix.RotateAtPrepend(angle, point);
       AddTransform(matrix, order);
     }
@@ -4159,7 +4301,7 @@ namespace PdfSharp.Drawing
     /// </summary>
     public void ShearTransform(double shearX, double shearY)
     {
-      XMatrix matrix = XMatrix.Identity;
+      XMatrix matrix = new XMatrix();  //XMatrix.Identity;
       matrix.ShearPrepend(shearX, shearY);
       AddTransform(matrix, XMatrixOrder.Prepend);
     }
@@ -4170,7 +4312,7 @@ namespace PdfSharp.Drawing
     /// </summary>
     public void ShearTransform(double shearX, double shearY, XMatrixOrder order)
     {
-      XMatrix matrix = XMatrix.Identity;
+      XMatrix matrix = new XMatrix();  //XMatrix.Identity;
       matrix.ShearPrepend(shearX, shearY);
       AddTransform(matrix, order);
     }
@@ -4181,7 +4323,7 @@ namespace PdfSharp.Drawing
     public void MultiplyTransform(XMatrix matrix)
     {
       //MultiplyTransform(matrix, XMatrixOrder.Prepend);
-      XMatrix matrix2 = XMatrix.Identity;
+      XMatrix matrix2 = new XMatrix();  //XMatrix.Identity;
       matrix2.Prepend(matrix);
       AddTransform(matrix2, XMatrixOrder.Prepend);
     }
@@ -4194,7 +4336,7 @@ namespace PdfSharp.Drawing
       //XMatrix matrix2 = this.transform;
       //matrix2.Multiply(matrix, order);
       //Transform = matrix2;
-      XMatrix matrix2 = XMatrix.Identity;
+      XMatrix matrix2 = new XMatrix();  //XMatrix.Identity;
       matrix2.Prepend(matrix);
       AddTransform(matrix2, order);
     }
@@ -4245,12 +4387,24 @@ namespace PdfSharp.Drawing
         matrix.Multiply(this.transform, XMatrixOrder.Prepend);
 #if GDI
         if (this.targetContext == XGraphicTargetContext.GDI)
+        {
+#if DEBUG
+          System.Drawing.Drawing2D.Matrix m = (System.Drawing.Drawing2D.Matrix)matrix;
+          this.gfx.Transform = m;
+#else
           this.gfx.Transform = (System.Drawing.Drawing2D.Matrix)matrix;
 #endif
+        }
+#endif
 #if WPF
         if (this.targetContext == XGraphicTargetContext.WPF)
         {
+#if !SILVERLIGHT
           MatrixTransform mt = new MatrixTransform(transform.ToWpfMatrix());
+#else
+          MatrixTransform mt = new MatrixTransform();
+          mt.Matrix = transform.ToWpfMatrix();
+#endif
           if (order == XMatrixOrder.Append)
             mt = (MatrixTransform)mt.Inverse;
           this.gsStack.Current.SetTransform(mt);
@@ -4267,21 +4421,8 @@ namespace PdfSharp.Drawing
     [Obsolete("Use Save/Restore to reset transformation.")]
     public void ResetTransform()
     {
+      // Definitely out of order
       throw new InvalidOperationException(PSSR.ObsoleteFunktionCalled);
-      //      if (!this.transform.IsIdentity)
-      //      {
-      //        this.transform = XMatrix.Identity;
-      //#if GDI
-      //        this.gfx.Transform = (System.Drawing.Drawing2D.Matrix)this.defaultViewMatrix;
-      //#endif
-      //#if WPF
-      //        // TODOWPF
-      //        //this.gfx.Transform = (Matrix)this.defaultViewMatrix;
-      //#endif
-
-      //        if (this.renderer != null)
-      //          this.renderer.Transform = this.transform;
-      //      }
     }
 
     //public void TransformPoints(CoordinateSpace destSpace, CoordinateSpace srcSpace, Point[] points)
@@ -4305,9 +4446,10 @@ namespace PdfSharp.Drawing
     [Obsolete("Use IntersectClip")]
     public void SetClip(Rectangle rect)
     {
-      XGraphicsPath path = new XGraphicsPath();
-      path.AddRectangle(rect);
-      SetClip(path, XCombineMode.Replace);
+      throw new InvalidOperationException("Function is obsolete. Use IntersectClip.");
+      //XGraphicsPath path = new XGraphicsPath();
+      //path.AddRectangle(rect);
+      //SetClip(path, XCombineMode.Replace);
     }
 #endif
 
@@ -4318,6 +4460,7 @@ namespace PdfSharp.Drawing
     [Obsolete("Use IntersectClip")]
     public void SetClip(RectangleF rect)
     {
+      throw new InvalidOperationException("Function is obsolete. Use IntersectClip.");
       //XGraphicsPath path = new XGraphicsPath();
       //path.AddRectangle(rect);
       //SetClip(path, XCombineMode.Replace);
@@ -4330,6 +4473,7 @@ namespace PdfSharp.Drawing
     [Obsolete("Use IntersectClip", true)]
     public void SetClip(XRect rect)
     {
+      throw new InvalidOperationException("Function is obsolete. Use IntersectClip.");
       //XGraphicsPath path = new XGraphicsPath();
       //path.AddRectangle(rect);
       //SetClip(path, XCombineMode.Replace);
@@ -4341,6 +4485,7 @@ namespace PdfSharp.Drawing
     [Obsolete("Use IntersectClip", true)]
     public void SetClip(XGraphicsPath path)
     {
+      throw new InvalidOperationException("Function is obsolete. Use IntersectClip.");
       //SetClip(path, XCombineMode.Replace);
     }
 
@@ -4350,6 +4495,7 @@ namespace PdfSharp.Drawing
     [Obsolete("Use IntersectClip", true)]
     public void SetClip(XRect rect, XCombineMode combineMode)
     {
+      throw new InvalidOperationException("Function is obsolete. Use IntersectClip.");
       //XGraphicsPath path = new XGraphicsPath();
       //path.AddRectangle(rect);
       //SetClip(path, combineMode);
@@ -4361,7 +4507,7 @@ namespace PdfSharp.Drawing
     [Obsolete("Use IntersectClip", true)]
     public void SetClip(XGraphicsPath path, XCombineMode combineMode)
     {
-      throw new InvalidOperationException("Frankly, user IntersectClip!");
+      throw new InvalidOperationException("Function is obsolete. Use IntersectClip.");
       //      if (path == null)
       //        throw new ArgumentNullException("path");
 
@@ -4482,7 +4628,7 @@ namespace PdfSharp.Drawing
     [Obsolete("Use Save/Restore pairs to reset clip area.", true)]
     public void ResetClip()
     {
-      throw new InvalidOperationException("ResetClip is obsolete.");
+      throw new InvalidOperationException("ResetClip is obsolete. Use Save/Restore instead.");
       //      if (this.drawGraphics)
       //      {
       //#if GDI
@@ -4531,7 +4677,7 @@ namespace PdfSharp.Drawing
     }
 
     /// <summary>
-    /// Permits acces to internal data.
+    /// Permits access to internal data.
     /// </summary>
     public XGraphicsInternals Internals
     {
@@ -4714,7 +4860,9 @@ namespace PdfSharp.Drawing
     /// <summary>
     /// Always defined System.Drawing.Graphics object. Used as 'query context' for PDF pages.
     /// </summary>
+#if !SILVERLIGHT
     DrawingVisual dv;
+#endif
     internal DrawingContext dc;
 #endif
 
@@ -4723,7 +4871,7 @@ namespace PdfSharp.Drawing
     /// (The name 'default view matrix' comes from Microsoft OS/2 Presentation Manager. I choose
     /// this name because I have no better one.)
     /// </summary>
-    internal XMatrix defaultViewMatrix = XMatrix.Identity;
+    internal XMatrix defaultViewMatrix;
 
     /// <summary>
     /// Indicates whether to send drawing operations to this.gfx or this.dc.
@@ -4744,7 +4892,7 @@ namespace PdfSharp.Drawing
     /// <summary>
     /// The transformation matrix from XGraphics world space to page unit space.
     /// </summary>
-    internal XMatrix transform = XMatrix.Identity;
+    internal XMatrix transform;
 
     /// <summary>
     /// The graphics state stack.
@@ -4775,7 +4923,7 @@ namespace PdfSharp.Drawing
 #endif
 
     /// <summary>
-    /// Privides access to internal data structures of the XGraphics class.
+    /// Provides access to internal data structures of the XGraphics class.
     /// </summary>
     public class XGraphicsInternals
     {
@@ -4818,7 +4966,7 @@ namespace PdfSharp.Drawing
       XGraphics gfx;
 
       /// <summary>
-      /// Gets the smalles rectangle in default page space units that completely encloses the specified rect
+      /// Gets the smallest rectangle in default page space units that completely encloses the specified rect
       /// in world space units.
       /// </summary>
       public XRect WorldToDefaultPage(XRect rect)
diff --git a/lib/PdfSharp/PdfSharp.Drawing/XGraphicsContainer.cs b/lib/PdfSharp/PdfSharp.Drawing/XGraphicsContainer.cs
index 1548d48..9eaf1b1 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/XGraphicsContainer.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/XGraphicsContainer.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Drawing/XGraphicsPath.cs b/lib/PdfSharp/PdfSharp.Drawing/XGraphicsPath.cs
index 2e4c316..68c2a7d 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/XGraphicsPath.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/XGraphicsPath.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -138,7 +138,11 @@ namespace PdfSharp.Drawing
       path.gdipPath = this.gdipPath.Clone() as GraphicsPath;
 #endif
 #if WPF
+#if !SILVERLIGHT
       path.pathGeometry = this.pathGeometry.Clone();
+#else
+      // AGHACK
+#endif
 #endif
       return path;
     }
@@ -216,12 +220,30 @@ namespace PdfSharp.Drawing
       if (figure.Segments.Count == 0)
       {
         figure.StartPoint = new System.Windows.Point(x1, y1);
-        figure.Segments.Add(new LineSegment(new System.Windows.Point(x2, y2), true));
+#if !SILVERLIGHT
+        LineSegment lineSegment = new LineSegment(new System.Windows.Point(x2, y2), true);
+#else
+        LineSegment lineSegment = new LineSegment();
+        lineSegment.Point = new Point(x2, y2);
+        // AGHACK: ,true??
+#endif
+        figure.Segments.Add(lineSegment);
       }
       else
       {
-        figure.Segments.Add(new LineSegment(new System.Windows.Point(x1, y1), true));
-        figure.Segments.Add(new LineSegment(new System.Windows.Point(x2, y2), true));
+#if !SILVERLIGHT
+        LineSegment lineSegment1 = new LineSegment(new System.Windows.Point(x1, y1), true);
+        LineSegment lineSegment2 = new LineSegment(new System.Windows.Point(x2, y2), true);
+#else
+        LineSegment lineSegment1 = new LineSegment();
+        lineSegment1.Point = new Point(x1, y1);
+        // AGHACK: ,true??
+        LineSegment lineSegment2 = new LineSegment();
+        lineSegment2.Point = new Point(x2, y2);
+        // AGHACK: ,true??
+#endif
+        figure.Segments.Add(lineSegment1);
+        figure.Segments.Add(lineSegment2);
       }
 #endif
     }
@@ -279,12 +301,29 @@ namespace PdfSharp.Drawing
       {
         figure.StartPoint = new System.Windows.Point(points[0].x, points[0].y);
         for (int idx = 1; idx < count; idx++)
-          figure.Segments.Add(new LineSegment(new System.Windows.Point(points[idx].x, points[idx].y), true));
+        {
+#if !SILVERLIGHT
+          LineSegment lineSegment = new LineSegment(new System.Windows.Point(points[idx].x, points[idx].y), true);
+#else
+          LineSegment lineSegment = new LineSegment();
+          lineSegment.Point = new Point(points[idx].x, points[idx].y); // ,true?
+#endif
+          figure.Segments.Add(lineSegment);
+        }
       }
       else
       {
         for (int idx = 0; idx < count; idx++)
-          figure.Segments.Add(new LineSegment(new System.Windows.Point(points[idx].x, points[idx].y), true));
+        {
+          // figure.Segments.Add(new LineSegment(new System.Windows.Point(points[idx].x, points[idx].y), true));
+#if !SILVERLIGHT
+          LineSegment lineSegment = new LineSegment(new System.Windows.Point(points[idx].x, points[idx].y), true);
+#else
+          LineSegment lineSegment = new LineSegment();
+          lineSegment.Point = new Point(points[idx].x, points[idx].y); // ,true?
+#endif
+          figure.Segments.Add(lineSegment);
+        }
       }
 #endif
     }
@@ -350,11 +389,32 @@ namespace PdfSharp.Drawing
       if (figure.Segments.Count == 0)
         figure.StartPoint = new System.Windows.Point(x1, y1);
       else
-        figure.Segments.Add(new LineSegment(new System.Windows.Point(x1, y1), true));
-      figure.Segments.Add(new BezierSegment(
+      {
+        // figure.Segments.Add(new LineSegment(new System.Windows.Point(x1, y1), true));
+#if !SILVERLIGHT
+        LineSegment lineSegment = new LineSegment(new System.Windows.Point(x1, y1), true);
+#else
+        LineSegment lineSegment = new LineSegment();
+        lineSegment.Point = new Point(x1, y1);
+#endif
+        figure.Segments.Add(lineSegment);
+      }
+      //figure.Segments.Add(new BezierSegment(
+      //  new System.Windows.Point(x2, y2),
+      //  new System.Windows.Point(x3, y3),
+      //  new System.Windows.Point(x4, y4), true));
+#if !SILVERLIGHT
+      BezierSegment bezierSegment = new BezierSegment(
         new System.Windows.Point(x2, y2),
         new System.Windows.Point(x3, y3),
-        new System.Windows.Point(x4, y4), true));
+        new System.Windows.Point(x4, y4), true);
+#else
+      BezierSegment bezierSegment = new BezierSegment();
+      bezierSegment.Point1 = new Point(x2, y2);
+      bezierSegment.Point2 = new Point(x3, y3);
+      bezierSegment.Point3 = new Point(x4, y4);
+#endif
+      figure.Segments.Add(bezierSegment);
 #endif
     }
 
@@ -413,13 +473,35 @@ namespace PdfSharp.Drawing
       if (figure.Segments.Count == 0)
         figure.StartPoint = new System.Windows.Point(points[0].x, points[0].y);
       else
-        figure.Segments.Add(new LineSegment(new System.Windows.Point(points[0].x, points[0].y), true));
-
+      {
+        // figure.Segments.Add(new LineSegment(new System.Windows.Point(points[0].x, points[0].y), true));
+#if !SILVERLIGHT
+        LineSegment lineSegment = new LineSegment(new System.Windows.Point(points[0].x, points[0].y), true);
+#else
+        LineSegment lineSegment = new LineSegment();
+        lineSegment.Point = new Point(points[0].x, points[0].y);
+#endif
+        figure.Segments.Add(lineSegment);
+      }
       for (int idx = 1; idx < count; idx += 3)
-        figure.Segments.Add(new BezierSegment(
-          new System.Windows.Point(points[idx].x, points[idx].y),
-          new System.Windows.Point(points[idx + 1].x, points[idx + 1].y),
-          new System.Windows.Point(points[idx + 2].x, points[idx + 2].y), true));
+      {
+        //figure.Segments.Add(new BezierSegment(
+        //                      new System.Windows.Point(points[idx].x, points[idx].y),
+        //                      new System.Windows.Point(points[idx + 1].x, points[idx + 1].y),
+        //                      new System.Windows.Point(points[idx + 2].x, points[idx + 2].y), true));
+#if !SILVERLIGHT
+        BezierSegment bezierSegment = new BezierSegment(
+                              new System.Windows.Point(points[idx].x, points[idx].y),
+                              new System.Windows.Point(points[idx + 1].x, points[idx + 1].y),
+                              new System.Windows.Point(points[idx + 2].x, points[idx + 2].y), true);
+#else
+        BezierSegment bezierSegment = new BezierSegment();
+        bezierSegment.Point1 = new Point(points[idx].x, points[idx].y);
+        bezierSegment.Point2 = new Point(points[idx + 1].x, points[idx + 1].y);
+        bezierSegment.Point3 = new Point(points[idx + 2].x, points[idx + 2].y);
+#endif
+        figure.Segments.Add(bezierSegment);
+      }
 #endif
     }
 
@@ -511,7 +593,16 @@ namespace PdfSharp.Drawing
       if (figure.Segments.Count == 0)
         figure.StartPoint = new System.Windows.Point(points[0].x, points[0].y);
       else
-        figure.Segments.Add(new LineSegment(new System.Windows.Point(points[0].x, points[0].y), true));
+      {
+        // figure.Segments.Add(new LineSegment(new System.Windows.Point(points[0].x, points[0].y), true));
+#if !SILVERLIGHT
+        LineSegment lineSegment = new LineSegment(new System.Windows.Point(points[0].x, points[0].y), true);
+#else
+        LineSegment lineSegment = new LineSegment();
+        lineSegment.Point = new Point(points[0].x, points[0].y);
+#endif
+        figure.Segments.Add(lineSegment);
+      }
 
       if (count == 2)
       {
@@ -648,8 +739,29 @@ namespace PdfSharp.Drawing
       if (figure.Segments.Count == 0)
         figure.StartPoint = point1.ToPoint();
       else
-        figure.Segments.Add(new LineSegment(point1.ToPoint(), true));
-      figure.Segments.Add(new ArcSegment(point2.ToPoint(), size.ToSize(), rotationAngle, isLargeArg, sweepDirection, true));
+      {
+        // figure.Segments.Add(new LineSegment(point1.ToPoint(), true));
+#if !SILVERLIGHT
+        LineSegment lineSegment = new LineSegment(point1.ToPoint(), true);
+#else
+        LineSegment lineSegment = new LineSegment();
+        lineSegment.Point = point1.ToPoint();
+#endif
+        figure.Segments.Add(lineSegment);
+      }
+
+      // figure.Segments.Add(new ArcSegment(point2.ToPoint(), size.ToSize(), rotationAngle, isLargeArg, sweepDirection, true));
+#if !SILVERLIGHT
+      ArcSegment arcSegment = new ArcSegment(point2.ToPoint(), size.ToSize(), rotationAngle, isLargeArg, sweepDirection, true);
+#else
+      ArcSegment arcSegment = new ArcSegment();
+      arcSegment.Point = point2.ToPoint();
+      arcSegment.Size = size.ToSize();
+      arcSegment.RotationAngle = rotationAngle;
+      arcSegment.IsLargeArc = isLargeArg;
+      arcSegment.SweepDirection = sweepDirection;
+#endif
+      figure.Segments.Add(arcSegment);
     }
 #endif
 
@@ -687,9 +799,25 @@ namespace PdfSharp.Drawing
       StartFigure();
       PathFigure figure = CurrentPathFigure;
       figure.StartPoint = new System.Windows.Point(rect.x, rect.y);
-      figure.Segments.Add(new LineSegment(new System.Windows.Point(rect.x + rect.width, rect.y), true));
-      figure.Segments.Add(new LineSegment(new System.Windows.Point(rect.x + rect.width, rect.y + rect.height), true));
-      figure.Segments.Add(new LineSegment(new System.Windows.Point(rect.x, rect.y + rect.height), true));
+
+      // figure.Segments.Add(new LineSegment(new System.Windows.Point(rect.x + rect.width, rect.y), true));
+      // figure.Segments.Add(new LineSegment(new System.Windows.Point(rect.x + rect.width, rect.y + rect.height), true));
+      // figure.Segments.Add(new LineSegment(new System.Windows.Point(rect.x, rect.y + rect.height), true));
+#if !SILVERLIGHT
+      LineSegment lineSegment1 = new LineSegment(new System.Windows.Point(rect.x + rect.width, rect.y), true);
+      LineSegment lineSegment2 = new LineSegment(new System.Windows.Point(rect.x + rect.width, rect.y + rect.height), true);
+      LineSegment lineSegment3 = new LineSegment(new System.Windows.Point(rect.x, rect.y + rect.height), true);
+#else
+      LineSegment lineSegment1 = new LineSegment();
+      lineSegment1.Point = new Point(rect.x + rect.width, rect.y);
+      LineSegment lineSegment2 = new LineSegment();
+      lineSegment2.Point = new Point(rect.x + rect.width, rect.y + rect.height);
+      LineSegment lineSegment3 = new LineSegment();
+      lineSegment3.Point = new Point(rect.x, rect.y + rect.height);
+#endif
+      figure.Segments.Add(lineSegment1);
+      figure.Segments.Add(lineSegment2);
+      figure.Segments.Add(lineSegment3);
       CloseFigure();
 #endif
     }
@@ -754,9 +882,25 @@ namespace PdfSharp.Drawing
         PathFigure figure = CurrentPathFigure;
         XRect rect = rects[idx];
         figure.StartPoint = new System.Windows.Point(rect.x, rect.y);
-        figure.Segments.Add(new LineSegment(new System.Windows.Point(rect.x + rect.width, rect.y), true));
-        figure.Segments.Add(new LineSegment(new System.Windows.Point(rect.x + rect.width, rect.y + rect.height), true));
-        figure.Segments.Add(new LineSegment(new System.Windows.Point(rect.x, rect.y + rect.height), true));
+
+        // figure.Segments.Add(new LineSegment(new System.Windows.Point(rect.x + rect.width, rect.y), true));
+        // figure.Segments.Add(new LineSegment(new System.Windows.Point(rect.x + rect.width, rect.y + rect.height), true));
+        // figure.Segments.Add(new LineSegment(new System.Windows.Point(rect.x, rect.y + rect.height), true));
+#if !SILVERLIGHT
+        LineSegment lineSegment1 = new LineSegment(new System.Windows.Point(rect.x + rect.width, rect.y), true);
+        LineSegment lineSegment2 = new LineSegment(new System.Windows.Point(rect.x + rect.width, rect.y + rect.height), true);
+        LineSegment lineSegment3 = new LineSegment(new System.Windows.Point(rect.x, rect.y + rect.height), true);
+#else
+        LineSegment lineSegment1 = new LineSegment();
+        lineSegment1.Point = new Point(rect.x + rect.width, rect.y);
+        LineSegment lineSegment2 = new LineSegment();
+        lineSegment2.Point = new Point(rect.x + rect.width, rect.y + rect.height);
+        LineSegment lineSegment3 = new LineSegment();
+        lineSegment3.Point = new Point(rect.x, rect.y + rect.height);
+#endif
+        figure.Segments.Add(lineSegment1);
+        figure.Segments.Add(lineSegment2);
+        figure.Segments.Add(lineSegment3);
         CloseFigure();
 #endif
       }
@@ -766,7 +910,7 @@ namespace PdfSharp.Drawing
 
 #if GDI
     /// <summary>
-    /// Adds a rectangle with rounded cornes to this path.
+    /// Adds a rectangle with rounded corners to this path.
     /// </summary>
     public void AddRoundedRectangle(Rectangle rect, System.Drawing.Size ellipseSize)
     {
@@ -777,7 +921,7 @@ namespace PdfSharp.Drawing
 
 #if WPF
     /// <summary>
-    /// Adds a rectangle with rounded cornes to this path.
+    /// Adds a rectangle with rounded corners to this path.
     /// </summary>
     public void AddRoundedRectangle(Rect rect, System.Windows.Size ellipseSize)
     {
@@ -788,7 +932,7 @@ namespace PdfSharp.Drawing
 
 #if GDI
     /// <summary>
-    /// Adds a rectangle with rounded cornes to this path.
+    /// Adds a rectangle with rounded corners to this path.
     /// </summary>
     public void AddRoundedRectangle(RectangleF rect, SizeF ellipseSize)
     {
@@ -799,7 +943,7 @@ namespace PdfSharp.Drawing
 
 #if GDI
     /// <summary>
-    /// Adds a rectangle with rounded cornes to this path.
+    /// Adds a rectangle with rounded corners to this path.
     /// </summary>
     public void AddRoundedRectangle(XRect rect, SizeF ellipseSize)
     {
@@ -809,7 +953,7 @@ namespace PdfSharp.Drawing
 #endif
 
     /// <summary>
-    /// Adds a rectangle with rounded cornes to this path.
+    /// Adds a rectangle with rounded corners to this path.
     /// </summary>
     public void AddRoundedRectangle(int x, int y, int width, int height, int ellipseWidth, int ellipseHeight)
     {
@@ -817,7 +961,7 @@ namespace PdfSharp.Drawing
     }
 
     /// <summary>
-    /// Adds a rectangle with rounded cornes to this path.
+    /// Adds a rectangle with rounded corners to this path.
     /// </summary>
     public void AddRoundedRectangle(double x, double y, double width, double height, double ellipseWidth, double ellipseHeight)
     {
@@ -834,8 +978,10 @@ namespace PdfSharp.Drawing
       StartFigure();
       PathFigure figure = CurrentPathFigure;
       figure.StartPoint = new System.Windows.Point(x + ex, y);
+
+#if !SILVERLIGHT
       figure.Segments.Add(new LineSegment(new System.Windows.Point(x + width - ex, y), true));
-      // TODOWPF
+      // TODOWPF XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXx
       figure.Segments.Add(new ArcSegment(new System.Windows.Point(x + width, y + ey), new System.Windows.Size(ex, ey), 0, false, SweepDirection.Clockwise, true));
       //figure.Segments.Add(new LineSegment(new System.Windows.Point(x + width, y + ey), true));
 
@@ -853,7 +999,9 @@ namespace PdfSharp.Drawing
       // TODOWPF
       figure.Segments.Add(new ArcSegment(new System.Windows.Point(x + ex, y), new System.Windows.Size(ex, ey), 0, false, SweepDirection.Clockwise, true));
       //figure.Segments.Add(new LineSegment(new System.Windows.Point(x + ex, y), true));
-
+#else
+      // AGHACK
+#endif
       CloseFigure();
 #endif
     }
@@ -906,7 +1054,18 @@ namespace PdfSharp.Drawing
 #endif
 #if WPF
       StartFigure();
+      //this.pathGeometry.AddGeometry(new EllipseGeometry(new Rect(x, y, width, height)));
+#if !SILVERLIGHT
       this.pathGeometry.AddGeometry(new EllipseGeometry(new Rect(x, y, width, height)));
+      //EllipseGeometry ellipseGeometry = new EllipseGeometry(new Rect(x, y, width, height));
+      //this.pa thGeometry..AddGeometry(ellipseGeometry);
+#else
+      // AGHACK: No AddGeometry in Silverlight version of PathGeometry
+      //EllipseGeometry ellipseGeometry = new EllipseGeometry();
+      //ellipseGeometry.Center = new Point((x + width) / 2, (y + height) / 2);
+      //ellipseGeometry.RadiusX = width / 2;
+      //ellipseGeometry.RadiusY = height / 2;
+#endif
 #endif
     }
 
@@ -928,7 +1087,13 @@ namespace PdfSharp.Drawing
     /// </summary>
     public void AddPolygon(System.Windows.Point[] points)
     {
-      //  TODOWPF
+      // TODO: fill mode unclear here
+      StartFigure();
+#if !SILVERLIGHT
+      this.pathGeometry.AddGeometry(GeometryHelper.CreatePolygonGeometry(points, XFillMode.Alternate, true));
+#else
+      // AGHACK: No AddGeometry in Silverlight version of PathGeometry
+#endif
     }
 #endif
 
@@ -952,7 +1117,11 @@ namespace PdfSharp.Drawing
 #endif
 #if WPF
       StartFigure();
-      this.pathGeometry.AddGeometry(GeometryHelper.CreatePolygonGeometry(XGraphics.MakePointArray(points), XFillMode.Alternate, false));
+#if !SILVERLIGHT
+      this.pathGeometry.AddGeometry(GeometryHelper.CreatePolygonGeometry(XGraphics.MakePointArray(points), XFillMode.Alternate, true));
+#else
+      // AGHACK: No AddGeometry in Silverlight version of PathGeometry
+#endif
 #endif
     }
 
@@ -1124,7 +1293,11 @@ namespace PdfSharp.Drawing
       this.gdipPath.AddPath(path.gdipPath, connect);
 #endif
 #if WPF
+#if !SILVERLIGHT
       this.pathGeometry.AddGeometry(path.pathGeometry);
+#else
+      // AGHACK: No AddGeometry in Silverlight version of PathGeometry
+#endif
 #endif
     }
 
@@ -1136,9 +1309,7 @@ namespace PdfSharp.Drawing
     /// </summary>
     public void AddString(string s, XFontFamily family, XFontStyle style, double emSize, System.Drawing.Point origin, XStringFormat format)
     {
-      //this.gdipPath.AddString(s, family.gdiFamily, (int)style, (float)emSize, origin, format.RealizeGdiStringFormat());
-      // TODOWPF
-      AddString(s, family, style, emSize, origin, format);
+      AddString(s, family, style, emSize, new XRect(origin.X, origin.Y, 0, 0), format);
     }
 #endif
 
@@ -1149,11 +1320,6 @@ namespace PdfSharp.Drawing
     public void AddString(string s, XFontFamily family, XFontStyle style, double emSize, System.Windows.Point origin, XStringFormat format)
     {
       AddString(s, family, style, emSize, new XPoint(origin), format);
-      //// TODOWPF
-      //Typeface typeface = FontHelper.CreateTypeface(family, style);
-      //FormattedText formattedText = new FormattedText(s, null, FlowDirection.LeftToRight, typeface, emSize, System.Windows.Media.Brushes.Black);
-      //Geometry geo = formattedText.BuildGeometry(origin);
-      //this.pathGeometry.AddGeometry(geo);
     }
 #endif
 
@@ -1163,8 +1329,6 @@ namespace PdfSharp.Drawing
     /// </summary>
     public void AddString(string s, XFontFamily family, XFontStyle style, double emSize, PointF origin, XStringFormat format)
     {
-      //this.gdipPath.AddString(s, family.gdiFamily, (int)style, (float)emSize, origin, format.RealizeGdiStringFormat());
-      // TODOWPF
       AddString(s, family, style, emSize, new XRect(origin.X, origin.Y, 0, 0), format);
     }
 #endif
@@ -1177,15 +1341,18 @@ namespace PdfSharp.Drawing
       try
       {
 #if GDI
-        // TODOWPF
         this.gdipPath.AddString(s, family.gdiFamily, (int)style, (float)emSize, origin.ToPointF(), format.RealizeGdiStringFormat());
 #endif
 #if WPF
-        Typeface typeface = FontHelper.CreateTypeface(family, style);
-        FormattedText ft = new FormattedText(s, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, typeface, emSize,
-          System.Windows.Media.Brushes.Black);
-        Geometry geo = ft.BuildGeometry(origin);
+#if !SILVERLIGHT
+        Typeface typeface = FontHelper.CreateTypeface(family.wpfFamily, style);
+        //FormattedText ft = new FormattedText(s, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, typeface, emSize, System.Windows.Media.Brushes.Black);
+        FormattedText formattedText = FontHelper.CreateFormattedText(s, typeface, emSize, System.Windows.Media.Brushes.Black);
+        Geometry geo = formattedText.BuildGeometry(origin);
         this.pathGeometry.AddGeometry(geo);
+#else
+        // AGHACK: 
+#endif
 #endif
       }
       catch { }
@@ -1197,7 +1364,6 @@ namespace PdfSharp.Drawing
     /// </summary>
     public void AddString(string s, XFontFamily family, XFontStyle style, double emSize, Rectangle layoutRect, XStringFormat format)
     {
-      // TODOWPF
       this.gdipPath.AddString(s, family.gdiFamily, (int)style, (float)emSize, layoutRect, format.RealizeGdiStringFormat());
     }
 #endif
@@ -1208,7 +1374,6 @@ namespace PdfSharp.Drawing
     /// </summary>
     public void AddString(string s, XFontFamily family, XFontStyle style, double emSize, RectangleF layoutRect, XStringFormat format)
     {
-      // TODOWPF
       this.gdipPath.AddString(s, family.gdiFamily, (int)style, (float)emSize, layoutRect, format.RealizeGdiStringFormat());
     }
 #endif
@@ -1261,6 +1426,7 @@ namespace PdfSharp.Drawing
       this.gdipPath.AddString(s, family.gdiFamily, (int)style, (float)emSize, rc, format.RealizeGdiStringFormat());
 #endif
 #if WPF && !GDI
+#if !SILVERLIGHT
       // Just a first sketch, but currently we do not need it and there is enough to do...
       double x = layoutRect.X;
       double y = layoutRect.Y;
@@ -1280,9 +1446,9 @@ namespace PdfSharp.Drawing
       bool strikeout = (style & XFontStyle.Strikeout) != 0;
       bool underline = (style & XFontStyle.Underline) != 0;
 
-      Typeface typeface = FontHelper.CreateTypeface(family, style);
-      FormattedText formattedText = new FormattedText(s, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, typeface, emSize,
-        System.Windows.Media.Brushes.Black);
+      Typeface typeface = FontHelper.CreateTypeface(family.wpfFamily, style);
+      //FormattedText formattedText = new FormattedText(s, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, typeface, emSize, System.Windows.Media.Brushes.Black);
+      FormattedText formattedText = FontHelper.CreateFormattedText(s, typeface, emSize, System.Windows.Media.Brushes.Black);
 
       switch (format.Alignment)
       {
@@ -1376,6 +1542,9 @@ namespace PdfSharp.Drawing
 
       Geometry geo = formattedText.BuildGeometry(new Point(x, y));
       this.pathGeometry.AddGeometry(geo);
+#else
+      // AGHACK
+#endif
 #endif
     }
 
@@ -1455,7 +1624,11 @@ namespace PdfSharp.Drawing
       this.gdipPath.Flatten();
 #endif
 #if WPF
+#if !SILVERLIGHT
       this.pathGeometry = this.pathGeometry.GetFlattenedPathGeometry();
+#else
+      // AGHACK
+#endif
 #endif
     }
 
@@ -1468,8 +1641,12 @@ namespace PdfSharp.Drawing
       this.gdipPath.Flatten(matrix.ToGdiMatrix());
 #endif
 #if WPF
+#if !SILVERLIGHT
       this.pathGeometry = this.pathGeometry.GetFlattenedPathGeometry();
       this.pathGeometry.Transform = new MatrixTransform(matrix.ToWpfMatrix());
+#else
+      // AGHACK
+#endif
 #endif
     }
 
@@ -1482,8 +1659,14 @@ namespace PdfSharp.Drawing
       this.gdipPath.Flatten(matrix.ToGdiMatrix(), (float)flatness);
 #endif
 #if WPF
-      // TODOWPF: matrix
+#if !SILVERLIGHT
       this.pathGeometry = this.pathGeometry.GetFlattenedPathGeometry();
+      // TODO: matrix handling not yet tested
+      if (!matrix.IsIdentity)
+        this.pathGeometry.Transform = new MatrixTransform(matrix.ToWpfMatrix());
+#else
+      // AGHACK
+#endif
 #endif
     }
 
@@ -1499,7 +1682,11 @@ namespace PdfSharp.Drawing
       this.gdipPath.Widen(pen.RealizeGdiPen());
 #endif
 #if WPF
+#if !SILVERLIGHT
       this.pathGeometry = this.pathGeometry.GetWidenedPathGeometry(pen.RealizeWpfPen());
+#else
+      // AGHACK
+#endif
 #endif
     }
 
@@ -1513,7 +1700,11 @@ namespace PdfSharp.Drawing
       this.gdipPath.Widen(pen.RealizeGdiPen(), matrix.ToGdiMatrix());
 #endif
 #if WPF
+#if !SILVERLIGHT
       this.pathGeometry = this.pathGeometry.GetWidenedPathGeometry(pen.RealizeWpfPen());
+#else
+      // AGHACK
+#endif
 #endif
     }
 
@@ -1527,7 +1718,11 @@ namespace PdfSharp.Drawing
       this.gdipPath.Widen(pen.RealizeGdiPen(), matrix.ToGdiMatrix(), (float)flatness);
 #endif
 #if WPF
+#if !SILVERLIGHT
       this.pathGeometry = this.pathGeometry.GetWidenedPathGeometry(pen.RealizeWpfPen());
+#else
+      // AGHACK
+#endif
 #endif
     }
 
diff --git a/lib/PdfSharp/PdfSharp.Drawing/XGraphicsPathInternals.cs b/lib/PdfSharp/PdfSharp.Drawing/XGraphicsPathInternals.cs
index 942a183..b11c4c1 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/XGraphicsPathInternals.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/XGraphicsPathInternals.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Drawing/XGraphicsPathItem.cs b/lib/PdfSharp/PdfSharp.Drawing/XGraphicsPathItem.cs
index 08c3a4f..f93cbe6 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/XGraphicsPathItem.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/XGraphicsPathItem.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Drawing/XGraphicsState.cs b/lib/PdfSharp/PdfSharp.Drawing/XGraphicsState.cs
index acc4f9e..f5ee1d6 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/XGraphicsState.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/XGraphicsState.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Drawing/XImage.cs b/lib/PdfSharp/PdfSharp.Drawing/XImage.cs
index 5285dc1..3af46da 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/XImage.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/XImage.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -42,8 +42,9 @@ using System.Windows;
 using System.Windows.Media;
 using System.Windows.Media.Imaging;
 #endif
+using PdfSharp;
 using PdfSharp.Internal;
-using PdfSharp.Fonts.TrueType;
+using PdfSharp.Fonts.OpenType;
 using PdfSharp.Pdf;
 using PdfSharp.Pdf.IO;
 using PdfSharp.Pdf.Advanced;
@@ -80,7 +81,7 @@ namespace PdfSharp.Drawing
     }
 #endif
 
-#if WPF
+#if WPF && !SILVERLIGHT
     /// <summary>
     /// Initializes a new instance of the <see cref="XImage"/> class from a WPF image.
     /// </summary>
@@ -107,8 +108,10 @@ namespace PdfSharp.Drawing
 #if GDI
       this.gdiImage = Image.FromFile(path);
 #endif
-#if WPF
-      this.wpfImage = new BitmapImage(new Uri(path));
+#if WPF && !SILVERLIGHT
+      //BitmapSource.Create()
+      // BUG: BitmapImage locks the file
+      this.wpfImage = new BitmapImage(new Uri(path));  // AGHACK
 #endif
 
 #if false
@@ -170,7 +173,7 @@ namespace PdfSharp.Drawing
     }
 #endif
 
-#if WPF
+#if WPF && !SILVERLIGHT
     /// <summary>
     /// Conversion from BitmapSource to XImage.
     /// </summary>
@@ -246,44 +249,55 @@ namespace PdfSharp.Drawing
       }
 #endif
 #if WPF
+#if !SILVERLIGHT
       if (this.wpfImage != null)
       {
         string pixelFormat = this.wpfImage.Format.ToString();
+        string filename = GetImageFilename(this.wpfImage);
+        // WPF treats all images as images.
+        // We give JPEG images a special treatment.
+        // Test if it's a JPEG:
+        bool isJpeg = IsJpeg; // TestJpeg(filename);
+        if (isJpeg)
+        {
+          this.format = XImageFormat.Jpeg;
+          return;
+        }
+
         switch (pixelFormat)
         {
           case "Bgr32":
           case "Bgra32":
           case "Pbgra32":
-          case "{B96B3CAB-0728-11D3-9D7B-0000F81EF32E}":  // bmp
-          case "{B96B3CAF-0728-11D3-9D7B-0000F81EF32E}":  // png
             this.format = XImageFormat.Png;
             break;
 
-          case "{B96B3CAE-0728-11D3-9D7B-0000F81EF32E}":  // jpeg
-            this.format = XImageFormat.Jpeg;
-            break;
+          //case "{B96B3CAE-0728-11D3-9D7B-0000F81EF32E}":  // jpeg
+          //  this.format = XImageFormat.Jpeg;
+          //  break;
 
-          case "{B96B3CB0-0728-11D3-9D7B-0000F81EF32E}":  // gif
-          case"BlackWhite":
+          //case "{B96B3CB0-0728-11D3-9D7B-0000F81EF32E}":  // gif
+          case "BlackWhite":
           case "Indexed1":
           case "Indexed4":
           case "Indexed8":
+          case "Gray8":
             this.format = XImageFormat.Gif;
             break;
 
-          case "{B96B3CB1-0728-11D3-9D7B-0000F81EF32E}":  // tiff
-            this.format = XImageFormat.Tiff;
-            break;
+          //case "{B96B3CB1-0728-11D3-9D7B-0000F81EF32E}":  // tiff
+          //  this.format = XImageFormat.Tiff;
+          //  break;
 
-          case "{B96B3CB5-0728-11D3-9D7B-0000F81EF32E}":  // icon
-            this.format = XImageFormat.Icon;
-            break;
+          //case "{B96B3CB5-0728-11D3-9D7B-0000F81EF32E}":  // icon
+          //  this.format = XImageFormat.Icon;
+          //  break;
 
-          case "{B96B3CAC-0728-11D3-9D7B-0000F81EF32E}":  // emf
-          case "{B96B3CAD-0728-11D3-9D7B-0000F81EF32E}":  // wmf
-          case "{B96B3CB2-0728-11D3-9D7B-0000F81EF32E}":  // exif
-          case "{B96B3CB3-0728-11D3-9D7B-0000F81EF32E}":  // photoCD
-          case "{B96B3CB4-0728-11D3-9D7B-0000F81EF32E}":  // flashPIX
+          //case "{B96B3CAC-0728-11D3-9D7B-0000F81EF32E}":  // emf
+          //case "{B96B3CAD-0728-11D3-9D7B-0000F81EF32E}":  // wmf
+          //case "{B96B3CB2-0728-11D3-9D7B-0000F81EF32E}":  // exif
+          //case "{B96B3CB3-0728-11D3-9D7B-0000F81EF32E}":  // photoCD
+          //case "{B96B3CB4-0728-11D3-9D7B-0000F81EF32E}":  // flashPIX
 
           default:
             Debug.Assert(false, "Unknown pixel format: " + pixelFormat);
@@ -291,11 +305,173 @@ namespace PdfSharp.Drawing
             break;// throw new InvalidOperationException("Unsupported image format.");
         }
       }
+#else
+      // AGHACK
+#endif
 #endif
     }
 
+#if WPF
+    /// <summary>
+    /// Gets the image filename.
+    /// </summary>
+    /// <param name="bitmapSource">The bitmap source.</param>
+    internal static string GetImageFilename(BitmapSource bitmapSource)
+    {
+      string filename = bitmapSource.ToString();
+      filename = UrlDecodeStringFromStringInternal(filename);
+      if (filename.StartsWith("file:///"))
+        filename = filename.Substring(8); // Remove all 3 slashes!
+      else if (filename.StartsWith("file://"))
+        filename = filename.Substring(5); // Keep 2 slashes (UNC path)
+      return filename;
+    }
+
+    private static string UrlDecodeStringFromStringInternal(string s/*, Encoding e*/)
+    {
+      int length = s.Length;
+      string result = "";
+      for (int i = 0; i < length; i++)
+      {
+        char ch = s[i];
+        if (ch == '+')
+        {
+          ch = ' ';
+        }
+        else if ((ch == '%') && (i < (length - 2)))
+        {
+          if ((s[i + 1] == 'u') && (i < (length - 5)))
+          {
+            int num3 = HexToInt(s[i + 2]);
+            int num4 = HexToInt(s[i + 3]);
+            int num5 = HexToInt(s[i + 4]);
+            int num6 = HexToInt(s[i + 5]);
+            if (((num3 < 0) || (num4 < 0)) || ((num5 < 0) || (num6 < 0)))
+            {
+              goto AddByte;
+            }
+            ch = (char)((((num3 << 12) | (num4 << 8)) | (num5 << 4)) | num6);
+            i += 5;
+            result += ch;
+            continue;
+          }
+          int num7 = HexToInt(s[i + 1]);
+          int num8 = HexToInt(s[i + 2]);
+          if ((num7 >= 0) && (num8 >= 0))
+          {
+            byte b = (byte)((num7 << 4) | num8);
+            i += 2;
+            result += (char)b;
+            continue;
+          }
+        }
+      AddByte:
+        if ((ch & 0xff80) == 0)
+        {
+          result += ch;
+        }
+        else
+        {
+          result += ch;
+        }
+      }
+      return result;
+    }
+
+    private static int HexToInt(char h)
+    {
+      if ((h >= '0') && (h <= '9'))
+      {
+        return (h - '0');
+      }
+      if ((h >= 'a') && (h <= 'f'))
+      {
+        return ((h - 'a') + 10);
+      }
+      if ((h >= 'A') && (h <= 'F'))
+      {
+        return ((h - 'A') + 10);
+      }
+      return -1;
+    }
+#endif
+
+#if WPF
+    /// <summary>
+    /// Tests if a file is a JPEG.
+    /// </summary>
+    /// <param name="filename">The filename.</param>
+    internal static bool TestJpeg(string filename)
+    {
+      byte[] imageBits = null;
+      return ReadJpegFile(filename, 16, ref imageBits);
+    }
+
+    /// <summary>
+    /// Reads the JPEG file.
+    /// </summary>
+    /// <param name="filename">The filename.</param>
+    /// <param name="maxRead">The maximum count of bytes to be read.</param>
+    /// <param name="imageBits">The bytes read from the file.</param>
+    /// <returns>False, if file could not be read or is not a JPEG file.</returns>
+    internal static bool ReadJpegFile(string filename, int maxRead, ref byte[] imageBits)
+    {
+      if (File.Exists(filename))
+      {
+        FileStream fs = null;
+        try
+        {
+          fs = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
+        }
+        catch
+        {
+          return false;
+        }
+
+        if (fs.Length < 16)
+        {
+          fs.Close();
+          return false;
+        }
+        int len = maxRead == -1 ? (int)fs.Length : maxRead;
+        imageBits = new byte[len];
+        fs.Read(imageBits, 0, len);
+        fs.Close();
+        if (imageBits[0] == 0xff &&
+            imageBits[1] == 0xd8 &&
+            imageBits[2] == 0xff &&
+            imageBits[3] == 0xe0 &&
+            imageBits[6] == 0x4a &&
+            imageBits[7] == 0x46 &&
+            imageBits[8] == 0x49 &&
+            imageBits[9] == 0x46 &&
+            imageBits[10] == 0x0)
+        {
+          return true;
+        }
+        // TODO: Exif: find JFIF header
+        if (imageBits[0] == 0xff &&
+            imageBits[1] == 0xd8 &&
+            imageBits[2] == 0xff &&
+            imageBits[3] == 0xe1 /*&&
+            imageBits[6] == 0x4a &&
+            imageBits[7] == 0x46 &&
+            imageBits[8] == 0x49 &&
+            imageBits[9] == 0x46 &&
+            imageBits[10] == 0x0*/)
+        {
+          // Hack: store the file in PDF if extension matches ...
+          string str = filename.ToLower();
+          if (str.EndsWith(".jpg") || str.EndsWith(".jpeg"))
+            return true;
+        }
+      }
+      return false;
+    }
+#endif
+
     /// <summary>
-    /// under construction
+    /// Under construction
     /// </summary>
     public void Dispose()
     {
@@ -319,6 +495,10 @@ namespace PdfSharp.Drawing
       }
 #endif
 #if WPF
+      if (wpfImage != null)
+      {
+        wpfImage = null;
+      }
 #endif
     }
     bool disposed;
@@ -342,7 +522,12 @@ namespace PdfSharp.Drawing
         return this.gdiImage.Width;
 #endif
 #if WPF && !GDI
+#if !SILVERLIGHT
         return this.wpfImage.PixelWidth;
+#else
+        // AGHACK
+        return 100;
+#endif
 #endif
       }
     }
@@ -365,7 +550,12 @@ namespace PdfSharp.Drawing
         return this.gdiImage.Height;
 #endif
 #if WPF && !GDI
+#if !SILVERLIGHT
         return this.wpfImage.PixelHeight;
+#else
+        // AGHACK
+        return 100;
+#endif
 #endif
       }
     }
@@ -388,8 +578,13 @@ namespace PdfSharp.Drawing
         return this.gdiImage.Width * 72 / this.gdiImage.HorizontalResolution;
 #endif
 #if WPF && !GDI
+#if !SILVERLIGHT
         Debug.Assert(Math.Abs(this.wpfImage.PixelWidth * 72 / this.wpfImage.DpiX - this.wpfImage.Width * 72.0 / 96.0) < 0.001);
         return this.wpfImage.Width * 72.0 / 96.0;
+#else
+        // AGHACK
+        return 100;
+#endif
 #endif
       }
     }
@@ -410,9 +605,14 @@ namespace PdfSharp.Drawing
 #if GDI && !WPF
         return this.gdiImage.Height * 72 / this.gdiImage.HorizontalResolution;
 #endif
-#if WPF && !GDI
+#if WPF || SILVERLIGHT && !GDI
+#if !SILVERLIGHT
         Debug.Assert(Math.Abs(this.wpfImage.PixelHeight * 72 / this.wpfImage.DpiY - this.wpfImage.Height * 72.0 / 96.0) < 0.001);
         return this.wpfImage.Height * 72.0 / 96.0;
+#else
+        // AGHACK
+        return 100;
+#endif
 #endif
       }
     }
@@ -434,7 +634,12 @@ namespace PdfSharp.Drawing
         return this.gdiImage.Width;
 #endif
 #if WPF && !GDI
+#if !SILVERLIGHT
         return this.wpfImage.PixelWidth;
+#else
+        // AGHACK
+        return 100;
+#endif
 #endif
       }
     }
@@ -456,7 +661,12 @@ namespace PdfSharp.Drawing
         return this.gdiImage.Height;
 #endif
 #if WPF && !GDI
+#if !SILVERLIGHT
         return this.wpfImage.PixelHeight;
+#else
+        // AGHACK
+        return 100;
+#endif
 #endif
       }
     }
@@ -486,7 +696,12 @@ namespace PdfSharp.Drawing
         return this.gdiImage.HorizontalResolution;
 #endif
 #if WPF && !GDI
+#if !SILVERLIGHT
         return this.wpfImage.DpiX; //.PixelWidth * 96.0 / this.wpfImage.Width;
+#else
+        // AGHACK
+        return 96;
+#endif
 #endif
       }
     }
@@ -508,7 +723,12 @@ namespace PdfSharp.Drawing
         return this.gdiImage.VerticalResolution;
 #endif
 #if WPF && !GDI
+#if !SILVERLIGHT
         return this.wpfImage.DpiY; //.PixelHeight * 96.0 / this.wpfImage.Height;
+#else
+        // AGHACK
+        return 96;
+#endif
 #endif
       }
     }
@@ -532,6 +752,92 @@ namespace PdfSharp.Drawing
     }
     XImageFormat format;
 
+#if WPF
+    /// <summary>
+    /// Gets a value indicating whether this image is JPEG.
+    /// </summary>
+    /// <value><c>true</c> if this image is JPEG; otherwise, <c>false</c>.</value>
+    public virtual bool IsJpeg
+    {
+#if !SILVERLIGHT
+      //get { if (!isJpeg.HasValue) InitializeGdiHelper(); return isJpeg.HasValue ? isJpeg.Value : false; }
+      get { if (!isJpeg.HasValue) InitializeJpegQuickTest(); return isJpeg.HasValue ? isJpeg.Value : false; }
+      //set { isJpeg = value; }
+#else
+      get { return false; } // AGHACK
+#endif
+    }
+    private bool? isJpeg;
+
+    /// <summary>
+    /// Gets a value indicating whether this image is cmyk.
+    /// </summary>
+    /// <value><c>true</c> if this image is cmyk; otherwise, <c>false</c>.</value>
+    public virtual bool IsCmyk
+    {
+#if !SILVERLIGHT
+      get { if (!isCmyk.HasValue) InitializeGdiHelper(); return isCmyk.HasValue ? isCmyk.Value : false; }
+      //set { isCmyk = value; }
+#else
+      get { return false; } // AGHACK
+#endif
+    }
+    private bool? isCmyk;
+
+#if !SILVERLIGHT
+    /// <summary>
+    /// Gets the JPEG memory stream (if IsJpeg returns true).
+    /// </summary>
+    /// <value>The memory.</value>
+    public virtual MemoryStream Memory
+    {
+      get { if (!isCmyk.HasValue) InitializeGdiHelper(); return memory; }
+      //set { memory = value; }
+    }
+    MemoryStream memory = null;
+
+    /// <summary>
+    /// Determines if an image is JPEG w/o creating an Image object.
+    /// </summary>
+    private void InitializeJpegQuickTest()
+    {
+      isJpeg = TestJpeg(GetImageFilename(wpfImage));
+    }
+
+    /// <summary>
+    /// Initializes the GDI helper.
+    /// We use GDI+ to detect if image is JPEG.
+    /// If so, we also determine if it's CMYK and we read the image bytes.
+    /// </summary>
+    private void InitializeGdiHelper()
+    {
+      if (!isCmyk.HasValue)
+      {
+        try
+        {
+          using (System.Drawing.Image image = new System.Drawing.Bitmap(GetImageFilename(wpfImage)))
+          {
+            string guid = image.RawFormat.Guid.ToString("B").ToUpper();
+            isJpeg = guid == "{B96B3CAE-0728-11D3-9D7B-0000F81EF32E}";
+            isCmyk = (image.Flags & ((int)System.Drawing.Imaging.ImageFlags.ColorSpaceCmyk | (int)System.Drawing.Imaging.ImageFlags.ColorSpaceYcck)) != 0;
+            if (isJpeg.Value)
+            {
+              memory = new MemoryStream();
+              image.Save(memory, System.Drawing.Imaging.ImageFormat.Jpeg);
+              if ((int)memory.Length == 0)
+              {
+                memory = null;
+              }
+            }
+          }
+        }
+        catch { }
+      }
+    }
+#endif    
+#endif    
+
+
 #if DEBUG_
     // TEST
     internal void CreateAllImages(string name)
diff --git a/lib/PdfSharp/PdfSharp.Drawing/XImageFormat.cs b/lib/PdfSharp/PdfSharp.Drawing/XImageFormat.cs
index 3ac1920..386d431 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/XImageFormat.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/XImageFormat.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Drawing/XKnownColorTable.cs b/lib/PdfSharp/PdfSharp.Drawing/XKnownColorTable.cs
index 6b6caa7..f383f6a 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/XKnownColorTable.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/XKnownColorTable.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Drawing/XLinearGradientBrush.cs b/lib/PdfSharp/PdfSharp.Drawing/XLinearGradientBrush.cs
index ac723a3..40d2f5e 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/XLinearGradientBrush.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/XLinearGradientBrush.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -38,6 +38,7 @@ using System.Drawing.Drawing2D;
 using System.Windows;
 using System.Windows.Media;
 #endif
+using PdfSharp;
 using PdfSharp.Internal;
 
 namespace PdfSharp.Drawing
@@ -109,6 +110,9 @@ namespace PdfSharp.Drawing
 #endif
 
 #if WPF
+    /// <summary>
+    /// Initializes a new instance of the <see cref="XLinearGradientBrush"/> class.
+    /// </summary>
     public XLinearGradientBrush(Rect rect, XColor color1, XColor color2, XLinearGradientMode linearGradientMode)
       : this(new XRect(rect), color1, color2, linearGradientMode)
     {
@@ -212,7 +216,7 @@ namespace PdfSharp.Drawing
     }
 
     /// <summary>
-    /// Multiplay the brush tranformation matrix with the specified matrix.
+    /// Multiply the brush transformation matrix with the specified matrix.
     /// </summary>
     public void MultiplyTransform(XMatrix matrix)
     {
@@ -220,7 +224,7 @@ namespace PdfSharp.Drawing
     }
 
     /// <summary>
-    /// Multiplay the brush tranformation matrix with the specified matrix.
+    /// Multiply the brush transformation matrix with the specified matrix.
     /// </summary>
     public void MultiplyTransform(XMatrix matrix, XMatrixOrder order)
     {
@@ -228,11 +232,11 @@ namespace PdfSharp.Drawing
     }
 
     /// <summary>
-    /// Resets the brush tranformation matrix with identity matrix.
+    /// Resets the brush transformation matrix with identity matrix.
     /// </summary>
     public void ResetTransform()
     {
-      this.matrix = XMatrix.Identity;
+      this.matrix = new XMatrix();  //XMatrix.Identity;
     }
 
     //public void SetBlendTriangularShape(double focus);
@@ -291,19 +295,63 @@ namespace PdfSharp.Drawing
       System.Windows.Media.LinearGradientBrush brush;
       if (this.useRect)
       {
+#if !SILVERLIGHT
         brush = new System.Windows.Media.LinearGradientBrush(this.color1.ToWpfColor(), this.color2.ToWpfColor(), new System.Windows.Point(0, 0), new System.Windows.Point(1,1));// this.rect.TopLeft, this.rect.BottomRight);
         //brush = new System.Drawing.Drawing2D.LinearGradientBrush(this.rect.ToRectangleF(),
         //  this.color1.ToGdiColor(), this.color2.ToGdiColor(), (LinearGradientMode)this.linearGradientMode);
+#else
+        GradientStop gs1 = new GradientStop();
+        gs1.Color = this.color1.ToWpfColor();
+        gs1.Offset = 0;
+
+        GradientStop gs2 = new GradientStop();
+        gs2.Color = this.color2.ToWpfColor();
+        gs2.Offset = 1;
+
+        GradientStopCollection gsc = new GradientStopCollection();
+        gsc.Add(gs1);
+        gsc.Add(gs2);
+
+        brush = new LinearGradientBrush(gsc, 0);
+        brush.StartPoint = new Point(0, 0);
+        brush.EndPoint = new Point(1, 1);
+#endif
       }
       else
       {
+#if !SILVERLIGHT
         brush = new System.Windows.Media.LinearGradientBrush(this.color1.ToWpfColor(), this.color2.ToWpfColor(), this.point1, this.point2);
         //brush = new System.Drawing.Drawing2D.LinearGradientBrush(
         //  this.point1.ToPointF(), this.point2.ToPointF(),
         //  this.color1.ToGdiColor(), this.color2.ToGdiColor());
+#else
+        GradientStop gs1 = new GradientStop();
+        gs1.Color = this.color1.ToWpfColor();
+        gs1.Offset = 0;
+
+        GradientStop gs2 = new GradientStop();
+        gs2.Color = this.color2.ToWpfColor();
+        gs2.Offset = 1;
+
+        GradientStopCollection gsc = new GradientStopCollection();
+        gsc.Add(gs1);
+        gsc.Add(gs2);
+
+        brush = new LinearGradientBrush(gsc, 0);
+        brush.StartPoint = this.point1;
+        brush.EndPoint = this.point2;
+#endif
       }
       if (!this.matrix.IsIdentity)
+      {
+#if !SILVERLIGHT
         brush.Transform = new MatrixTransform(this.matrix.ToWpfMatrix());
+#else
+        MatrixTransform transform = new MatrixTransform();
+        transform.Matrix = this.matrix.ToWpfMatrix();
+        brush.Transform = transform;
+#endif
+      }
       return brush;  //this.brush;
     }
 #endif
@@ -322,7 +370,7 @@ namespace PdfSharp.Drawing
     internal XRect rect;
     internal XLinearGradientMode linearGradientMode;
 
-    internal XMatrix matrix = XMatrix.Identity;
+    internal XMatrix matrix;
     //bool dirty = true;
     //LinearGradientBrush brush;
   }
diff --git a/lib/PdfSharp/PdfSharp.Drawing/XMatrix.cs b/lib/PdfSharp/PdfSharp.Drawing/XMatrix.cs
index e6ffc3b..86475ff 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/XMatrix.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/XMatrix.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -42,11 +42,9 @@ using System.Windows.Media;
 #endif
 using PdfSharp.Internal;
 
-#pragma warning disable 1591
-
+// ReSharper disable RedundantNameQualifier
 namespace PdfSharp.Drawing
 {
-#if true
   /// <summary>
   /// Represents a 3-by-3 matrix that represents an affine 2D transformation.
   /// </summary>
@@ -96,6 +94,22 @@ namespace PdfSharp.Drawing
     }
 
     /// <summary>
+    /// Fixes a bug that XMatrixTypes.Identity is not handled correctly in some cases.
+    /// </summary>
+    // HACK: Fixes a bug that XMatrixTypes.Identity is not handled correctly in some cases.
+    // TODO: Eliminate this function.
+    void InitIdentity()
+    {
+      Debug.Assert(this.type == XMatrixTypes.Identity);
+      this.m11 = 1;
+      this.m22 = 1;
+      Debug.Assert(this.m12 == 0);
+      Debug.Assert(this.m21 == 0);
+      Debug.Assert(this.offsetX == 0);
+      Debug.Assert(this.offsetY == 0);
+    }
+
+    /// <summary>
     /// Gets a value indicating whether this matrix instance is the identity matrix.
     /// </summary>
     public bool IsIdentity
@@ -129,7 +143,7 @@ namespace PdfSharp.Drawing
     {
       if (this.type == XMatrixTypes.Identity)
         return new double[] { 1, 0, 0, 1, 0, 0 };
-      return new double[] { this.m11, this.m12, this.m21, this.m22, this.offsetX, this.OffsetY };
+      return new double[] { this.m11, this.m12, this.m21, this.m22, this.offsetX, this.offsetY };
     }
 
     /// <summary>
@@ -137,7 +151,7 @@ namespace PdfSharp.Drawing
     /// </summary>
     public static XMatrix operator *(XMatrix trans1, XMatrix trans2)
     {
-      MatrixUtil.MultiplyMatrix(ref trans1, ref trans2);
+      MatrixHelper.MultiplyMatrix(ref trans1, ref trans2);
       return trans1;
     }
 
@@ -146,7 +160,7 @@ namespace PdfSharp.Drawing
     /// </summary>
     public static XMatrix Multiply(XMatrix trans1, XMatrix trans2)
     {
-      MatrixUtil.MultiplyMatrix(ref trans1, ref trans2);
+      MatrixHelper.MultiplyMatrix(ref trans1, ref trans2);
       return trans1;
     }
 
@@ -189,6 +203,10 @@ namespace PdfSharp.Drawing
     /// </summary>
     public void Multiply(XMatrix matrix, XMatrixOrder order)
     {
+      // HACK in Multiply
+      if (this.type == XMatrixTypes.Identity)
+        InitIdentity();
+
       // Must use properties, the fields can be invalid if the matrix is identity matrix.
       double t11 = M11;
       double t12 = M12;
@@ -249,7 +267,7 @@ namespace PdfSharp.Drawing
     {
       if (this.type == XMatrixTypes.Identity)
       {
-        this.SetMatrix(1, 0, 0, 1, offsetX, offsetY, XMatrixTypes.Translation);
+        SetMatrix(1, 0, 0, 1, offsetX, offsetY, XMatrixTypes.Translation);
       }
       else if (this.type == XMatrixTypes.Unknown)
       {
@@ -277,6 +295,10 @@ namespace PdfSharp.Drawing
     /// </summary>
     public void Translate(double offsetX, double offsetY, XMatrixOrder order)
     {
+      // HACK in Translate
+      if (this.type == XMatrixTypes.Identity)
+        InitIdentity();
+
       if (order == XMatrixOrder.Append)
       {
         this.offsetX += offsetX;
@@ -321,6 +343,10 @@ namespace PdfSharp.Drawing
     /// </summary>
     public void Scale(double scaleX, double scaleY, XMatrixOrder order)
     {
+      // HACK in Scale
+      if (this.type == XMatrixTypes.Identity)
+        InitIdentity();
+
       if (order == XMatrixOrder.Append)
       {
         this.m11 *= scaleX;
@@ -374,6 +400,9 @@ namespace PdfSharp.Drawing
       Scale(scaleXY, scaleXY, order);
     }
 
+    /// <summary>
+    /// Function is obsolete.
+    /// </summary>
     [Obsolete("Use ScaleAtAppend or ScaleAtPrepend explicitly, because in GDI+ and WPF the defaults are contrary.", true)]
     public void ScaleAt(double scaleX, double scaleY, double centerX, double centerY)
     {
@@ -397,6 +426,9 @@ namespace PdfSharp.Drawing
       this = CreateScaling(scaleX, scaleY, centerX, centerY) * this;
     }
 
+    /// <summary>
+    /// Function is obsolete.
+    /// </summary>
     [Obsolete("Use RotateAppend or RotatePrepend explicitly, because in GDI+ and WPF the defaults are contrary.", true)]
     public void Rotate(double angle)
     {
@@ -428,6 +460,10 @@ namespace PdfSharp.Drawing
     /// </summary>
     public void Rotate(double angle, XMatrixOrder order)
     {
+      // HACK in Rotate
+      if (this.type == XMatrixTypes.Identity)
+        InitIdentity();
+
       angle = angle * Calc.Deg2Rad;
       double cos = Math.Cos(angle);
       double sin = Math.Sin(angle);
@@ -460,6 +496,9 @@ namespace PdfSharp.Drawing
       DeriveMatrixType();
     }
 
+    /// <summary>
+    /// Function is obsolete.
+    /// </summary>
     [Obsolete("Use RotateAtAppend or RotateAtPrepend explicitly, because in GDI+ and WPF the defaults are contrary.", true)]
     public void RotateAt(double angle, double centerX, double centerY)
     {
@@ -534,6 +573,9 @@ namespace PdfSharp.Drawing
       DeriveMatrixType();
     }
 
+    /// <summary>
+    /// Function is obsolete.
+    /// </summary>
     [Obsolete("Use ShearAppend or ShearPrepend explicitly, because in GDI+ and WPF the defaults are contrary.", true)]
     public void Shear(double shearX, double shearY)
     {
@@ -562,6 +604,10 @@ namespace PdfSharp.Drawing
     /// </summary>
     public void Shear(double shearX, double shearY, XMatrixOrder order)
     {
+      // HACK in Shear
+      if (this.type == XMatrixTypes.Identity)
+        InitIdentity();
+
       double t11 = this.m11;
       double t12 = this.m12;
       double t21 = this.m21;
@@ -587,6 +633,9 @@ namespace PdfSharp.Drawing
       DeriveMatrixType();
     }
 
+    /// <summary>
+    /// Function is obsolete.
+    /// </summary>
     [Obsolete("Use SkewAppend or SkewPrepend explicitly, because in GDI+ and WPF the defaults are contrary.", true)]
     public void Skew(double skewX, double skewY)
     {
@@ -622,7 +671,7 @@ namespace PdfSharp.Drawing
     public XPoint Transform(XPoint point)
     {
       XPoint point2 = point;
-      this.MultiplyPoint(ref point2.x, ref point2.y);
+      MultiplyPoint(ref point2.x, ref point2.y);
       return point2;
     }
 
@@ -635,7 +684,7 @@ namespace PdfSharp.Drawing
       {
         int count = points.Length;
         for (int idx = 0; idx < count; idx++)
-          this.MultiplyPoint(ref points[idx].x, ref points[idx].y);
+          MultiplyPoint(ref points[idx].x, ref points[idx].y);
       }
     }
 
@@ -647,6 +696,9 @@ namespace PdfSharp.Drawing
       if (points == null)
         throw new ArgumentNullException("points");
 
+      if (IsIdentity)
+        return;
+
       int count = points.Length;
       for (int idx = 0; idx < count; idx++)
       {
@@ -709,7 +761,7 @@ namespace PdfSharp.Drawing
     public XVector Transform(XVector vector)
     {
       XVector vector2 = vector;
-      this.MultiplyVector(ref vector2.x, ref vector2.y);
+      MultiplyVector(ref vector2.x, ref vector2.y);
       return vector2;
     }
 
@@ -722,7 +774,7 @@ namespace PdfSharp.Drawing
       {
         int count = vectors.Length;
         for (int idx = 0; idx < count; idx++)
-          this.MultiplyVector(ref vectors[idx].x, ref vectors[idx].y);
+          MultiplyVector(ref vectors[idx].x, ref vectors[idx].y);
       }
     }
 
@@ -736,6 +788,9 @@ namespace PdfSharp.Drawing
       if (points == null)
         throw new ArgumentNullException("points");
 
+      if (IsIdentity)
+        return;
+
       int count = points.Length;
       for (int idx = 0; idx < count; idx++)
       {
@@ -781,7 +836,7 @@ namespace PdfSharp.Drawing
     /// </summary>
     public void Invert()
     {
-      double determinant = this.Determinant;
+      double determinant = Determinant;
       if (DoubleUtil.IsZero(determinant))
         throw new InvalidOperationException("NotInvertible"); //SR.Get(SRID.Transform_NotInvertible, new object[0]));
 
@@ -810,7 +865,7 @@ namespace PdfSharp.Drawing
         default:
           {
             double detInvers = 1.0 / determinant;
-            this.SetMatrix(this.m22 * detInvers, -this.m12 * detInvers, -this.m21 * detInvers, this.m11 * detInvers, (this.m21 * this.offsetY - this.offsetX * this.m22) * detInvers, (this.offsetX * this.m12 - this.m11 * this.offsetY) * detInvers, XMatrixTypes.Unknown);
+            SetMatrix(this.m22 * detInvers, -this.m12 * detInvers, -this.m21 * detInvers, this.m11 * detInvers, (this.m21 * this.offsetY - this.offsetX * this.m22) * detInvers, (this.offsetX * this.m12 - this.m11 * this.offsetY) * detInvers, XMatrixTypes.Unknown);
             break;
           }
       }
@@ -970,6 +1025,9 @@ namespace PdfSharp.Drawing
         (float)this.offsetX, (float)this.offsetY);
     }
 
+    /// <summary>
+    /// Obsolete, will be deleted.
+    /// </summary>
     [Obsolete("Use ToGdiMatrix.")]
     public System.Drawing.Drawing2D.Matrix ToGdipMatrix()
     {
@@ -994,6 +1052,9 @@ namespace PdfSharp.Drawing
     /// </summary>
     public static explicit operator System.Drawing.Drawing2D.Matrix(XMatrix matrix)
     {
+      if (matrix.IsIdentity)
+        return new System.Drawing.Drawing2D.Matrix();
+
       return new System.Drawing.Drawing2D.Matrix(
         (float)matrix.m11, (float)matrix.m12,
         (float)matrix.m21, (float)matrix.m22,
@@ -1007,6 +1068,9 @@ namespace PdfSharp.Drawing
     /// </summary>
     public static explicit operator System.Windows.Media.Matrix(XMatrix matrix)
     {
+      if (matrix.IsIdentity)
+        return new System.Windows.Media.Matrix();
+
       return new System.Windows.Media.Matrix(
         matrix.m11, matrix.m12,
         matrix.m21, matrix.m22,
@@ -1092,9 +1156,9 @@ namespace PdfSharp.Drawing
     /// </summary>
     public override int GetHashCode()
     {
-      if (this.IsDistinguishedIdentity)
+      if (IsDistinguishedIdentity)
         return 0;
-      return this.M11.GetHashCode() ^ this.M12.GetHashCode() ^ this.M21.GetHashCode() ^ this.M22.GetHashCode() ^ this.OffsetX.GetHashCode() ^ this.OffsetY.GetHashCode();
+      return M11.GetHashCode() ^ M12.GetHashCode() ^ M21.GetHashCode() ^ M22.GetHashCode() ^ OffsetX.GetHashCode() ^ OffsetY.GetHashCode();
     }
 
     /// <summary>
@@ -1103,13 +1167,11 @@ namespace PdfSharp.Drawing
     public static XMatrix Parse(string source)
     {
       XMatrix identity;
-      IFormatProvider cultureInfo = CultureInfo.GetCultureInfo("en-us");
+      IFormatProvider cultureInfo = CultureInfo.InvariantCulture; //.GetCultureInfo("en-us");
       TokenizerHelper helper = new TokenizerHelper(source, cultureInfo);
       string str = helper.NextTokenRequired();
-      if (str == "Identity")
-        identity = Identity;
-      else
-        identity = new XMatrix(Convert.ToDouble(str, cultureInfo), Convert.ToDouble(helper.NextTokenRequired(), cultureInfo), Convert.ToDouble(helper.NextTokenRequired(), cultureInfo), Convert.ToDouble(helper.NextTokenRequired(), cultureInfo), Convert.ToDouble(helper.NextTokenRequired(), cultureInfo), Convert.ToDouble(helper.NextTokenRequired(), cultureInfo));
+      identity = str == "Identity" ? Identity : 
+        new XMatrix(Convert.ToDouble(str, cultureInfo), Convert.ToDouble(helper.NextTokenRequired(), cultureInfo), Convert.ToDouble(helper.NextTokenRequired(), cultureInfo), Convert.ToDouble(helper.NextTokenRequired(), cultureInfo), Convert.ToDouble(helper.NextTokenRequired(), cultureInfo), Convert.ToDouble(helper.NextTokenRequired(), cultureInfo));
       helper.LastTokenRequired();
       return identity;
     }
@@ -1119,7 +1181,7 @@ namespace PdfSharp.Drawing
     /// </summary>
     public override string ToString()
     {
-      return this.ConvertToString(null, null);
+      return ConvertToString(null, null);
     }
 
     /// <summary>
@@ -1127,7 +1189,7 @@ namespace PdfSharp.Drawing
     /// </summary>
     public string ToString(IFormatProvider provider)
     {
-      return this.ConvertToString(null, provider);
+      return ConvertToString(null, provider);
     }
 
     /// <summary>
@@ -1135,12 +1197,12 @@ namespace PdfSharp.Drawing
     /// </summary>
     string IFormattable.ToString(string format, IFormatProvider provider)
     {
-      return this.ConvertToString(format, provider);
+      return ConvertToString(format, provider);
     }
 
     internal string ConvertToString(string format, IFormatProvider provider)
     {
-      if (this.IsIdentity)
+      if (IsIdentity)
         return "Identity";
 
       char numericListSeparator = TokenizerHelper.GetNumericListSeparator(provider);
@@ -1252,7 +1314,12 @@ namespace PdfSharp.Drawing
       return matrix;
     }
 
+    /// <summary>
+    /// Sets the matrix.
+    /// </summary>
+    // ReSharper disable ParameterHidesMember
     void SetMatrix(double m11, double m12, double m21, double m22, double offsetX, double offsetY, XMatrixTypes type)
+    // ReSharper restore ParameterHidesMember
     {
       this.m11 = m11;
       this.m12 = m12;
@@ -1303,15 +1370,14 @@ namespace PdfSharp.Drawing
     double offsetY;
     XMatrixTypes type;
     int padding;
-    const int c_identityHashCode = 0;
-    static XMatrix s_identity;
+    static readonly XMatrix s_identity;
 
     /// <summary>
     /// Internal matrix helper.
     /// </summary>
-    internal static class MatrixUtil
+    internal static class MatrixHelper
     {
-      // Fast mutiplication taking matrx type into account. Reflected from WPF.
+      // Fast mutiplication taking matrix type into account. Reflectored from WPF.
       internal static void MultiplyMatrix(ref XMatrix matrix1, ref XMatrix matrix2)
       {
         XMatrixTypes type1 = matrix1.type;
@@ -1319,9 +1385,7 @@ namespace PdfSharp.Drawing
         if (type2 != XMatrixTypes.Identity)
         {
           if (type1 == XMatrixTypes.Identity)
-          {
             matrix1 = matrix2;
-          }
           else if (type2 == XMatrixTypes.Translation)
           {
             matrix1.offsetX += matrix2.offsetX;
@@ -1343,7 +1407,6 @@ namespace PdfSharp.Drawing
           }
           else
           {
-            //switch (((((int)types) << 4) | types2))
             switch ((((int)type1) << 4) | (int)type2)
             {
               case 0x22:
@@ -1452,891 +1515,4 @@ namespace PdfSharp.Drawing
       }
     }
   }
-
-#else
-  // Old code, delete end of 2008
-
-  /// <summary>
-  /// Represents a 3-by-3 matrix that represents an affine 2D transformation.
-  /// </summary>
-  [DebuggerDisplay("({M11}, {M12}, {M21}, {M22}, {OffsetX}, {OffsetY})")]
-  public struct XMatrix
-  {
-    // TODO: In Windows 6.0 the type System.Windows.Media.Matrix is a much more
-    // sophisticated implementation of a matrix -> enhance this implementation
-
-    // is struct now and must be initializes with Matrix.Identity
-    //    /// <summary>
-    //    /// Initializes a new instance of the Matrix class as the identity matrix.
-    //    /// </summary>
-    //    public XMatrix()
-    //    {
-    //      Reset();
-    //    }
-
-    static XMatrix()
-    {
-      XMatrix.identity = new XMatrix(1, 0, 0, 1, 0, 0);
-    }
-
-    ///// <summary>
-    ///// Initializes a new instance of the Matrix class with the specified matrix.
-    ///// </summary>
-    //public XMatrix(Matrix matrix)
-    //{
-    //  float[] elements = matrix.Elements;
-    //  this.m11 = elements[0];
-    //  this.m12 = elements[1];
-    //  this.m21 = elements[2];
-    //  this.m22 = elements[3];
-    //  this.mdx = elements[4];
-    //  this.mdy = elements[5];
-    //}
-
-#if GDI
-    /// <summary>
-    /// Initializes a new instance of the Matrix class to the transform defined by the specified rectangle and 
-    /// array of points.
-    /// </summary>
-    public XMatrix(Rectangle rect, System.Drawing.Point[] plgpts)
-      : this(new XRect(rect.X, rect.Y, rect.Width, rect.Height),
-      new XPoint[3] { new XPoint(plgpts[0]), new XPoint(plgpts[1]), new XPoint(plgpts[2]) })
-    { }
-#endif
-
-#if WPF
-    /// <summary>
-    /// Initializes a new instance of the Matrix class to the transform defined by the specified rectangle and 
-    /// array of points.
-    /// </summary>
-    public XMatrix(Rect rect, System.Windows.Point[] plgpts)
-      : this(new XRect(rect.X, rect.Y, rect.Width, rect.Height),
-      new XPoint[3] { new XPoint(plgpts[0]), new XPoint(plgpts[1]), new XPoint(plgpts[2]) })
-    { }
-#endif
-
-#if GDI
-    /// <summary>
-    /// Initializes a new instance of the Matrix class to the transform defined by the specified rectangle and 
-    /// array of points.
-    /// </summary>
-    public XMatrix(RectangleF rect, PointF[] plgpts)
-      : this(new XRect(rect.X, rect.Y, rect.Width, rect.Height),
-      new XPoint[3] { new XPoint(plgpts[0]), new XPoint(plgpts[1]), new XPoint(plgpts[2]) })
-    {
-    }
-#endif
-
-#if GDI
-    /// <summary>
-    /// Initializes a new instance of the <see cref="XMatrix"/> class.
-    /// </summary>
-    public XMatrix(XRect rect, XPoint[] plgpts)
-    {
-      // TODO
-#if true
-      // Lazy solution... left as an exercise :-)
-      System.Drawing.Drawing2D.Matrix matrix = new System.Drawing.Drawing2D.Matrix(
-        new RectangleF((float)rect.X, (float)rect.Y, (float)rect.Width, (float)rect.Height),
-        new PointF[3]{new PointF((float)plgpts[0].X, (float)plgpts[0].Y),
-                      new PointF((float)plgpts[1].X, (float)plgpts[1].Y), 
-                      new PointF((float)plgpts[2].X, (float)plgpts[2].Y)});
-      float[] elements = matrix.Elements;
-      this.m11 = elements[0];
-      this.m12 = elements[1];
-      this.m21 = elements[2];
-      this.m22 = elements[3];
-      this.mdx = elements[4];
-      this.mdy = elements[5];
-#else
-      // TODO work out the formulas for each value...
-      this.m11 = 0;
-      this.m12 = 0;
-      this.m21 = 0;
-      this.m22 = 0;
-      this.mdx = 0;
-      this.mdy = 0;
-      throw new NotImplementedException("TODO");
-#endif
-    }
-#endif
-
-    /// <summary>
-    /// Initializes a new instance of the Matrix class with the specified points.
-    /// </summary>
-    public XMatrix(double m11, double m12, double m21, double m22, double offsetX, double offsetY)
-    {
-      this.m11 = m11;
-      this.m12 = m12;
-      this.m21 = m21;
-      this.m22 = m22;
-      this.mdx = offsetX;
-      this.mdy = offsetY;
-    }
-
-    /// <summary>
-    /// Returns the hash code for this instance.
-    /// </summary>
-    public override int GetHashCode()
-    {
-      return base.GetHashCode();
-    }
-
-    /// <summary>
-    /// Indicates whether this instance and a specified object are equal.
-    /// </summary>
-    public override bool Equals(object obj)
-    {
-      if (obj is XMatrix)
-      {
-        XMatrix matrix = (XMatrix)obj;
-        return this.m11 == matrix.m11 && this.m12 == matrix.m12 && this.m21 == matrix.m21 &&
-          this.m22 == matrix.m22 && this.mdx == matrix.mdx && this.mdy == matrix.mdy;
-      }
-      return false;
-    }
-
-    /// <summary>
-    /// Inverts this XMatrix object. Throws an exception if the matrix is not invertible.
-    /// </summary>
-    public void Invert()
-    {
-      double det = this.m11 * this.m22 - this.m12 * this.m21;
-      if (det == 0.0)
-        throw new InvalidOperationException("Matrix is singular and cannot be inverted.");
-
-      double i11 = this.m22 / det;
-      double i12 = -this.m12 / det;
-      double i21 = -this.m21 / det;
-      double i22 = this.m11 / det;
-      double idx = (this.m21 * this.mdy - this.m22 * this.mdx) / det;
-      double idy = (this.m12 * this.mdx - this.m11 * this.mdy) / det;
-
-      this.m11 = i11;
-      this.m12 = i12;
-      this.m21 = i21;
-      this.m22 = i22;
-      this.mdx = idx;
-      this.mdy = idy;
-    }
-
-    /// <summary>
-    /// Multiplies this matrix with the specified matrix.
-    /// </summary>
-    [Obsolete("Use MultiplyAppend or MultiplyPrepend explicitly, because in GDI+ and WPF the defaults are contrary.", true)]
-    public void Multiply(XMatrix matrix)
-    {
-      throw new InvalidOperationException("Temporarily out of order.");
-    }
-
-    /// <summary>
-    /// Multiplies this matrix with the specified matrix.
-    /// </summary>
-    public void MultiplyAppend(XMatrix matrix)
-    {
-      Multiply(matrix, XMatrixOrder.Append);
-    }
-
-    /// <summary>
-    /// Multiplies this matrix with the specified matrix.
-    /// </summary>
-    public void MultiplyPrepend(XMatrix matrix)
-    {
-      Multiply(matrix, XMatrixOrder.Prepend);
-    }
-
-    /// <summary>
-    /// Multiplies this matrix with the specified matrix.
-    /// </summary>
-    public void Multiply(XMatrix matrix, XMatrixOrder order)
-    {
-      double t11 = this.m11;
-      double t12 = this.m12;
-      double t21 = this.m21;
-      double t22 = this.m22;
-      double tdx = this.mdx;
-      double tdy = this.mdy;
-
-      if (order == XMatrixOrder.Append)
-      {
-        this.m11 = t11 * matrix.m11 + t12 * matrix.m21;
-        this.m12 = t11 * matrix.m12 + t12 * matrix.m22;
-        this.m21 = t21 * matrix.m11 + t22 * matrix.m21;
-        this.m22 = t21 * matrix.m12 + t22 * matrix.m22;
-        this.mdx = tdx * matrix.m11 + tdy * matrix.m21 + matrix.mdx;
-        this.mdy = tdx * matrix.m12 + tdy * matrix.m22 + matrix.mdy;
-      }
-      else
-      {
-        this.m11 = t11 * matrix.m11 + t21 * matrix.m12;
-        this.m12 = t12 * matrix.m11 + t22 * matrix.m12;
-        this.m21 = t11 * matrix.m21 + t21 * matrix.m22;
-        this.m22 = t12 * matrix.m21 + t22 * matrix.m22;
-        this.mdx = t11 * matrix.mdx + t21 * matrix.mdy + tdx;
-        this.mdy = t12 * matrix.mdx + t22 * matrix.mdy + tdy;
-      }
-    }
-
-    /// <summary>
-    /// Translates the matrix with the specified offsets.
-    /// </summary>
-    [Obsolete("Use TranslateAppend or TranslatePrepend explicitly, because in GDI+ and WPF the defaults are contrary.", true)]
-    public void Translate(double offsetX, double offsetY)
-    {
-      throw new InvalidOperationException("Temporarily out of order.");
-    }
-
-    /// <summary>
-    /// Translates the matrix with the specified offsets.
-    /// </summary>
-    public void TranslateAppend(double offsetX, double offsetY)
-    {
-      Translate(offsetX, offsetY, XMatrixOrder.Append);
-    }
-
-    /// <summary>
-    /// Translates the matrix with the specified offsets.
-    /// </summary>
-    public void TranslatePrepend(double offsetX, double offsetY)
-    {
-      Translate(offsetX, offsetY, XMatrixOrder.Prepend);
-    }
-
-    /// <summary>
-    /// Translates the matrix with the specified offsets.
-    /// </summary>
-    public void Translate(double offsetX, double offsetY, XMatrixOrder order)
-    {
-      if (order == XMatrixOrder.Append)
-      {
-        this.mdx += offsetX;
-        this.mdy += offsetY;
-      }
-      else
-      {
-        this.mdx += offsetX * this.m11 + offsetY * this.m21;
-        this.mdy += offsetX * this.m12 + offsetY * this.m22;
-      }
-    }
-
-    /// <summary>
-    /// Scales the matrix with the specified scalars.
-    /// </summary>
-    [Obsolete("Use ScaleAppend or ScalePrepend explicitly, because in GDI+ and WPF the defaults are contrary.", true)]
-    public void Scale(double scaleX, double scaleY)
-    {
-      throw new InvalidOperationException("Temporarily out of order.");
-    }
-
-    /// <summary>
-    /// Scales the matrix with the specified scalars.
-    /// </summary>
-    public void ScaleAppend(double scaleX, double scaleY)
-    {
-      Scale(scaleX, scaleY, XMatrixOrder.Append);
-    }
-
-    /// <summary>
-    /// Scales the matrix with the specified scalars.
-    /// </summary>
-    public void ScalePrepend(double scaleX, double scaleY)
-    {
-      Scale(scaleX, scaleY, XMatrixOrder.Prepend);
-    }
-
-    /// <summary>
-    /// Scales the matrix with the specified scalars.
-    /// </summary>
-    public void Scale(double scaleX, double scaleY, XMatrixOrder order)
-    {
-      if (order == XMatrixOrder.Append)
-      {
-        this.m11 *= scaleX;
-        this.m12 *= scaleY;
-        this.m21 *= scaleX;
-        this.m22 *= scaleY;
-        this.mdx *= scaleX;
-        this.mdy *= scaleY;
-      }
-      else
-      {
-        this.m11 *= scaleX;
-        this.m12 *= scaleX;
-        this.m21 *= scaleY;
-        this.m22 *= scaleY;
-      }
-    }
-
-    /// <summary>
-    /// Scales the matrix with the specified scalar.
-    /// </summary>
-    [Obsolete("Use ScaleAppend or ScalePrepend explicitly, because in GDI+ and WPF the defaults are contrary.", true)]
-    public void Scale(double scaleXY)
-    {
-      throw new InvalidOperationException("Temporarily out of order.");
-    }
-
-    /// <summary>
-    /// Scales the matrix with the specified scalar.
-    /// </summary>
-    public void ScaleAppend(double scaleXY)
-    {
-      Scale(scaleXY, scaleXY, XMatrixOrder.Append);
-    }
-
-    /// <summary>
-    /// Scales the matrix with the specified scalar.
-    /// </summary>
-    public void ScalePrepend(double scaleXY)
-    {
-      Scale(scaleXY, scaleXY, XMatrixOrder.Prepend);
-    }
-
-    /// <summary>
-    /// Scales the matrix with the specified scalar.
-    /// </summary>
-    public void Scale(double scaleXY, XMatrixOrder order)
-    {
-      Scale(scaleXY, scaleXY, order);
-    }
-
-    /// <summary>
-    /// Rotates the matrix with the specified angle.
-    /// </summary>
-    [Obsolete("Use RotateAppend or RotatePrepend explicitly, because in GDI+ and WPF the defaults are contrary.", true)]
-    public void Rotate(double angle)
-    {
-      throw new InvalidOperationException("Temporarily out of order.");
-    }
-
-    /// <summary>
-    /// Rotates the matrix with the specified angle.
-    /// </summary>
-    public void RotateAppend(double angle)
-    {
-      Rotate(angle, XMatrixOrder.Append);
-    }
-
-    /// <summary>
-    /// Rotates the matrix with the specified angle.
-    /// </summary>
-    public void RotatePrepend(double angle)
-    {
-      Rotate(angle, XMatrixOrder.Prepend);
-    }
-
-    /// <summary>
-    /// Rotates the matrix with the specified angle.
-    /// </summary>
-    public void Rotate(double angle, XMatrixOrder order)
-    {
-      angle = angle * Calc.Deg2Rad;
-      double cos = Math.Cos(angle);
-      double sin = Math.Sin(angle);
-      if (order == XMatrixOrder.Append)
-      {
-        double t11 = this.m11;
-        double t12 = this.m12;
-        double t21 = this.m21;
-        double t22 = this.m22;
-        double tdx = this.mdx;
-        double tdy = this.mdy;
-        this.m11 = t11 * cos - t12 * sin;
-        this.m12 = t11 * sin + t12 * cos;
-        this.m21 = t21 * cos - t22 * sin;
-        this.m22 = t21 * sin + t22 * cos;
-        this.mdx = tdx * cos - tdy * sin;
-        this.mdy = tdx * sin + tdy * cos;
-      }
-      else
-      {
-        double t11 = this.m11;
-        double t12 = this.m12;
-        double t21 = this.m21;
-        double t22 = this.m22;
-        this.m11 = t11 * cos + t21 * sin;
-        this.m12 = t12 * cos + t22 * sin;
-        this.m21 = -t11 * sin + t21 * cos;
-        this.m22 = -t12 * sin + t22 * cos;
-      }
-    }
-
-    /// <summary>
-    /// Rotates the matrix with the specified angle at the specified point.
-    /// </summary>
-    [Obsolete("Use RotateAtAppend or RotateAtPrepend explicitly, because in GDI+ and WPF the defaults are contrary.", true)]
-    public void RotateAt(double angle, XPoint point)
-    {
-      throw new InvalidOperationException("Temporarily out of order.");
-    }
-
-    /// <summary>
-    /// Rotates the matrix with the specified angle at the specified point.
-    /// </summary>
-    public void RotateAtAppend(double angle, XPoint point)
-    {
-      RotateAt(angle, point, XMatrixOrder.Append);
-    }
-
-    /// <summary>
-    /// Rotates the matrix with the specified angle at the specified point.
-    /// </summary>
-    public void RotateAtPrepend(double angle, XPoint point)
-    {
-      RotateAt(angle, point, XMatrixOrder.Prepend);
-    }
-
-    /// <summary>
-    /// Rotates the matrix with the specified angle at the specified point.
-    /// </summary>
-    public void RotateAt(double angle, XPoint point, XMatrixOrder order)
-    {
-      // TODO: check code
-      if (order == XMatrixOrder.Prepend)
-      {
-        this.Translate(point.X, point.Y, order);
-        this.Rotate(angle, order);
-        this.Translate(-point.X, -point.Y, order);
-      }
-      else
-      {
-        throw new NotImplementedException("RotateAt with XMatrixOrder.Append");
-      }
-    }
-
-    /// <summary>
-    /// Shears the matrix with the specified scalars.
-    /// </summary>
-    [Obsolete("Use ShearAppend or ShearPrepend explicitly, because in GDI+ and WPF the defaults are contrary.", true)]
-    public void Shear(double shearX, double shearY)
-    {
-      throw new InvalidOperationException("Temporarily out of order.");
-    }
-
-    /// <summary>
-    /// Shears the matrix with the specified scalars.
-    /// </summary>
-    public void ShearAppend(double shearX, double shearY)
-    {
-      Shear(shearX, shearY, XMatrixOrder.Append);
-    }
-
-    /// <summary>
-    /// Shears the matrix with the specified scalars.
-    /// </summary>
-    public void ShearPrepend(double shearX, double shearY)
-    {
-      Shear(shearX, shearY, XMatrixOrder.Prepend);
-    }
-
-    /// <summary>
-    /// Shears the matrix with the specified scalars.
-    /// </summary>
-    public void Shear(double shearX, double shearY, XMatrixOrder order)
-    {
-      double t11 = this.m11;
-      double t12 = this.m12;
-      double t21 = this.m21;
-      double t22 = this.m22;
-      double tdx = this.mdx;
-      double tdy = this.mdy;
-      if (order == XMatrixOrder.Append)
-      {
-        this.m11 += shearX * t12;
-        this.m12 += shearY * t11;
-        this.m21 += shearX * t22;
-        this.m22 += shearY * t21;
-        this.mdx += shearX * tdy;
-        this.mdy += shearY * tdx;
-      }
-      else
-      {
-        this.m11 += shearY * t21;
-        this.m12 += shearY * t22;
-        this.m21 += shearX * t11;
-        this.m22 += shearX * t12;
-      }
-    }
-
-#if GDI
-    /// <summary>
-    /// Multiplies all points of the specified array with the this matrix.
-    /// </summary>
-    public void TransformPoints(System.Drawing.Point[] points)
-    {
-      if (points == null)
-        throw new ArgumentNullException("points");
-
-      if (IsIdentity)
-        return;
-
-      int count = points.Length;
-      for (int idx = 0; idx < count; idx++)
-      {
-        double x = points[idx].X;
-        double y = points[idx].Y;
-        points[idx].X = (int)(x * this.m11 + y * this.m21 + this.mdx);
-        points[idx].Y = (int)(x * this.m12 + y * this.m22 + this.mdy);
-      }
-    }
-#endif
-
-#if WPF
-    /// <summary>
-    /// Multiplies all points of the specified array with the this matrix.
-    /// </summary>
-    public void TransformPoints(System.Windows.Point[] points)
-    {
-      if (points == null)
-        throw new ArgumentNullException("points");
-
-      if (IsIdentity)
-        return;
-
-      int count = points.Length;
-      for (int idx = 0; idx < count; idx++)
-      {
-        double x = points[idx].X;
-        double y = points[idx].Y;
-        points[idx].X = (int)(x * this.m11 + y * this.m21 + this.mdx);
-        points[idx].Y = (int)(x * this.m12 + y * this.m22 + this.mdy);
-      }
-    }
-#endif
-
-    /// <summary>
-    /// Multiplies all points of the specified array with the this matrix.
-    /// </summary>
-    public void TransformPoints(XPoint[] points)
-    {
-      if (points == null)
-        throw new ArgumentNullException("points");
-
-      int count = points.Length;
-      for (int idx = 0; idx < count; idx++)
-      {
-        double x = points[idx].X;
-        double y = points[idx].Y;
-        points[idx].X = x * this.m11 + y * this.m21 + this.mdx;
-        points[idx].Y = x * this.m12 + y * this.m22 + this.mdy;
-      }
-    }
-
-    /// <summary>
-    /// Multiplies all vectors of the specified array with the this matrix. The translation elements 
-    /// of this matrix (third row) are ignored.
-    /// </summary>
-    public void TransformVectors(XPoint[] points)
-    {
-      if (points == null)
-        throw new ArgumentNullException("points");
-
-      int count = points.Length;
-      for (int idx = 0; idx < count; idx++)
-      {
-        double x = points[idx].X;
-        double y = points[idx].Y;
-        points[idx].X = x * this.m11 + y * this.m21;
-        points[idx].Y = x * this.m12 + y * this.m22;
-      }
-    }
-
-    public XVector Transform(XVector vector)
-    {
-      return new XVector();
-    }
-
-#if GDI
-    /// <summary>
-    /// Multiplies all vectors of the specified array with the this matrix. The translation elements 
-    /// of this matrix (third row) are ignored.
-    /// </summary>
-    public void TransformVectors(PointF[] points)
-    {
-      if (points == null)
-        throw new ArgumentNullException("points");
-
-      int count = points.Length;
-      for (int idx = 0; idx < count; idx++)
-      {
-        double x = points[idx].X;
-        double y = points[idx].Y;
-        points[idx].X = (float)(x * this.m11 + y * this.m21 + this.mdx);
-        points[idx].Y = (float)(x * this.m12 + y * this.m22 + this.mdy);
-      }
-    }
-#endif
-
-    /// <summary>
-    /// Gets an array of double values that represents the elements of this matrix.
-    /// </summary>
-    public double[] Elements
-    {
-      get
-      {
-        double[] elements = new double[6];
-        elements[0] = this.m11;
-        elements[1] = this.m12;
-        elements[2] = this.m21;
-        elements[3] = this.m22;
-        elements[4] = this.mdx;
-        elements[5] = this.mdy;
-        return elements;
-      }
-    }
-
-    /// <summary>
-    /// Gets a value from the matrix.
-    /// </summary>
-    public double M11
-    {
-      get { return this.m11; }
-      set { this.m11 = value; }
-    }
-
-    /// <summary>
-    /// Gets a value from the matrix.
-    /// </summary>
-    public double M12
-    {
-      get { return this.m12; }
-      set { this.m12 = value; }
-    }
-
-    /// <summary>
-    /// Gets a value from the matrix.
-    /// </summary>
-    public double M21
-    {
-      get { return this.m21; }
-      set { this.m21 = value; }
-    }
-
-    /// <summary>
-    /// Gets a value from the matrix.
-    /// </summary>
-    public double M22
-    {
-      get { return this.m22; }
-      set { this.m22 = value; }
-    }
-
-    /// <summary>
-    /// Gets the x translation value.
-    /// </summary>
-    public double OffsetX
-    {
-      get { return this.mdx; }
-      set { this.mdx = value; }
-    }
-
-    /// <summary>
-    /// Gets the y translation value.
-    /// </summary>
-    public double OffsetY
-    {
-      get { return this.mdy; }
-      set { this.mdy = value; }
-    }
-
-#if GDI
-    /// <summary>
-    /// Converts this matrix to a System.Drawing.Drawing2D.Matrix object.
-    /// </summary>
-    public System.Drawing.Drawing2D.Matrix ToGdiMatrix()
-    {
-      return new System.Drawing.Drawing2D.Matrix((float)this.m11, (float)this.m12, (float)this.m21, (float)this.m22,
-        (float)this.mdx, (float)this.mdy);
-    }
-#endif
-
-#if WPF
-    /// <summary>
-    /// Converts this matrix to a System.Drawing.Drawing2D.Matrix object.
-    /// </summary>
-    public System.Windows.Media.Matrix ToWpfMatrix()
-    {
-      return new System.Windows.Media.Matrix(this.m11, this.m12, this.m21, this.m22, this.mdx, this.mdy);
-    }
-#endif
-
-    /// <summary>
-    /// Indicates whether this matrix is the identity matrix.
-    /// </summary>
-    public bool IsIdentity
-    {
-      get { return this.m11 == 1 && this.m12 == 0 && this.m21 == 0 && this.m22 == 1 && this.mdx == 0 && this.mdy == 0; }
-    }
-
-    /// <summary>
-    /// Indicates whether this matrix is invertible, i. e. its determinant is not zero.
-    /// </summary>
-    public bool IsInvertible
-    {
-      get { return this.m11 * this.m22 - this.m12 * this.m21 != 0; }
-    }
-
-#if GDI
-    /// <summary>
-    /// Explicitly converts a XMatrix to a Matrix.
-    /// </summary>
-    public static explicit operator System.Drawing.Drawing2D.Matrix(XMatrix matrix)
-    {
-      return new System.Drawing.Drawing2D.Matrix(
-        (float)matrix.m11, (float)matrix.m12,
-        (float)matrix.m21, (float)matrix.m22,
-        (float)matrix.mdx, (float)matrix.mdy);
-    }
-#endif
-
-#if WPF
-    /// <summary>
-    /// Explicitly converts a XMatrix to a Matrix.
-    /// </summary>
-    public static explicit operator System.Windows.Media.Matrix(XMatrix matrix)
-    {
-      return new System.Windows.Media.Matrix(
-        matrix.m11, matrix.m12,
-        matrix.m21, matrix.m22,
-        matrix.mdx, matrix.mdy);
-    }
-#endif
-
-#if GDI
-    /// <summary>
-    /// Implicitly converts a Matrix to an XMatrix.
-    /// </summary>
-    public static implicit operator XMatrix(System.Drawing.Drawing2D.Matrix matrix)
-    {
-      float[] elements = matrix.Elements;
-      return new XMatrix(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5]);
-    }
-#endif
-
-#if WPF
-    /// <summary>
-    /// Implicitly converts a Matrix to an XMatrix.
-    /// </summary>
-    public static implicit operator XMatrix(System.Windows.Media.Matrix matrix)
-    {
-      return new XMatrix(matrix.M11, matrix.M12, matrix.M21, matrix.M22, matrix.OffsetX, matrix.OffsetY);
-    }
-#endif
-
-    /// <summary>
-    /// Gets an identity matrix.
-    /// </summary>
-    public static XMatrix Identity
-    {
-      get { return XMatrix.identity; }
-    }
-
-    /// <summary>
-    /// Determines whether to matrices are equal.
-    /// </summary>
-    public static bool operator ==(XMatrix matrix1, XMatrix matrix2)
-    {
-      return
-        matrix1.m11 == matrix2.m11 &&
-        matrix1.m12 == matrix2.m12 &&
-        matrix1.m21 == matrix2.m21 &&
-        matrix1.m22 == matrix2.m22 &&
-        matrix1.mdx == matrix2.mdx &&
-        matrix1.mdy == matrix2.mdy;
-    }
-
-    /// <summary>
-    /// Determines whether to matrices are not equal.
-    /// </summary>
-    public static bool operator !=(XMatrix matrix1, XMatrix matrix2)
-    {
-      return !(matrix1 == matrix2);
-    }
-
-    //private static Matrix CreateIdentity()
-    //{
-    //  Matrix matrix = new Matrix();
-    //  matrix.SetMatrix(1.0, 0.0, 0.0, 1.0, 0.0, 0.0, MatrixTypes.TRANSFORM_IS_IDENTITY);
-    //  return matrix;
-    //}
-
-
-    double m11, m12, m21, m22, mdx, mdy;
-
-    private static XMatrix identity;
-
-#if DEBUG_
-    /// <summary>
-    /// Some test code to check that there are no typing errors in the formulars.
-    /// </summary>
-    public static void Test()
-    {
-      XMatrix xm1 = new XMatrix(23, -35, 837, 332, -3, 12);
-      Matrix  m1 = new Matrix(23, -35, 837, 332, -3, 12);
-      DumpMatrix(xm1, m1);
-      XMatrix xm2 = new XMatrix(12, 235, 245, 42, 33, -56);
-      Matrix  m2 = xm2.ToMatrix();
-      DumpMatrix(xm2, m2);
-
-//      xm1.Multiply(xm2, XMatrixOrder.Prepend);
-//      m1.Multiply(m2, MatrixOrder.Append);
-      xm1.Multiply(xm2, XMatrixOrder.Append);
-      m1.Multiply(m2, MatrixOrder.Append);
-      DumpMatrix(xm1, m1);
-
-      xm1.Translate(-243, 342, XMatrixOrder.Append);
-      m1.Translate(-243, 342, MatrixOrder.Append);
-      DumpMatrix(xm1, m1);
-
-      xm1.Scale(-5.66, 7.87);
-      m1.Scale(-5.66f, 7.87f);
-//      xm1.Scale(-5.66, 7.87, XMatrixOrder.Prepend);
-//      m1.Scale(-5.66f, 7.87f, MatrixOrder.Prepend);
-      DumpMatrix(xm1, m1);
-
-
-      xm1.Rotate(135, XMatrixOrder.Append);
-      m1.Rotate(135, MatrixOrder.Append);
-      //      xm1.Scale(-5.66, 7.87, XMatrixOrder.Prepend);
-      //      m1.Scale(-5.66f, 7.87f, MatrixOrder.Prepend);
-      DumpMatrix(xm1, m1);
-
-      xm1.RotateAt(177, new XPoint(-3456, 654), XMatrixOrder.Append);
-      m1.RotateAt(177, new PointF(-3456, 654), MatrixOrder.Append);
-      DumpMatrix(xm1, m1);
-
-      xm1.Shear(0.76, -0.87, XMatrixOrder.Prepend);
-      m1.Shear(0.76f, -0.87f, MatrixOrder.Prepend);
-      DumpMatrix(xm1, m1);
-
-      xm1 = new XMatrix(23, -35, 837, 332, -3, 12);
-      m1 = new Matrix(23, -35, 837, 332, -3, 12);
-
-      XPoint[] xpoints = new XPoint[3]{new XPoint(23, 10), new XPoint(-27, 120), new XPoint(-87, -55)};
-      PointF[] points = new PointF[3]{new PointF(23, 10), new PointF(-27, 120), new PointF(-87, -55)};
-
-      xm1.TransformPoints(xpoints);
-      m1.TransformPoints(points);
-
-      xm1.Invert();
-      m1.Invert();
-      DumpMatrix(xm1, m1);
-
-    }
-
-    static void DumpMatrix(XMatrix xm, Matrix m)
-    {
-      double[] xmv = xm.Elements;
-      float[] mv = m.Elements;
-      string message = String.Format("{0:0.###} {1:0.###} {2:0.###} {3:0.###} {4:0.###} {5:0.###}",
-        xmv[0], xmv[1], xmv[2], xmv[3], xmv[4], xmv[5]);
-      Console.WriteLine(message);
-      message = String.Format("{0:0.###} {1:0.###} {2:0.###} {3:0.###} {4:0.###} {5:0.###}",
-        mv[0], mv[1], mv[2], mv[3], mv[4], mv[5]);
-      Console.WriteLine(message);
-      Console.WriteLine();
-    }
-#endif
-  }
-#endif
-}
\ No newline at end of file
+}
diff --git a/lib/PdfSharp/PdfSharp.Drawing/XPdfForm.cs b/lib/PdfSharp/PdfSharp.Drawing/XPdfForm.cs
index 5a47b03..2dad15c 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/XPdfForm.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/XPdfForm.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -42,7 +42,7 @@ using System.Windows.Media;
 #endif
 using PdfSharp.Internal;
 using PdfSharp.Drawing.Pdf;
-using PdfSharp.Fonts.TrueType;
+using PdfSharp.Fonts.OpenType;
 using PdfSharp.Pdf;
 using PdfSharp.Pdf.IO;
 using PdfSharp.Pdf.Advanced;
@@ -62,7 +62,7 @@ namespace PdfSharp.Drawing
   {
     /// <summary>
     /// Initializes a new instance of the XPdfForm class from the specified path to an external PDF document.
-    /// Although PDFsharp internally caches XPdfForm objects it is recommended to reuse PdfXFrom objects
+    /// Although PDFsharp internally caches XPdfForm objects it is recommended to reuse XPdfForm objects
     /// in your code and change the PageNumber property if more than one page is needed form the external
     /// document. Furthermore, because XPdfForm can occupy very much memory, it is recommended to
     /// dispose XPdfForm objects if not needed anymore.
@@ -74,7 +74,7 @@ namespace PdfSharp.Drawing
 
       path = Path.GetFullPath(path);
       if (!File.Exists(path))
-        throw new FileNotFoundException(PSSR.FileNotFound(path), path);
+        throw new FileNotFoundException(PSSR.FileNotFound(path));
 
       if (PdfReader.TestPdfFile(path) == 0)
         throw new ArgumentException("The specified file has no valid PDF file header.", "path");
@@ -116,10 +116,12 @@ namespace PdfSharp.Drawing
       return new XPdfForm(stream);
     }
 
+/*
     void Initialize()
     {
       // ImageFormat has no overridden Equals...
     }
+*/
 
     /// <summary>
     /// Sets the form in the state FormState.Finished.
@@ -154,11 +156,11 @@ namespace PdfSharp.Drawing
     }
 
     /// <summary>
-    /// TODO:
     /// Frees the memory occupied by the underlying imported PDF document, even if other XPdfForm objects
-    /// refer to this document. A reuse of this object doesnt fail, because the underlying PDF document
-    /// is re-imported if neccessary. NYI
+    /// refer to this document. A reuse of this object doesn't fail, because the underlying PDF document
+    /// is re-imported if necessary.
     /// </summary>
+    // TODO: NYI: Dispose
     protected override void Dispose(bool disposing)
     {
       if (!this.disposed)
@@ -352,6 +354,16 @@ namespace PdfSharp.Drawing
     int pageNumber = 1;
 
     /// <summary>
+    /// Gets or sets the page index in the external PDF document this object refers to. The page index
+    /// is zero-based, i.e. it is in the range from 0 to PageCount - 1. The default value is 0.
+    /// </summary>
+    public int PageIndex
+    {
+      get { return PageNumber - 1; }
+      set { PageNumber = value + 1; }
+    }
+
+    /// <summary>
     /// Gets the underlying document from which pages are imported.
     /// </summary>
     internal PdfDocument ExternalDocument
diff --git a/lib/PdfSharp/PdfSharp.Drawing/XPen.cs b/lib/PdfSharp/PdfSharp.Drawing/XPen.cs
index 9be4d98..1f81836 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/XPen.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/XPen.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -244,7 +244,7 @@ namespace PdfSharp.Drawing
 #if GDI
 #if UseGdiObjects
     /// <summary>
-    /// Implicit convertion from Pen to XPen
+    /// Implicit conversion from Pen to XPen
     /// </summary>
     public static implicit operator XPen(Pen pen)
     {
@@ -309,7 +309,8 @@ namespace PdfSharp.Drawing
 #if WPF
     internal System.Windows.Media.Pen RealizeWpfPen()
     {
-      if (this.dirty || !this.dirty) // TODOWPF
+#if !SILVERLIGHT
+      if (this.dirty || !this.dirty) // TODOWPF: XPen is frozen by design, WPF Pen can change
       {
         //if (this.wpfPen == null)
         this.wpfPen = new System.Windows.Media.Pen(new SolidColorBrush(this.color.ToWpfColor()), this.width);
@@ -324,7 +325,7 @@ namespace PdfSharp.Drawing
         this.wpfPen.LineJoin = XConvert.ToPenLineJoin(this.lineJoin);
         if (this.dashStyle == XDashStyle.Custom)
         {
-          // TODOWPF
+          // TODOWPF: does not work in all cases
           this.wpfPen.DashStyle = new System.Windows.Media.DashStyle(this.dashPattern, this.dashOffset);
         }
         else
@@ -357,6 +358,9 @@ namespace PdfSharp.Drawing
           }
         }
       }
+#else
+      this.wpfPen = new System.Windows.Media.Pen(new SolidColorBrush(this.color.ToWpfColor()), this.width);
+#endif
       return this.wpfPen;
     }
 #endif
@@ -366,7 +370,7 @@ namespace PdfSharp.Drawing
 #if GDI
     System.Drawing.Pen gdiPen;
 #endif
-#if WPF
+#if WPF //&& !SILVERLIGHT
     System.Windows.Media.Pen wpfPen;
 #endif
   }
diff --git a/lib/PdfSharp/PdfSharp.Drawing/XPens.cs b/lib/PdfSharp/PdfSharp.Drawing/XPens.cs
index aea2d6e..68fcc3e 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/XPens.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/XPens.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -34,10 +34,8 @@ namespace PdfSharp.Drawing
   /// <summary>
   /// Pens for all the pre-defined colors.
   /// </summary>
-  public sealed class XPens
+  public static class XPens
   {
-    XPens() { }
-
     /// <summary>Gets a pre-defined XPen object.</summary>
     public static XPen AliceBlue
     {
diff --git a/lib/PdfSharp/PdfSharp.Drawing/XPoint.cs b/lib/PdfSharp/PdfSharp.Drawing/XPoint.cs
index ca44dc7..ae59db9 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/XPoint.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/XPoint.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -42,7 +42,6 @@ using PdfSharp.Internal;
 
 namespace PdfSharp.Drawing
 {
-#if true
   /// <summary>
   /// Represents a pair of floating point x- and y-coordinates that defines a point
   /// in a two-dimensional plane.
@@ -142,7 +141,7 @@ namespace PdfSharp.Drawing
     /// </summary>
     public override int GetHashCode()
     {
-      return this.X.GetHashCode() ^ this.Y.GetHashCode();
+      return X.GetHashCode() ^ Y.GetHashCode();
     }
 
     /// <summary>
@@ -260,7 +259,7 @@ namespace PdfSharp.Drawing
     /// </summary>
     [Browsable(false)]
     [Obsolete("Use '== new XPoint()'")]
-    public bool IsEmpty // DELETE: 08-12-31
+    public bool IsEmpty // DELETE: 09-12-31
     {
       get { return this.x == 0 && this.y == 0; }
     }
@@ -366,7 +365,7 @@ namespace PdfSharp.Drawing
     /// Divides a point by a scalar value.
     /// </summary>
     [Obsolete("Avoid using this operator.")]
-    public static XPoint operator /(XPoint point, double value)  // DELETE: 08-12-31
+    public static XPoint operator /(XPoint point, double value)  // DELETE: 09-12-31
     {
       if (value == 0)
         throw new DivideByZeroException("Divisor is zero.");
@@ -412,248 +411,9 @@ namespace PdfSharp.Drawing
     /// For convergence with WPF use new XPoint(), not XPoint.Empty
     /// </summary>
     [Obsolete("For convergence with WPF use new XPoint(), not XPoint.Empty")]
-    public static readonly XPoint Empty = new XPoint();  // DELETE: 08-12-31
+    public static readonly XPoint Empty = new XPoint();  // DELETE: 09-12-31
 
     internal double x;
     internal double y;
   }
-
-#else
-  // Old code, delete end of 2008
-
-  /// <summary>
-  /// Represents a pair of floating point x- and y-coordinates that defines a point
-  /// in a two-dimensional plane.
-  /// </summary>
-  [DebuggerDisplay("X={X.ToString(\"0.####\",System.Globalization.CultureInfo.InvariantCulture)}, Y={Y.ToString(\"0.####\",System.Globalization.CultureInfo.InvariantCulture)}")]
-  public struct XPoint
-  {
-    /// <summary>
-    /// Initializes a new instance of the XPoint class with the specified coordinates.
-    /// </summary>
-    public XPoint(double x, double y)
-    {
-      this.x = x;
-      this.y = y;
-    }
-
-#if GDI
-    /// <summary>
-    /// Initializes a new instance of the XPoint class with the specified point.
-    /// </summary>
-    public XPoint(System.Drawing.Point point)
-    {
-      this.x = point.X;
-      this.y = point.Y;
-    }
-#endif
-
-#if WPF
-    /// <summary>
-    /// Initializes a new instance of the XPoint class with the specified point.
-    /// </summary>
-    public XPoint(System.Windows.Point point)
-    {
-      this.x = point.X;
-      this.y = point.Y;
-    }
-#endif
-
-#if GDI
-    /// <summary>
-    /// Initializes a new instance of the XPoint class with the specified point.
-    /// </summary>
-    public XPoint(PointF point)
-    {
-      this.x = point.X;
-      this.y = point.Y;
-    }
-#endif
-
-    /// <summary>
-    /// Indicates whether this instance and a specified object are equal.
-    /// </summary>
-    public override bool Equals(object obj)
-    {
-      XPoint point = (XPoint)obj;
-      if (obj != null)
-        return point.x == this.x && point.y == this.y;
-      return false;
-    }
-
-    /// <summary>
-    /// Returns the hash code for this instance.
-    /// </summary>
-    public override int GetHashCode()
-    {
-      return this.x.GetHashCode() ^ this.y.GetHashCode();
-    }
-
-    /// <summary>
-    /// Converts this XPoint to a human readable string.
-    /// </summary>
-    public override string ToString()
-    {
-      return String.Format("{{X={0}, Y={1}}}", this.x, this.y);
-    }
-
-#if GDI
-    /// <summary>
-    /// Converts this XPoint to a System.Drawing.Point.
-    /// </summary>
-    public PointF ToPointF()
-    {
-      return new PointF((float)this.x, (float)this.y);
-    }
-#endif
-
-#if WPF
-    /// <summary>
-    /// Converts this XPoint to a System.Windows.Point.
-    /// </summary>
-    public System.Windows. Point ToPoint()
-    {
-      return new System.Windows.Point(this.x, this.y);
-    }
-#endif
-
-    /// <summary>
-    /// Gets the x-coordinate of this XPoint.
-    /// </summary>
-    public double X
-    {
-      get { return this.x; }
-      set { this.x = value; }
-    }
-
-    /// <summary>
-    /// Gets the y-coordinate of this XPoint.
-    /// </summary>
-    public double Y
-    {
-      get { return this.y; }
-      set { this.y = value; }
-    }
-
-    /// <summary>
-    /// Indicates whether this XPoint is empty.
-    /// </summary>
-    [Browsable(false)]
-    public bool IsEmpty
-    {
-      get { return this.x == 0 && this.y == 0; }
-    }
-
-    /// <summary>
-    /// Add a point and a size.
-    /// </summary>
-    public static XPoint operator +(XPoint point, XSize sz)
-    {
-      return new XPoint(point.x + sz.width, point.y + sz.height);
-    }
-
-    /// <summary>
-    /// Add a size from a point.
-    /// </summary>
-    public static XPoint operator -(XPoint point, XSize sz)
-    {
-      return new XPoint(point.x - sz.width, point.y - sz.height);
-    }
-
-    /// <summary>
-    /// Multiplies a point with a scalar value.
-    /// </summary>
-    public static XPoint operator *(XPoint point, double f)
-    {
-      return new XPoint(point.x * f, point.y * f);
-    }
-
-    /// <summary>
-    /// Multiplies a point with a scalar value.
-    /// </summary>
-    public static XPoint operator *(double f, XPoint point)
-    {
-      return new XPoint(f * point.x, f * point.y);
-    }
-
-    /// <summary>
-    /// Divides a point by a scalar value.
-    /// </summary>
-    public static XPoint operator /(XPoint point, double f)
-    {
-      if (f == 0)
-        throw new DivideByZeroException("Divisor is zero.");
-
-      return new XPoint(point.x / f, point.y / f);
-    }
-
-    /// <summary>
-    /// Determines whether two points are equal.
-    /// </summary>
-    public static bool operator ==(XPoint left, XPoint right)
-    {
-      return left.x == right.x && left.y == right.y;
-    }
-
-    /// <summary>
-    /// Determines whether two points are not equal.
-    /// </summary>
-    public static bool operator !=(XPoint left, XPoint right)
-    {
-      return !(left == right);
-    }
-
-    /// <summary>
-    /// Offsets the x and y value of this point.
-    /// </summary>
-    internal void Offset(double dx, double dy)
-    {
-      this.X += dx;
-      this.Y += dy;
-    }
-
-    internal double x;
-    internal double y;
-
-    /// <summary>
-    /// Parses the point from a string.
-    /// </summary>
-    public static XPoint ParsePoint(string value)
-    {
-      if (value == null)
-        throw new ArgumentNullException("value");
-
-      // TODO: Reflect reliabel implementation from Avalon
-      int ich = value.IndexOf(',');
-      if (ich == -1)
-        throw new ArgumentException("Invalid value.", "value");
-
-      double x = double.Parse(value.Substring(0, ich), CultureInfo.InvariantCulture);
-      double y = double.Parse(value.Substring(ich + 1), CultureInfo.InvariantCulture);
-      return new XPoint(x, y);
-    }
-
-    /// <summary>
-    /// Parses an array of points from a string.
-    /// </summary>
-    public static XPoint[] ParsePoints(string value)
-    {
-      if (value == null)
-        throw new ArgumentNullException("value");
-
-      // TODO: Reflect reliabel implementation from Avalon
-      string[] values = value.Split(' ');
-      int count = values.Length;
-      XPoint[] points = new XPoint[count];
-      for (int idx = 0; idx < count; idx++)
-        points[idx] = ParsePoint(values[idx]);
-      return points;
-    }
-
-    /// <summary>
-    /// Represents a new instance of the XPoint class with member data left uninitialized.
-    /// </summary>
-    public static readonly XPoint Empty = new XPoint();
-  }
-#endif
 }
diff --git a/lib/PdfSharp/PdfSharp.Drawing/XPrivateFontCollection.cs b/lib/PdfSharp/PdfSharp.Drawing/XPrivateFontCollection.cs
index 1f9b0f1..f77a090 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/XPrivateFontCollection.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/XPrivateFontCollection.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -29,95 +29,295 @@
 
 using System;
 using System.Diagnostics;
+using System.Collections.Generic;
 using System.Globalization;
 using System.ComponentModel;
+using System.IO;
+using System.Runtime.InteropServices;
 #if GDI
-using System.Collections.Generic;
 using System.Drawing;
 using System.Drawing.Text;
-using System.Runtime.InteropServices;
 #endif
 #if WPF
 using System.Windows.Media;
 #endif
 using PdfSharp.Internal;
-
-#pragma warning disable 1591
+using PdfSharp.Fonts.OpenType;
 
 namespace PdfSharp.Drawing
 {
-#if GDI
   ///<summary>
-  /// Represents a PrivateFontCollection.
+  /// Makes fonts that are not installed on the system available within the current application domain.
   /// </summary>
-  public class XPrivateFontCollection
+  public sealed class XPrivateFontCollection : IDisposable
   {
+    /// <summary>
+    /// Initializes a new instance of the <see cref="XPrivateFontCollection"/> class.
+    /// </summary>
     public XPrivateFontCollection()
     {
-      privateFontCollection = null;
-      privateFonts = null;
+      //// HACK: Use one global PrivateFontCollection in GDI+
+      //// TODO: Make a list of it
+      //if (s_global != null)
+      //  throw new InvalidOperationException("Because of limitations in GDI+ you can only have one instance of XPrivateFontCollection in your application.");
     }
+    internal static XPrivateFontCollection s_global = new XPrivateFontCollection();
+
+    //static XPrivateFontCollection()
+    //{
+    //  // HACK: Use one global PrivateFontCollection in GDI+
+    //  // TODO: Make a list of it
+    //  if (global != null)
+    //    throw new InvalidOperationException("Because of limitations in GDI+ you can only have one instance of XPrivateFontCollection in your application.");
+    //  global = this;
+    //}
+    //internal static XPrivateFontCollection global;
 
-    public PrivateFontCollection PrivateFontCollection
+    /// <summary>
+    /// Disposes all fonts from the collection.
+    /// </summary>
+    public void Dispose()
     {
-      get { return privateFontCollection; }
-      set { privateFontCollection = value; }
+#if GDI
+      //privateFonts.Clear();
+      this.privateFontCollection.Dispose();
+      this.privateFontCollection = new PrivateFontCollection();
+#endif
+      s_global = null;
+      //GC.SuppressFinalize(this);
     }
-    PrivateFontCollection privateFontCollection;
-    List<XPrivateFont> privateFonts;
 
-    void Initialize()
+#if GDI
+    internal static PrivateFontCollection GlobalPrivateFontCollection
     {
-      if (privateFontCollection == null)
-        privateFontCollection = new PrivateFontCollection();
-      if (privateFonts == null)
-        privateFonts = new List<XPrivateFont>();
+      get { return s_global != null ? s_global.privateFontCollection : null; }
     }
+#endif
+
 
-    /*public void AddMemoryFont(IntPtr memory, int length,
-      string fontName, bool bold, bool italic)
+#if GDI
+    //internal PrivateFontCollection PrivateFontCollection
+    //{
+    //  get { return privateFontCollection; }
+    //  set { privateFontCollection = value; }
+    //}
+    // PrivateFontCollection of GDI+
+    PrivateFontCollection privateFontCollection = new PrivateFontCollection();
+#endif
+
+    /// <summary>
+    /// Gets the global font collection.
+    /// </summary>
+    public static XPrivateFontCollection Global
+    {
+      get { return s_global; }
+    }
+
+    /// <summary>
+    /// Sets a new global font collection and returns the previous one, or null if no previous one exists.
+    /// </summary>
+    public static XPrivateFontCollection SetGlobalFontCollection(XPrivateFontCollection fontCollection)
     {
-    }*/
+      if (fontCollection==null)
+        throw new ArgumentNullException("fontCollection");
+
+      XPrivateFontCollection old = s_global;
+      s_global = fontCollection;
+      return old;
+    }
 
-    public void AddMemoryFont(byte[] data, int length,
-      string fontName, bool bold, bool italic)
+#if GDI
+    /// <summary>
+    /// Adds the font data to the font collections.
+    /// </summary>
+    public void AddFont(byte[] data, string familyName)
     {
-      Initialize();
-      // Do it w/o unsafe code (do it like VB programmers do): 
+      if (String.IsNullOrEmpty(familyName))
+        throw new ArgumentNullException("familyName");
+
+      //if (glyphTypeface == null)
+      //  throw new ArgumentNullException("glyphTypeface");
+
+      // Add to GDI+ PrivateFontCollection
+      int length = data.Length;
+
+      // Copy data without unsafe code 
       IntPtr ip = Marshal.AllocCoTaskMem(length);
       Marshal.Copy(data, 0, ip, length);
-      privateFontCollection.AddMemoryFont(ip, length);
+      this.privateFontCollection.AddMemoryFont(ip, length);
       Marshal.FreeCoTaskMem(ip);
-      byte[] data2 = new byte[length];
-      Array.Copy(data, data2, length);
-      XPrivateFont pf = new XPrivateFont(fontName, bold, italic, data2, length);
-      privateFonts.Add(pf);
+      //privateFonts.Add(glyphTypeface);
+    }
+#endif
+
+    //    /// <summary>
+    //    /// Adds the glyph typeface to this collection.
+    //    /// </summary>
+    //    public void AddGlyphTypeface(XGlyphTypeface glyphTypeface)
+    //    {
+    //      if (glyphTypeface == null)
+    //        throw new ArgumentNullException("glyphTypeface");
+
+    //#if GDI
+    //      // Add to GDI+ PrivateFontCollection
+    //      byte[] data = glyphTypeface.FontData.Data;
+    //      int length = data.Length;
+
+    //      // Do it w/o unsafe code (do it like VB programmers do): 
+    //      IntPtr ip = Marshal.AllocCoTaskMem(length);
+    //      Marshal.Copy(data, 0, ip, length);
+    //      this.privateFontCollection.AddMemoryFont(ip, length);
+    //      Marshal.FreeCoTaskMem(ip);
+    //      privateFonts.Add(glyphTypeface);
+    //#endif
+    //    }
+
+#if GDI
+    /// <summary>
+    /// HACK: to be removed.
+    /// </summary>
+    //[Obsolete("Just make QBX compile. Will be removed when Private Fonts are working.", false)]
+    public void AddFont(byte[] data, string fontName, bool bold, bool italic)
+    {
+      throw new NotImplementedException("AddFont");
+      //AddGlyphTypeface(new XGlyphTypeface(data));
+    }
+
+    /// <summary>
+    /// Adds a font from the specified file to this collection.
+    /// </summary>
+    public void AddFont(string filename)
+    {
+      throw new NotImplementedException("AddFont");
+      //AddGlyphTypeface(new XGlyphTypeface(filename));
+    }
+
+    /// <summary>
+    /// Adds a font from memory to this collection.
+    /// </summary>
+    public void AddFont(byte[] data)
+    {
+      throw new NotImplementedException("AddFont");
+      //AddGlyphTypeface(new XGlyphTypeface(data));
+    }
+#endif
+
+#if WPF
+    /// <summary>
+    /// Initializes a new instance of the FontFamily class from the specified font family name and an optional base uniform resource identifier (URI) value.
+    /// Sample: Add(new Uri("pack://application:,,,/"), "./myFonts/#FontFamilyName");)
+    /// </summary>
+    /// <param name="baseUri">Specifies the base URI that is used to resolve familyName.</param>
+    /// <param name="familyName">The family name or names that comprise the new FontFamily. Multiple family names should be separated by commas.</param>
+    public void Add(Uri baseUri, string familyName)
+    {
+      // TODO: What means 'Multiple family names should be separated by commas.'?
+      // does not work
+
+      if (String.IsNullOrEmpty(familyName))
+        throw new ArgumentNullException("familyName");
+      if (familyName.Contains(","))
+        throw new NotImplementedException("Only one family name is supported.");
+
+      // family name starts right of '#'
+      int idxHash = familyName.IndexOf('#');
+      if (idxHash < 0)
+        throw new ArgumentException("Family name must contain a '#'. Example './#MyFontFamilyName'", "familyName");
+
+      string key = familyName.Substring(idxHash + 1);
+      if (String.IsNullOrEmpty(key))
+        throw new ArgumentException("familyName has invalid format.");
+
+      if (this.fontFamilies.ContainsKey(key))
+        throw new ArgumentException("An entry with the specified family name already exists.");
+
+#if !SILVERLIGHT
+      System.Windows.Media.FontFamily fontFamily = new System.Windows.Media.FontFamily(baseUri, familyName);
+#else
+      System.Windows.Media.FontFamily fontFamily = new System.Windows.Media.FontFamily(familyName);
+#endif
+
+      // Check whether font data realy exists
+#if DEBUG && !SILVERLIGHT
+      ICollection<Typeface> list = fontFamily.GetTypefaces();
+      foreach (Typeface typeFace in list)
+      {
+        //Debug.WriteLine(String.Format("{0}, {1}, {2}, {3}", typeFace.FaceNames.Values.First(), typeFace.Style, typeFace.Weight, typeFace.Stretch));
+        GlyphTypeface glyphTypeface;
+        if (!typeFace.TryGetGlyphTypeface(out glyphTypeface))
+          throw new ArgumentException("Font with the specified family name does not exist.");
+      }
+#endif
+
+      this.fontFamilies.Add(key, fontFamily);
     }
+#endif
 
-    public XPrivateFont FindFont(string fontName, bool bold, bool italic)
+#if GDI
+    internal static Font TryFindPrivateFont(string name, double size, FontStyle style)
     {
-      if (privateFonts != null)
+      try
       {
-        for (int i = 0; i < 2; ++i)
+        PrivateFontCollection pfc = GlobalPrivateFontCollection;
+        if (pfc == null)
+          return null;
+        foreach (System.Drawing.FontFamily family in pfc.Families)
         {
-          // We make 3 passes.
-          // On second pass, we ignore Bold.
-          // On third pass, we ignore Bold and Italic
-          foreach (XPrivateFont pf in privateFonts)
+          if (String.Compare(family.Name, name, true) == 0)
+            return new Font(family, (float)size, style, GraphicsUnit.World);
+        }
+      }
+      catch
+      {
+#if DEBUG
+#endif
+      }
+      return null;
+    }
+#endif
+
+#if WPF
+    internal static Typeface TryFindTypeface(string name, XFontStyle style, out System.Windows.Media.FontFamily fontFamily)
+    {
+      if (s_global.fontFamilies.TryGetValue(name, out fontFamily))
+      {
+        Typeface typeface = FontHelper.CreateTypeface(fontFamily, style);
+        return typeface;
+      }
+      return null;
+    }
+#endif
+
+#if GDI___
+    internal XGlyphTypeface FindFont(string fontName, bool bold, bool italic)
+    {
+      //if (privateFonts != null)
+      {
+        for (int i = 0; i < 3; ++i)
+        {
+          // We make 4 passes.
+          // On second pass, we ignore Italic.
+          // On third pass, we ignore Bold.
+          // On fourth pass, we ignore Bold and Italic
+          foreach (XGlyphTypeface pf in privateFonts)
           {
-            if (string.Compare(pf.FontName, fontName, true) == 0)
+            if (string.Compare(pf.FamilyName, fontName, StringComparison.InvariantCultureIgnoreCase) == 0)
             {
               switch (i)
               {
                 case 0:
-                  if (pf.Bold == bold && pf.Italic == italic)
+                  if (pf.IsBold == bold && pf.IsItalic == italic)
                     return pf;
                   break;
                 case 1:
-                  if (/*pf.Bold == bold &&*/ pf.Italic == italic)
+                  if (pf.IsBold == bold /*&& pf.Italic == italic*/)
                     return pf;
                   break;
                 case 2:
+                  if (/*pf.Bold == bold &&*/ pf.IsItalic == italic)
+                    return pf;
+                  break;
+                case 3:
                   //if (pf.Bold == bold && pf.Italic == italic)
                   return pf;
               }
@@ -127,53 +327,13 @@ namespace PdfSharp.Drawing
       }
       return null;
     }
-  }
-
-  /// <summary>
-  /// THHO4THHO: TODO!
-  /// </summary>
-  public class XPrivateFont
-  {
-    public XPrivateFont(string fontName,
-      bool bold,
-      bool italic,
-      byte[] data,
-      int length)
-    {
-      this.FontName = fontName;
-      this.Bold = bold;
-      this.Italic = italic;
-      this.Data = data;
-      this.Length = length;
-    }
-
-    internal string FontName;
-    internal bool Bold;
-    internal bool Italic;
-    internal byte[] Data;
-    internal int Length;
-
-    public int GetFontData(ref byte[] data,
-       int length)
-    {
-      if (length == this.Length)
-      {
-        // Copy the data:
-        //Data.CopyTo(data, 0);
-        Array.Copy(Data, data, length);
-      }
-      return this.Length;
-    }
-  }
 #endif
 
-#if WPF && !GDI
-  /// <summary>
-  /// Stub - yni.
-  /// </summary>
-  public class XPrivateFontCollection
-  {
-  // TODOWPF:
-  }
+#if GDI
+    //List<XGlyphTypeface> privateFonts = new List<XGlyphTypeface>();
 #endif
-}
\ No newline at end of file
+#if WPF
+    readonly Dictionary<string, System.Windows.Media.FontFamily> fontFamilies = new Dictionary<string, System.Windows.Media.FontFamily>(StringComparer.InvariantCultureIgnoreCase);
+#endif
+  }
+}
diff --git a/lib/PdfSharp/PdfSharp.Drawing/XRect.cs b/lib/PdfSharp/PdfSharp.Drawing/XRect.cs
index d167cc6..32b9243 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/XRect.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/XRect.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -43,7 +43,6 @@ using PdfSharp.Internal;
 
 namespace PdfSharp.Drawing
 {
-#if true
   /// <summary>
   /// Stores a set of four floating-point numbers that represent the location and size of a rectangle.
   /// </summary>
@@ -71,8 +70,8 @@ namespace PdfSharp.Drawing
     {
       this.x = Math.Min(point1.x, point2.x);
       this.y = Math.Min(point1.y, point2.y);
-      this.width = Math.Max((double)(Math.Max(point1.x, point2.x) - this.x), 0);
-      this.height = Math.Max((double)(Math.Max(point1.y, point2.y) - this.y), 0);
+      this.width = Math.Max(Math.Max(point1.x, point2.x) - this.x, 0);
+      this.height = Math.Max(Math.Max(point1.y, point2.y) - this.y, 0);
     }
 
     /// <summary>
@@ -212,7 +211,7 @@ namespace PdfSharp.Drawing
     {
       if (IsEmpty)
         return 0;
-      return this.X.GetHashCode() ^ this.Y.GetHashCode() ^ this.Width.GetHashCode() ^ this.Height.GetHashCode();
+      return X.GetHashCode() ^ Y.GetHashCode() ^ Width.GetHashCode() ^ Height.GetHashCode();
     }
 
     /// <summary>
@@ -237,7 +236,7 @@ namespace PdfSharp.Drawing
     /// </summary>
     public override string ToString()
     {
-      return this.ConvertToString(null, null);
+      return ConvertToString(null, null);
     }
 
     /// <summary>
@@ -245,7 +244,7 @@ namespace PdfSharp.Drawing
     /// </summary>
     public string ToString(IFormatProvider provider)
     {
-      return this.ConvertToString(null, provider);
+      return ConvertToString(null, provider);
     }
 
     /// <summary>
@@ -253,7 +252,7 @@ namespace PdfSharp.Drawing
     /// </summary>
     string IFormattable.ToString(string format, IFormatProvider provider)
     {
-      return this.ConvertToString(format, provider);
+      return ConvertToString(format, provider);
     }
 
     internal string ConvertToString(string format, IFormatProvider provider)
@@ -429,7 +428,7 @@ namespace PdfSharp.Drawing
     /// </summary>
     public XPoint TopLeft
     {
-      get { return new XPoint(this.Left, this.Top); }
+      get { return new XPoint(Left, Top); }
     }
 
     /// <summary>
@@ -437,7 +436,7 @@ namespace PdfSharp.Drawing
     /// </summary>
     public XPoint TopRight
     {
-      get { return new XPoint(this.Right, this.Top); }
+      get { return new XPoint(Right, Top); }
     }
 
     /// <summary>
@@ -445,7 +444,7 @@ namespace PdfSharp.Drawing
     /// </summary>
     public XPoint BottomLeft
     {
-      get { return new XPoint(this.Left, this.Bottom); }
+      get { return new XPoint(Left, Bottom); }
     }
 
     /// <summary>
@@ -453,7 +452,7 @@ namespace PdfSharp.Drawing
     /// </summary>
     public XPoint BottomRight
     {
-      get { return new XPoint(this.Right, this.Bottom); }
+      get { return new XPoint(Right, Bottom); }
     }
 
     /// <summary>
@@ -480,7 +479,7 @@ namespace PdfSharp.Drawing
     {
       if (IsEmpty)
         return false;
-      return this.ContainsInternal(x, y);
+      return ContainsInternal(x, y);
     }
 
     /// <summary>
@@ -499,8 +498,8 @@ namespace PdfSharp.Drawing
     public bool IntersectsWith(XRect rect)
     {
       return !IsEmpty && !rect.IsEmpty &&
-        rect.Left <= this.Right && rect.Right >= this.Left &&
-        rect.Top <= this.Bottom && rect.Bottom >= this.Top;
+          rect.Left <= Right && rect.Right >= Left &&
+          rect.Top <= Bottom && rect.Bottom >= Top;
     }
 
     /// <summary>
@@ -508,14 +507,14 @@ namespace PdfSharp.Drawing
     /// </summary>
     public void Intersect(XRect rect)
     {
-      if (!this.IntersectsWith(rect))
+      if (!IntersectsWith(rect))
         this = Empty;
       else
       {
-        double left = Math.Max(this.Left, rect.Left);
-        double top = Math.Max(this.Top, rect.Top);
-        this.width = Math.Max((double)(Math.Min(this.Right, rect.Right) - left), 0.0);
-        this.height = Math.Max((double)(Math.Min(this.Bottom, rect.Bottom) - top), 0.0);
+        double left = Math.Max(Left, rect.Left);
+        double top = Math.Max(Top, rect.Top);
+        this.width = Math.Max(Math.Min(Right, rect.Right) - left, 0.0);
+        this.height = Math.Max(Math.Min(Bottom, rect.Bottom) - top, 0.0);
         this.x = left;
         this.y = top;
       }
@@ -539,22 +538,22 @@ namespace PdfSharp.Drawing
         this = rect;
       else if (!rect.IsEmpty)
       {
-        double left = Math.Min(this.Left, rect.Left);
-        double top = Math.Min(this.Top, rect.Top);
-        if (rect.Width == Double.PositiveInfinity || this.Width == Double.PositiveInfinity)
+        double left = Math.Min(Left, rect.Left);
+        double top = Math.Min(Top, rect.Top);
+        if (rect.Width == Double.PositiveInfinity || Width == Double.PositiveInfinity)
           this.width = Double.PositiveInfinity;
         else
         {
-          double right = Math.Max(this.Right, rect.Right);
-          this.width = Math.Max((double)(right - left), 0.0);
+          double right = Math.Max(Right, rect.Right);
+          this.width = Math.Max(right - left, 0.0);
         }
 
         if (rect.Height == Double.PositiveInfinity || this.height == Double.PositiveInfinity)
           this.height = Double.PositiveInfinity;
         else
         {
-          double bottom = Math.Max(this.Bottom, rect.Bottom);
-          this.height = Math.Max((double)(bottom - top), 0.0);
+          double bottom = Math.Max(Bottom, rect.Bottom);
+          this.height = Math.Max(bottom - top, 0.0);
         }
         this.x = left;
         this.y = top;
@@ -628,7 +627,7 @@ namespace PdfSharp.Drawing
     }
 
     /// <summary>
-    /// Translates the rectangle by adding the specifed point.
+    /// Translates the rectangle by adding the specified point.
     /// </summary>
     //[Obsolete("Use Offset.")]
     public static XRect operator +(XRect rect, XPoint point)
@@ -637,7 +636,7 @@ namespace PdfSharp.Drawing
     }
 
     /// <summary>
-    /// Translates the rectangle by subtracting the specifed point.
+    /// Translates the rectangle by subtracting the specified point.
     /// </summary>
     //[Obsolete("Use Offset.")]
     public static XRect operator -(XRect rect, XPoint point)
@@ -693,7 +692,7 @@ namespace PdfSharp.Drawing
     /// </summary>
     public static XRect Transform(XRect rect, XMatrix matrix)
     {
-      XMatrix.MatrixUtil.TransformRect(ref rect, ref matrix);
+      XMatrix.MatrixHelper.TransformRect(ref rect, ref matrix);
       return rect;
     }
 
@@ -702,7 +701,7 @@ namespace PdfSharp.Drawing
     /// </summary>
     public void Transform(XMatrix matrix)
     {
-      XMatrix.MatrixUtil.TransformRect(ref this, ref matrix);
+      XMatrix.MatrixHelper.TransformRect(ref this, ref matrix);
     }
 
     /// <summary>
@@ -793,429 +792,4 @@ namespace PdfSharp.Drawing
     internal double height;
     private static readonly XRect s_empty;
   }
-
-#else
-  // Old code, delete end of 2008
-
-  /// <summary>
-  /// Stores a set of four floating-point numbers that represent the location and size of a rectangle.
-  /// </summary>
-  [DebuggerDisplay("({X}, {Y}, {Width}, {Height})")]
-  public struct XRect
-  {
-    // Called XRect and not XRectangle because XRectangle will get the name of a shape object
-    // in a forthcoming extension.
-
-    /// <summary>
-    /// Initializes a new instance of the XRect class.
-    /// </summary>
-    public XRect(double x, double y, double width, double height)
-    {
-      this.x = x;
-      this.y = y;
-      this.width = width;
-      this.height = height;
-    }
-
-    /// <summary>
-    /// Initializes a new instance of the XRect class.
-    /// </summary>
-    public XRect(XPoint location, XSize size)
-    {
-      this.x = location.X;
-      this.y = location.Y;
-      this.width = size.Width;
-      this.height = size.Height;
-    }
-
-#if GDI
-    /// <summary>
-    /// Initializes a new instance of the XRect class.
-    /// </summary>
-    public XRect(PointF location, SizeF size)
-    {
-      this.x = location.X;
-      this.y = location.Y;
-      this.width = size.Width;
-      this.height = size.Height;
-    }
-#endif
-
-#if GDI
-    /// <summary>
-    /// Initializes a new instance of the XRect class.
-    /// </summary>
-    public XRect(RectangleF rect)
-    {
-      this.x = rect.X;
-      this.y = rect.Y;
-      this.width = rect.Width;
-      this.height = rect.Height;
-    }
-#endif
-
-#if WPF
-    /// <summary>
-    /// Initializes a new instance of the XRect class.
-    /// </summary>
-    public XRect(Rect rect)
-    {
-      this.x = rect.X;
-      this.y = rect.Y;
-      this.width = rect.Width;
-      this.height = rect.Height;
-    }
-#endif
-
-    /// <summary>
-    /// Creates a rectangle from for straight lines.
-    /// </summary>
-    public static XRect FromLTRB(double left, double top, double right, double bottom)
-    {
-      return new XRect(left, top, right - left, bottom - top);
-    }
-
-    /// <summary>
-    /// Returns the hash code for this instance.
-    /// </summary>
-    public override int GetHashCode()
-    {
-      // Lutz Roeder's .NET Reflector proudly presents:
-      //   »THE ART OF HASH CODE PROGRAMMING«
-      //
-      // .NET 1.1:
-      //   return (int) (((((uint) this.X) ^ ((((uint) this.Y) << 13) | (((uint) this.Y) >> 0x13))) ^ ((((uint) this.Width) << 0x1a) | (((uint) this.Width) >> 6))) ^ ((((uint) this.Height) << 7) | (((uint) this.Height) >> 0x19)));
-      // Mono:
-      //   return (int) (x + y + width + height);
-      return (int)(x + y + width + height);
-    }
-
-    /// <summary>
-    /// Indicates whether this instance and a specified object are equal.
-    /// </summary>
-    public override bool Equals(object obj)
-    {
-      if (obj is XRect)
-      {
-        XRect rect = (XRect)obj;
-        return rect.x == this.x && rect.y == this.y && rect.width == this.width && rect.height == this.height;
-      }
-      return false;
-    }
-
-    /// <summary>
-    /// Returns a string with the values of this rectangle.
-    /// </summary>
-    public override string ToString()
-    {
-      return String.Format("{{X={0},Y={1},Width={2},Height={3}}}", this.x, this.y, this.width, this.height);
-    }
-
-#if GDI
-    /// <summary>
-    /// Converts this instance to a System.Drawing.RectangleF.
-    /// </summary>
-    public RectangleF ToRectangleF()
-    {
-      return new RectangleF((float)this.x, (float)this.y, (float)this.width, (float)this.height);
-    }
-#endif
-
-    /// <summary>
-    /// Gets a value indicating whether this rectangle is empty.
-    /// </summary>
-    [Browsable(false)]
-    public bool IsEmpty
-    {
-      // The .NET documentation differs from the actual implemention, which differs from the Mono 
-      // implementation. This is my recommendation what an empty rectangle means:
-      get { return this.width <= 0.0 || this.height <= 0.0; }
-    }
-
-    /// <summary>
-    /// Gets or sets the location of the rectangle.
-    /// </summary>
-    [Browsable(false)]
-    public XPoint Location
-    {
-      get { return new XPoint(this.x, this.y); }
-      set { this.x = value.X; this.y = value.Y; }
-    }
-
-    /// <summary>
-    /// Gets or sets the size of the rectangle.
-    /// </summary>
-    [Browsable(false)]
-    public XSize Size
-    {
-      get { return new XSize(this.width, this.height); }
-      set { this.width = value.Width; this.height = value.Height; }
-    }
-
-    /// <summary>
-    /// Gets or sets the X value.
-    /// </summary>
-    public double X
-    {
-      get { return this.x; }
-      set { this.x = value; }
-    }
-
-    /// <summary>
-    /// Gets or sets the Y value.
-    /// </summary>
-    public double Y
-    {
-      get { return this.y; }
-      set { this.y = value; }
-    }
-
-    /// <summary>
-    /// Gets or sets the width.
-    /// </summary>
-    public double Width
-    {
-      get { return this.width; }
-      set { this.width = value; }
-    }
-
-    /// <summary>
-    /// Gets or sets the height.
-    /// </summary>
-    public double Height
-    {
-      get { return this.height; }
-      set { this.height = value; }
-    }
-
-    /// <summary>
-    /// Gets the left.
-    /// </summary>
-    [Browsable(false)]
-    public double Left
-    {
-      get { return this.x; }
-    }
-
-    /// <summary>
-    /// Gets the top.
-    /// </summary>
-    [Browsable(false)]
-    public double Top
-    {
-      get { return this.y; }
-    }
-
-    /// <summary>
-    /// Gets the right.
-    /// </summary>
-    [Browsable(false)]
-    public double Right
-    {
-      get { return this.x + this.width; }
-    }
-
-    /// <summary>
-    /// Gets the bottom.
-    /// </summary>
-    [Browsable(false)]
-    public double Bottom
-    {
-      get { return this.y + this.height; }
-    }
-
-    /// <summary>
-    /// Gets the center of the rectangle.
-    /// </summary>
-    [Browsable(false)]
-    public XPoint Center
-    {
-      get { return new XPoint(this.x + this.width / 2, this.y + this.height / 2); }
-    }
-
-    /// <summary>
-    /// Determines whether the rectangle contains the specified point.
-    /// </summary>
-    public bool Contains(XPoint pt)
-    {
-      return Contains(pt.X, pt.Y);
-    }
-
-    /// <summary>
-    /// Determines whether the rectangle contains the specified point.
-    /// </summary>
-    public bool Contains(double x, double y)
-    {
-      return this.x <= x && x < this.x + this.width && this.y <= y && y < this.y + this.height;
-    }
-
-    /// <summary>
-    /// Determines whether the rectangle completely contains the specified rectangle.
-    /// </summary>
-    public bool Contains(XRect rect)
-    {
-      return this.x <= rect.x && rect.x + rect.width <= this.x + this.width &&
-             this.y <= rect.y && rect.y + rect.height <= this.y + this.height;
-    }
-
-    /// <summary>
-    /// Inflates the rectangle by the specified size.
-    /// </summary>
-    public void Inflate(XSize size)
-    {
-      Inflate(size.Width, size.Height);
-    }
-
-    /// <summary>
-    /// Inflates the rectangle by the specified size.
-    /// </summary>
-    public void Inflate(double x, double y)
-    {
-      this.x -= x;
-      this.y -= y;
-      this.width += x * 2;
-      this.height += y * 2;
-    }
-
-    /// <summary>
-    /// Inflates the rectangle by the specified size.
-    /// </summary>
-    public static XRect Inflate(XRect rect, double x, double y)
-    {
-      rect.Inflate(x, y);
-      return rect;
-    }
-
-    /// <summary>
-    /// Intersects the rectangle with the specified rectangle.
-    /// </summary>
-    public void Intersect(XRect rect)
-    {
-      rect = XRect.Intersect(rect, this);
-      this.x = rect.x;
-      this.y = rect.y;
-      this.width = rect.width;
-      this.height = rect.height;
-    }
-
-    /// <summary>
-    /// Intersects the specified rectangles.
-    /// </summary>
-    public static XRect Intersect(XRect left, XRect right)
-    {
-      double l = Math.Max(left.x, right.x);
-      double r = Math.Min(left.x + left.width, right.x + right.width);
-      double t = Math.Max(left.y, right.y);
-      double b = Math.Min(left.y + left.height, right.y + right.height);
-      if ((r >= l) && (b >= t))
-        return new XRect(l, t, r - l, b - t);
-      return XRect.Empty;
-    }
-
-    /// <summary>
-    /// Determines whether the rectangle intersects with the specified rectangle.
-    /// </summary>
-    public bool IntersectsWith(XRect rect)
-    {
-      return rect.x < this.x + this.width && this.x < rect.x + rect.width &&
-        rect.y < this.y + this.height && this.y < rect.y + rect.height;
-    }
-
-    /// <summary>
-    /// Unites the specified rectangles.
-    /// </summary>
-    public static XRect Union(XRect left, XRect right)
-    {
-      double l = Math.Min(left.X, right.X);
-      double r = Math.Max(left.X + left.Width, right.X + right.Width);
-      double t = Math.Min(left.Y, right.Y);
-      double b = Math.Max(left.Y + left.Height, right.Y + right.Height);
-      return new XRect(l, t, r - l, b - t);
-    }
-
-    /// <summary>
-    /// Translates the rectangle by the specifed offset.
-    /// </summary>
-    public void Offset(XPoint pt)
-    {
-      Offset(pt.X, pt.Y);
-    }
-
-    /// <summary>
-    /// Translates the rectangle by the specifed offset.
-    /// </summary>
-    public void Offset(double x, double y)
-    {
-      this.x += x;
-      this.y += y;
-    }
-
-    /// <summary>
-    /// Translates the rectangle by adding the specifed point.
-    /// </summary>
-    public static XRect operator +(XRect rect, XPoint point)
-    {
-      return new XRect(rect.x + point.x, rect.Y + point.y, rect.width, rect.height);
-    }
-
-    /// <summary>
-    /// Translates the rectangle by subtracting the specifed point.
-    /// </summary>
-    public static XRect operator -(XRect rect, XPoint point)
-    {
-      return new XRect(rect.x - point.x, rect.Y - point.y, rect.width, rect.height);
-    }
-
-#if GDI
-    /// <summary>
-    /// Implicit conversion from a System.Drawing.Rectangle to an XRect.
-    /// </summary>
-    public static implicit operator XRect(Rectangle rect)
-    {
-      return new XRect(rect.X, rect.Y, rect.Width, rect.Height);
-    }
-
-    /// <summary>
-    /// Implicit conversion from a System.Drawing.RectangleF to an XRect.
-    /// </summary>
-    public static implicit operator XRect(RectangleF rect)
-    {
-      return new XRect(rect.X, rect.Y, rect.Width, rect.Height);
-    }
-#endif
-
-#if WPF
-    public static implicit operator XRect(Rect rect)
-    {
-      return new XRect(rect.X, rect.Y, rect.Width, rect.Height);
-    }
-#endif
-
-    /// <summary>
-    /// Determines whether the two rectangles are equal.
-    /// </summary>
-    public static bool operator ==(XRect left, XRect right)
-    {
-      return left.x == right.x && left.y == right.y && left.width == right.width && left.height == right.height;
-    }
-
-    /// <summary>
-    /// Determines whether the two rectangles not are equal.
-    /// </summary>
-    public static bool operator !=(XRect left, XRect right)
-    {
-      return !(left == right);
-    }
-
-    /// <summary>
-    /// Represents the empty rectangle.
-    /// </summary>
-    public static readonly XRect Empty = new XRect();
-
-    internal double x;
-    internal double y;
-    internal double width;
-    internal double height;
-  }
-#endif
 }
diff --git a/lib/PdfSharp/PdfSharp.Drawing/XSize.cs b/lib/PdfSharp/PdfSharp.Drawing/XSize.cs
index a05b659..efe2de2 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/XSize.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/XSize.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -42,7 +42,6 @@ using PdfSharp.Internal;
 
 namespace PdfSharp.Drawing
 {
-#if true
   /// <summary>
   /// Represents a pair of floating-point numbers, typically the width and height of a
   /// graphical object.
@@ -124,9 +123,9 @@ namespace PdfSharp.Drawing
     /// </summary>
     public override int GetHashCode()
     {
-      if (this.IsEmpty)
+      if (IsEmpty)
         return 0;
-      return this.Width.GetHashCode() ^ this.Height.GetHashCode();
+      return Width.GetHashCode() ^ Height.GetHashCode();
     }
 
     /// <summary>
@@ -236,7 +235,7 @@ namespace PdfSharp.Drawing
     /// </summary>
     public override string ToString()
     {
-      return this.ConvertToString(null, null);
+      return ConvertToString(null, null);
     }
 
     /// <summary>
@@ -244,7 +243,7 @@ namespace PdfSharp.Drawing
     /// </summary>
     public string ToString(IFormatProvider provider)
     {
-      return this.ConvertToString(null, provider);
+      return ConvertToString(null, provider);
     }
 
     /// <summary>
@@ -252,7 +251,7 @@ namespace PdfSharp.Drawing
     /// </summary>
     string IFormattable.ToString(string format, IFormatProvider provider)
     {
-      return this.ConvertToString(format, provider);
+      return ConvertToString(format, provider);
     }
 
     internal string ConvertToString(string format, IFormatProvider provider)
@@ -269,7 +268,7 @@ namespace PdfSharp.Drawing
     /// </summary>
     public static XSize Empty
     {
-      get { return XSize.s_empty; }
+      get { return s_empty; }
     }
 
     /// <summary>
@@ -288,7 +287,7 @@ namespace PdfSharp.Drawing
       get { return this.width; }
       set
       {
-        if (this.IsEmpty)
+        if (IsEmpty)
           throw new InvalidOperationException("CannotModifyEmptySize"); //SR.Get(SRID.Size_CannotModifyEmptySize, new object[0]));
         if (value < 0)
           throw new ArgumentException("WidthCannotBeNegative"); //SR.Get(SRID.Size_WidthCannotBeNegative, new object[0]));
@@ -304,7 +303,7 @@ namespace PdfSharp.Drawing
       get { return this.height; }
       set
       {
-        if (this.IsEmpty)
+        if (IsEmpty)
           throw new InvalidOperationException("CannotModifyEmptySize"); // SR.Get(SRID.Size_CannotModifyEmptySize, new object[0]));
         if (value < 0)
           throw new ArgumentException("HeightCannotBeNegative"); //SR.Get(SRID.Size_HeightCannotBeNegative, new object[0]));
@@ -355,244 +354,4 @@ namespace PdfSharp.Drawing
     internal double height;
     private static readonly XSize s_empty;
   }
-
-#else
-  // Old code, delete end of 2008
-
-  /// <summary>
-  /// Represents a pair of floating-point numbers, typically the width and height of a
-  /// graphical object.
-  /// </summary>
-  //[DebuggerDisplay("({Width}, {Height})")]
-  [DebuggerDisplay("Width={Width.ToString(\"0.####\",System.Globalization.CultureInfo.InvariantCulture)}, Width={Width.ToString(\"0.####\",System.Globalization.CultureInfo.InvariantCulture)}")]
-  public struct XSize
-  {
-    /// <summary>
-    /// Initializes a new instance of the <see cref="XSize"/> class.
-    /// </summary>
-    public XSize(XSize size)
-    {
-      this.width = size.width;
-      this.height = size.height;
-    }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="XSize"/> class.
-    /// </summary>
-    /// <param name="pt">The pt.</param>
-    public XSize(XPoint pt)
-    {
-      this.width = pt.X;
-      this.height = pt.Y;
-    }
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="XSize"/> class.
-    /// </summary>
-    /// <param name="width">The width.</param>
-    /// <param name="height">The height.</param>
-    public XSize(double width, double height)
-    {
-      this.width = width;
-      this.height = height;
-    }
-
-    /// <summary>
-    /// Returns the hash code for this instance.
-    /// </summary>
-    public override int GetHashCode()
-    {
-      return this.width.GetHashCode() ^ this.height.GetHashCode();
-    }
-
-    /// <summary>
-    /// Indicates whether this instance and a specified object are equal.
-    /// </summary>
-    public override bool Equals(object obj)
-    {
-      if (obj is XSize)
-      {
-        XSize size = (XSize)obj;
-        return size.width == this.width && size.height == this.height;
-      }
-      return false;
-    }
-
-#if GDI
-    /// <summary>
-    /// Creates an XSize from a System.Drawing.Size.
-    /// </summary>
-    public static XSize FromSize(System.Drawing.Size size)
-    {
-      return new XSize(size.Width, size.Height);
-    }
-#endif
-
-#if WPF
-    /// <summary>
-    /// Creates an XSize from a System.Drawing.Size.
-    /// </summary>
-    public static XSize FromSize(System.Windows.Size size)
-    {
-      return new XSize(size.Width, size.Height);
-    }
-#endif
-
-#if GDI
-    /// <summary>
-    /// Creates an XSize from a System.Drawing.Size.
-    /// </summary>
-    public static XSize FromSizeF(SizeF size)
-    {
-      return new XSize(size.Width, size.Height);
-    }
-#endif
-
-    /// <summary>
-    /// Returns a string with the values of this instance.
-    /// </summary>
-    public override string ToString()
-    {
-      return string.Format("{{Width={0}, Height={1}}}", this.width, this.height);
-    }
-
-#if GDI
-    /// <summary>
-    /// Converts this XSize to a PointF.
-    /// </summary>
-    public PointF ToPointF()
-    {
-      return new PointF((float)this.width, (float)this.height);
-    }
-#endif
-
-    /// <summary>
-    /// Converts this XSize to an XPoint.
-    /// </summary>
-    public XPoint ToXPoint()
-    {
-      return new XPoint(this.width, this.height);
-    }
-
-#if GDI
-    /// <summary>
-    /// Converts this XSize to a SizeF.
-    /// </summary>
-    public SizeF ToSizeF()
-    {
-      return new SizeF((float)this.width, (float)this.height);
-    }
-#endif
-
-    /// <summary>
-    /// Gets a value indicating whether this instance is empty.
-    /// </summary>
-    [Browsable(false)]
-    public bool IsEmpty
-    {
-      get { return this.width == 0 && this.height == 0; }
-    }
-
-    /// <summary>
-    /// Gets or sets the width.
-    /// </summary>
-    public double Width
-    {
-      get { return this.width; }
-      set { this.width = value; }
-    }
-
-    /// <summary>
-    /// Gets or sets the height.
-    /// </summary>
-    public double Height
-    {
-      get { return this.height; }
-      set { this.height = value; }
-    }
-
-    /// <summary>
-    /// Adds two size objects.
-    /// </summary>
-    public static XSize operator +(XSize size1, XSize size2)
-    {
-      return new XSize(size1.width + size2.width, size1.height + size2.height);
-    }
-
-    /// <summary>
-    /// Subtracts two size objects.
-    /// </summary>
-    public static XSize operator -(XSize size1, XSize size2)
-    {
-      return new XSize(size1.width - size2.width, size1.height - size2.height);
-    }
-
-    /// <summary>
-    /// Multiplies a size with a scalar.
-    /// </summary>
-    public static XSize operator *(XSize size, double f)
-    {
-      return new XSize(size.width * f, size.height * f);
-    }
-
-    /// <summary>
-    /// Multiplies a scalar with a size.
-    /// </summary>
-    public static XSize operator *(double f, XSize size)
-    {
-      return new XSize(f * size.width, f * size.height);
-    }
-
-    /// <summary>
-    /// Divides a size by a scalar.
-    /// </summary>
-    public static XSize operator /(XSize size, double f)
-    {
-      if (f == 0)
-        throw new DivideByZeroException("Divisor is zero.");
-
-      return new XSize(size.width / f, size.height / f);
-    }
-
-    /// <summary>
-    /// Determines whether two size objects are equal.
-    /// </summary>
-    public static bool operator ==(XSize left, XSize right)
-    {
-      return left.width == right.width && left.height == right.height;
-    }
-
-    /// <summary>
-    /// Determines whether two size objects are not equal.
-    /// </summary>
-    public static bool operator !=(XSize left, XSize right)
-    {
-      return !(left == right);
-    }
-
-    /// <summary>
-    /// Explicit conversion from XSize to XPoint.
-    /// </summary>
-    public static explicit operator XPoint(XSize size)
-    {
-      return new XPoint(size.width, size.height);
-    }
-
-    /// <summary>
-    /// Explicit conversion from XSize to System.Drawing.Size.
-    /// </summary>
-    public static implicit operator XSize(System.Drawing.Size size)
-    {
-      return new XSize(size.Width, size.Height);
-    }
-
-    /// <summary>
-    /// Represents the empty size.
-    /// </summary>
-    public static readonly XSize Empty = new XSize();
-
-    internal double width;
-    internal double height;
-  }
-#endif
 }
\ No newline at end of file
diff --git a/lib/PdfSharp/PdfSharp.Drawing/XSolidBrush.cs b/lib/PdfSharp/PdfSharp.Drawing/XSolidBrush.cs
index 2f22a56..7c17be1 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/XSolidBrush.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/XSolidBrush.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Drawing/XStringFormat.cs b/lib/PdfSharp/PdfSharp.Drawing/XStringFormat.cs
index d729a5a..37dff41 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/XStringFormat.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/XStringFormat.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -41,7 +41,7 @@ using PdfSharp.Internal;
 namespace PdfSharp.Drawing
 {
   /// <summary>
-  /// Not used in this implemtation.
+  /// Not used in this implementation.
   /// </summary>
   [Flags]
   public enum XStringFormatFlags
diff --git a/lib/PdfSharp/PdfSharp.Drawing/XStringFormats.cs b/lib/PdfSharp/PdfSharp.Drawing/XStringFormats.cs
index 55ef1b3..296a444 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/XStringFormats.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/XStringFormats.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Drawing/XTypeFace.cs b/lib/PdfSharp/PdfSharp.Drawing/XTypeFace.cs
new file mode 100644
index 0000000..e892af5
--- /dev/null
+++ b/lib/PdfSharp/PdfSharp.Drawing/XTypeFace.cs
@@ -0,0 +1,778 @@
+#region PDFsharp - A .NET library for processing PDF
+//
+// Authors:
+//   Stefan Lange (mailto:Stefan Lange pdfsharp com)
+//
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
+//
+// http://www.pdfsharp.com
+// http://sourceforge.net/projects/pdfsharp
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+// DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+using System.ComponentModel;
+using System.IO;
+#if GDI
+using System.Drawing;
+using System.Drawing.Drawing2D;
+#endif
+#if WPF
+using System.Windows;
+using System.Windows.Media;
+#endif
+using PdfSharp.Internal;
+using PdfSharp.Fonts.OpenType;
+using PdfSharp.Pdf;
+using PdfSharp.Pdf.Advanced;
+
+namespace PdfSharp.Drawing
+{
+  /// <summary>
+  /// Temporary hack to implement PrivateFontCollection.
+  /// </summary>
+  class XTypefaceHack
+  {
+    public XTypefaceHack(string typefaceName)
+      : this(typefaceName, XFontStyle.Regular, XFontWeights.Normal, new XFontStretch())
+    { }
+
+    public XTypefaceHack(string typefaceName, XFontStyle style, XFontWeight weight)
+      : this(typefaceName, style, weight, new XFontStretch())
+    { }
+
+    public XTypefaceHack(string fontFamilyName, XFontStyle style, XFontWeight weight, XFontStretch stretch)
+    {
+      if (String.IsNullOrEmpty(fontFamilyName))
+        throw new ArgumentNullException("fontFamilyName");
+
+      this.fontFamilyName = fontFamilyName;
+      this.style = style;
+      this.weight = weight;
+      this.stretch = stretch;
+    }
+
+    public string FontFamilyName
+    {
+      get { return this.fontFamilyName; }
+    }
+    string fontFamilyName;
+
+    public XFontWeight Weight
+    {
+      get { return this.weight; }
+    }
+    private XFontWeight weight;
+
+    public XFontStyle Style
+    {
+      get { return this.style; }
+    }
+    private XFontStyle style;
+
+    public XFontStretch Stretch
+    {
+      get { return this.stretch; }
+    }
+    private XFontStretch stretch;
+  }
+
+
+  /// <summary>
+  /// NYI
+  /// </summary>
+  internal class XTypeface
+  {
+    //  /// <summary>
+    //  /// Construct a typeface 
+    //  /// </summary>
+    //  /// <param name="typefaceName">font typeface name</param>
+    //  public Typeface(
+    //      string typefaceName
+    //      )
+    //    // assume face name is family name until we get face name resolved properly. 
+    //    : this(
+    //        new FontFamily(typefaceName),
+    //        FontStyles.Normal,
+    //        FontWeights.Normal,
+    //        FontStretches.Normal
+    //        )
+    //  { }
+
+
+
+    //  /// <summary>
+    //  /// Construct a typeface 
+    //  /// </summary>
+    //  /// <param name="fontFamily">Font family</param>
+    //  /// <param name="style">Font style</param>
+    //  /// <param name="weight">Boldness of font</param> 
+    //  /// <param name="stretch">Width of characters</param>
+    //  public Typeface(
+    //      FontFamily fontFamily,
+    //      FontStyle style,
+    //      FontWeight weight,
+    //      FontStretch stretch
+    //      )
+    //    : this(
+    //        fontFamily,
+    //        style,
+    //        weight,
+    //        stretch,
+    //        FontFamily.FontFamilyGlobalUI
+    //        )
+    //  { }
+
+
+
+    //  /// <summary>
+    //  /// Construct a typeface 
+    //  /// </summary> 
+    //  /// <param name="fontFamily">Font family</param>
+    //  /// <param name="style">Font style</param> 
+    //  /// <param name="weight">Boldness of font</param>
+    //  /// <param name="stretch">Width of characters</param>
+    //  /// <param name="fallbackFontFamily">fallback font family</param>
+    //  public Typeface(
+    //      FontFamily fontFamily,
+    //      FontStyle style,
+    //      FontWeight weight,
+    //      FontStretch stretch,
+    //      FontFamily fallbackFontFamily
+    //      )
+    //  {
+    //    if (fontFamily == null)
+    //    {
+    //      throw new ArgumentNullException("fontFamily");
+    //    }
+
+    //    _fontFamily = fontFamily;
+    //    _style = style;
+    //    _weight = weight;
+    //    _stretch = stretch;
+    //    _fallbackFontFamily = fallbackFontFamily;
+    //  }
+
+
+
+
+    //  private FontFamily _fontFamily;
+
+    //  // these _style, _weight and _stretch are only used for storing what was passed into the constructor.
+    //  // Since FontFamily may change these values when it includes a style name implicitly, 
+    //  private FontStyle _style;
+    //  private FontWeight _weight;
+    //  private FontStretch _stretch;
+
+
+    //  /// <summary>
+    //  /// Font family 
+    //  /// </summary>
+    //  public FontFamily FontFamily
+    //  {
+    //    get { return _fontFamily; }
+    //  }
+
+
+    //  /// <summary>
+    //  /// Font weight (light, bold, etc.) 
+    //  /// </summary>
+    //  public FontWeight Weight
+    //  {
+    //    get { return _weight; }
+    //  }
+
+
+    //  /// <summary>
+    //  /// Font style (italic, oblique) 
+    //  /// </summary>
+    //  public FontStyle Style
+    //  {
+    //    get { return _style; }
+    //  }
+
+
+    //  /// <summary>
+    //  /// Font Stretch (narrow, wide, etc.) 
+    //  /// </summary>
+    //  public FontStretch Stretch
+    //  {
+    //    get { return _stretch; }
+    //  }
+
+
+
+
+    //  private FontFamily _fallbackFontFamily;
+
+    //  // Cached canonical values of the typeface. 
+    //  private CachedTypeface _cachedTypeface;
+
+
+    //  /// <summary> 
+    //  /// Returns true if FontStyle.Oblique is algorithmically simulated by
+    //  /// slanting glyphs. Returns false otherwise. 
+    //  /// </summary>
+    //  public bool IsObliqueSimulated
+    //  {
+    //    get
+    //    {
+    //      return (CachedTypeface.TypefaceMetrics.StyleSimulations & StyleSimulations.ItalicSimulation) != 0;
+    //    }
+    //  }
+
+    //  /// <summary>
+    //  /// Returns true if FontStyle.Bold is algorithmically simulated by
+    //  /// thickening glyphs. Returns false otherwise.
+    //  /// </summary> 
+    //  public bool IsBoldSimulated
+    //  {
+    //    get
+    //    {
+    //      return (CachedTypeface.TypefaceMetrics.StyleSimulations & StyleSimulations.BoldSimulation) != 0;
+    //    }
+    //  }
+
+    //  /// <summary> 
+    //  /// Obtain a glyph typeface that corresponds to the Typeface object constructed from an OpenType font family.
+    //  /// If the Typeface was constructed from a composite font family, returns null. 
+    //  /// </summary> 
+    //  /// <param name="glyphTypeface">GlyphTypeface object that corresponds to this Typeface, or null if the Typeface
+    //  /// was constructed from a composite font.</param> 
+    //  /// <returns>Whether glyphTypeface is not null.</returns>
+    //  public bool TryGetGlyphTypeface(out GlyphTypeface glyphTypeface)
+    //  {
+    //    glyphTypeface = CachedTypeface.TypefaceMetrics as GlyphTypeface;
+    //    return glyphTypeface != null;
+    //  }
+
+
+    //  /// <summary> 
+    //  /// Fallback font family
+    //  /// </summary>
+    //  internal FontFamily FallbackFontFamily
+    //  {
+    //    get { return _fallbackFontFamily; }
+    //  }
+
+    //  /// <summary>
+    //  /// (Western) x-height relative to em size. 
+    //  /// </summary>
+    //  public double XHeight
+    //  {
+    //    get
+    //    {
+    //      return CachedTypeface.TypefaceMetrics.XHeight;
+    //    }
+    //  }
+
+
+    //  /// <summary>
+    //  /// Distance from baseline to top of English capital, relative to em size.
+    //  /// </summary> 
+    //  public double CapsHeight
+    //  {
+    //    get
+    //    {
+    //      return CachedTypeface.TypefaceMetrics.CapsHeight;
+    //    }
+    //  }
+
+
+    //  /// <summary>
+    //  /// Distance from baseline to underline position 
+    //  /// </summary> 
+    //  public double UnderlinePosition
+    //  {
+    //    get
+    //    {
+    //      return CachedTypeface.TypefaceMetrics.UnderlinePosition;
+    //    }
+    //  }
+
+
+    //  /// <summary>
+    //  /// Underline thickness 
+    //  /// </summary>
+    //  public double UnderlineThickness
+    //  {
+    //    get
+    //    {
+    //      return CachedTypeface.TypefaceMetrics.UnderlineThickness;
+    //    }
+    //  }
+
+
+    //  /// <summary>
+    //  /// Distance from baseline to strike-through position
+    //  /// </summary> 
+    //  public double StrikethroughPosition
+    //  {
+    //    get
+    //    {
+    //      return CachedTypeface.TypefaceMetrics.StrikethroughPosition;
+    //    }
+    //  }
+
+
+    //  /// <summary>
+    //  /// strike-through thickness 
+    //  /// </summary> 
+    //  public double StrikethroughThickness
+    //  {
+    //    get
+    //    {
+    //      return CachedTypeface.TypefaceMetrics.StrikethroughThickness;
+    //    }
+    //  }
+
+    //  /// <summary> 
+    //  /// Collection of culture-dependant face names.
+    //  /// </summary> 
+    //  public LanguageSpecificStringDictionary FaceNames
+    //  {
+    //    get
+    //    {
+    //      return new LanguageSpecificStringDictionary(CachedTypeface.TypefaceMetrics.AdjustedFaceNames);
+    //    }
+    //  }
+
+    //  /// <summary> 
+    //  /// Distance from character cell top to English baseline relative to em size.
+    //  /// </summary>
+    //  internal double Baseline
+    //  {
+    //    get
+    //    {
+    //      return CachedTypeface.FirstFontFamily.Baseline;
+    //    }
+    //  }
+
+    //  /// <summary>
+    //  /// Baseline to baseline distance relative to em size
+    //  /// </summary> 
+    //  internal double LineSpacing
+    //  {
+    //    get
+    //    {
+    //      return CachedTypeface.FirstFontFamily.LineSpacing;
+    //    }
+    //  }
+
+    //  /// <summary> 
+    //  /// Flag indicating if the typeface is of symbol type
+    //  /// </summary> 
+    //  internal bool Symbol
+    //  {
+    //    get
+    //    {
+    //      return CachedTypeface.TypefaceMetrics.Symbol;
+    //    }
+    //  }
+
+    //  internal bool NullFont
+    //  {
+    //    get
+    //    {
+    //      return CachedTypeface.NullFont;
+    //    }
+    //  }
+
+    //  // Tries to get a GlyphTypeface based on the Typeface properties. The
+    //  // return value can be null. However, if CheckFastPathNominalGlyphs 
+    //  // returns true, then one can expect this function to return a valid 
+    //  // GlyphTypeface that maps all the specified text.
+    //  internal GlyphTypeface TryGetGlyphTypeface()
+    //  {
+    //    return CachedTypeface.TypefaceMetrics as GlyphTypeface;
+    //  }
+
+    //  internal FontStyle CanonicalStyle
+    //  {
+    //    get
+    //    {
+    //      return CachedTypeface.CanonicalStyle;
+    //    }
+    //  }
+
+    //  internal FontWeight CanonicalWeight
+    //  {
+    //    get
+    //    {
+    //      return CachedTypeface.CanonicalWeight;
+    //    }
+    //  }
+
+    //  internal FontStretch CanonicalStretch
+    //  {
+    //    get
+    //    {
+    //      return CachedTypeface.CanonicalStretch;
+    //    }
+    //  }
+
+
+    //  /// <summary>
+    //  /// Scan through specified character string checking for valid character 
+    //  /// nominal glyph.
+    //  /// </summary> 
+    //  /// <param name="charBufferRange">character buffer range</param> 
+    //  /// <param name="emSize">height of Em</param>
+    //  /// <param name="widthMax">maximum width allowed</param> 
+    //  /// <param name="keepAWord">do not stop arbitrarily in the middle of a word</param>
+    //  /// <param name="numberSubstitution">digits require complex shaping</param>
+    //  /// <param name="cultureInfo">CultureInfo of the text</param>
+    //  /// <param name="stringLengthFit">number of character fit in given width</param> 
+    //  /// <returns>whether the specified string can be optimized by nominal glyph lookup</returns>
+    //  internal bool CheckFastPathNominalGlyphs(
+    //      CharacterBufferRange charBufferRange,
+    //      double emSize,
+    //      double widthMax,
+    //      bool keepAWord,
+    //      bool numberSubstitution,
+    //      CultureInfo cultureInfo,
+    //      out int stringLengthFit
+    //      )
+    //  {
+    //    stringLengthFit = 0;
+
+    //    if (CachedTypeface.NullFont) return false;
+
+    //    GlyphTypeface glyphTypeface = TryGetGlyphTypeface();
+
+    //    if (glyphTypeface == null) return false;
+
+
+    //    stringLengthFit = 0;
+    //    IDictionary<int, ushort> cmap = glyphTypeface.CharacterToGlyphMap;
+
+    //    double totalWidth = 0;
+    //    int i = 0;
+
+    //    ushort blankGlyph = glyphTypeface.BlankGlyphIndex;
+    //    ushort glyph = blankGlyph;
+
+    //    ushort charFlagsMask = numberSubstitution ?
+    //        (ushort)(CharacterAttributeFlags.CharacterComplex | CharacterAttributeFlags.CharacterDigit) :
+    //        (ushort)CharacterAttributeFlags.CharacterComplex;
+    //    ushort charFlags = 0;
+    //    ushort charFastTextCheck = (ushort)(CharacterAttributeFlags.CharacterFastText | CharacterAttributeFlags.CharacterIdeo);
+
+    //    bool symbolTypeface = glyphTypeface.Symbol;
+    //    if (symbolTypeface)
+    //    {
+    //      // we don't care what code points are present if it's a non-Unicode font such as Symbol or Wingdings; 
+    //      // the code points don't have any standardized meanings, and we always want to bypass shaping
+    //      charFlagsMask = 0;
+    //    }
+
+    //    if (keepAWord)
+    //    {
+    //      do
+    //      {
+    //        char ch = charBufferRange[i++];
+    //        int charClass = (int)Classification.GetUnicodeClassUTF16(ch);
+    //        charFlags = Classification.CharAttributeOf(charClass).Flags;
+    //        charFastTextCheck &= charFlags;
+    //        cmap.TryGetValue(ch, out glyph);
+
+    //        totalWidth += emSize * glyphTypeface.GetAdvanceWidth(glyph);
+
+    //      } while (
+    //              i < charBufferRange.Length
+    //          && ((charFlags & charFlagsMask) == 0)
+    //          && (glyph != 0 || symbolTypeface)
+    //          && glyph != blankGlyph
+    //          );
+
+    //      // i is now at a character immediately following a leading blank 
+    //    }
+
+    //    while (
+    //            i < charBufferRange.Length
+    //        && totalWidth <= widthMax
+    //        && ((charFlags & charFlagsMask) == 0)
+    //        && (glyph != 0 || symbolTypeface)
+    //        )
+    //    {
+    //      char ch = charBufferRange[i++];
+    //      int charClass = (int)Classification.GetUnicodeClassUTF16(ch);
+    //      charFlags = Classification.CharAttributeOf(charClass).Flags;
+    //      charFastTextCheck &= charFlags;
+    //      cmap.TryGetValue(ch, out glyph);
+    //      totalWidth += emSize * glyphTypeface.GetAdvanceWidth(glyph);
+    //    }
+
+    //    if (symbolTypeface)
+    //    {
+    //      // always optimize for non-Unicode font as we don't support shaping or typographic features; 
+    //      // we also don't fall back from non-Unicode fonts so we don't care if there are missing glyphs 
+    //      stringLengthFit = i;
+    //      return true;
+    //    }
+
+    //    if (glyph == 0)
+    //    {
+    //      // character is not supported by the font
+    //      return false;
+    //    }
+
+    //    if ((charFlags & charFlagsMask) != 0)
+    //    {
+    //      // complex character encountered, exclude it
+    //      Debug.Assert(i > 0);
+
+    //      if (--i <= 0)
+    //      {
+    //        // first char is complex, fail the call 
+    //        return false;
+    //      }
+    //    }
+
+    //    stringLengthFit = i;
+    //    TypographyAvailabilities typography = glyphTypeface.FontFaceLayoutInfo.TypographyAvailabilities;
+
+    //    if ((charFastTextCheck & (byte)CharacterAttributeFlags.CharacterFastText) != 0)
+    //    {
+    //      // all input code points are Fast Text
+    //      if ((typography &
+    //               (TypographyAvailabilities.FastTextTypographyAvailable
+    //                | TypographyAvailabilities.FastTextMajorLanguageLocalizedFormAvailable
+    //               )
+    //           ) != 0
+    //         )
+    //      {
+    //        // Considered too risky to optimize. It is either because the font 
+    //        // has required features or the font has 'locl' lookup for major languages.
+    //        return false;
+    //      }
+    //      else if ((typography & TypographyAvailabilities.FastTextExtraLanguageLocalizedFormAvailable) != 0)
+    //      {
+    //        // The font has 'locl' lookup for FastText code points for non major languages. 
+    //        // Check whether the input is major langauge. If it is, we are still good to optimize.
+    //        return MajorLanguages.Contains(cultureInfo);
+    //      }
+    //      else
+    //      {
+    //        // No FastText flags are present, safe to optimize
+    //        return true;
+    //      }
+    //    }
+    //    else if ((charFastTextCheck & (byte)CharacterAttributeFlags.CharacterIdeo) != 0)
+    //    {
+    //      // The input are all ideographs, check the IdeoTypographyAvailable bit. It is safe if 
+    //      // the bit is not set.
+    //      return ((typography & TypographyAvailabilities.IdeoTypographyAvailable) == 0);
+    //    }
+    //    else
+    //    {
+    //      // for all the rest of the cases, just check whether there is any required typography 
+    //      // present at all. If none exists, it is optimizable. We might under-optimize here but
+    //      // it will be non-major languages. 
+    //      return ((typography & TypographyAvailabilities.Available) == 0);
+    //    }
+    //  }
+
+
+    //  /// <summary>
+    //  /// Lookup characters nominal glyphs and width 
+    //  /// </summary>
+    //  /// <param name="charBufferRange">character buffer range</param> 
+    //  /// <param name="emSize">height of Em</param> 
+    //  /// <param name="toIdeal"> scaling factor from real to ideal unit </param>
+    //  /// <param name="nominalWidths">glyph nominal advances in ideal units</param> 
+    //  /// <param name="idealWidth">total width in ideal units</param>
+    //  /// <returns>true for success</returns>
+    //  /// <remarks>This function is only used in fast path, and can only be called
+    //  /// if CheckFastPathNominalGlyphs has previously returned true.</remarks> 
+    //  internal void GetCharacterNominalWidthsAndIdealWidth(
+    //      CharacterBufferRange charBufferRange,
+    //      double emSize,
+    //      double toIdeal,
+    //      out int[] nominalWidths,
+    //      out int idealWidth
+    //      )
+    //  {
+    //    // This function should only be called if CheckFastPathNominalGlyphs has 
+    //    // returned true so we can assume the ITypefaceMetrics is a GlyphTypeface.
+    //    GlyphTypeface glyphTypeface = TryGetGlyphTypeface();
+    //    Invariant.Assert(glyphTypeface != null);
+
+    //    IDictionary<int, ushort> cmap = glyphTypeface.CharacterToGlyphMap;
+    //    nominalWidths = new int[charBufferRange.Length];
+    //    idealWidth = 0;
+
+    //    for (int i = 0; i < charBufferRange.Length; i++)
+    //    {
+    //      ushort glyphIndex;
+    //      cmap.TryGetValue(charBufferRange[i], out glyphIndex);
+    //      double advance = emSize * glyphTypeface.GetAdvanceWidth(glyphIndex);
+
+    //      nominalWidths[i] = (int)Math.Round(advance * toIdeal);
+    //      idealWidth += nominalWidths[i];
+    //    }
+
+    //  }
+
+
+
+    //  /// <summary> 
+    //  /// Create correspondent hash code for the object
+    //  /// </summary>
+    //  /// <returns>object hash code</returns>
+    //  public override int GetHashCode()
+    //  {
+    //    int hash = _fontFamily.GetHashCode();
+
+    //    if (_fallbackFontFamily != null)
+    //      hash = HashFn.HashMultiply(hash) + _fallbackFontFamily.GetHashCode();
+
+    //    hash = HashFn.HashMultiply(hash) + _style.GetHashCode();
+    //    hash = HashFn.HashMultiply(hash) + _weight.GetHashCode();
+    //    hash = HashFn.HashMultiply(hash) + _stretch.GetHashCode();
+    //    return HashFn.HashScramble(hash);
+    //  }
+
+
+
+    //  /// <summary>
+    //  /// Equality check
+    //  /// </summary>
+    //  public override bool Equals(object o)
+    //  {
+    //    Typeface t = o as Typeface;
+    //    if (t == null)
+    //      return false;
+
+    //    return _style == t._style
+    //        && _weight == t._weight
+    //        && _stretch == t._stretch
+    //        && _fontFamily.Equals(t._fontFamily)
+    //        && CompareFallbackFontFamily(t._fallbackFontFamily);
+    //  }
+
+
+    //  internal bool CompareFallbackFontFamily(FontFamily fallbackFontFamily)
+    //  {
+    //    if (fallbackFontFamily == null || _fallbackFontFamily == null)
+    //      return fallbackFontFamily == _fallbackFontFamily;
+
+    //    return _fallbackFontFamily.Equals(fallbackFontFamily);
+    //  }
+
+    //  //----------------------------------------
+    //  // Private method 
+    //  //----------------------------------------
+    //  private CachedTypeface CachedTypeface
+    //  {
+    //    get
+    //    {
+    //      if (_cachedTypeface == null)
+    //      {
+    //        CachedTypeface cachedTypeface = TypefaceMetricsCache.ReadonlyLookup(this) as CachedTypeface;
+
+    //        if (cachedTypeface == null)
+    //        {
+    //          cachedTypeface = ConstructCachedTypeface();
+    //          TypefaceMetricsCache.Add(this, cachedTypeface);
+    //        }
+
+    //        // For thread-safety, set the _cachedTypeface field only after we have a fully 
+    //        // initialized CachedTypeface object.
+    //        _cachedTypeface = cachedTypeface;
+    //      }
+
+    //      return _cachedTypeface;
+    //    }
+    //  }
+
+    //  private CachedTypeface ConstructCachedTypeface()
+    //  {
+    //    FontStyle canonicalStyle = _style;
+    //    FontWeight canonicalWeight = _weight;
+    //    FontStretch canonicalStretch = _stretch;
+
+    //    // 
+    //    // We always call FontFamily.FindFirstFontFamilyAndFace() method to resolve the
+    //    // canonical styles since the implied styles in FontFamily name will override 
+    //    // the given styles in the Typeface. But we don't always use the IFontFamily 
+    //    // instance returned from this method because an equal instance might already be
+    //    // cached. 
+    //    //
+    //    FontFamily sourceFontFamily = FontFamily;
+
+    //    IFontFamily firstFontFamily = sourceFontFamily.FindFirstFontFamilyAndFace(
+    //        ref canonicalStyle,
+    //        ref canonicalWeight,
+    //        ref canonicalStretch
+    //        );
+
+    //    if (firstFontFamily == null)
+    //    {
+    //      if (FallbackFontFamily != null)
+    //      {
+    //        sourceFontFamily = FallbackFontFamily;
+    //        firstFontFamily = sourceFontFamily.FindFirstFontFamilyAndFace(
+    //            ref canonicalStyle,
+    //            ref canonicalWeight,
+    //            ref canonicalStretch
+    //            );
+    //      }
+
+    //      if (firstFontFamily == null)
+    //      {
+    //        sourceFontFamily = null;
+    //        firstFontFamily = FontFamily.LookupFontFamily(FontFamily.NullFontFamilyCanonicalName);
+    //      }
+    //    }
+
+    //    // If it's a named font, map all occurrences of the same name to one cached IFontFamily.
+    //    if (sourceFontFamily != null && sourceFontFamily.Source != null)
+    //    {
+    //      // We lookup in the cache to see if there is cached IFontFamily instance of the source FontFamily. Otherwise,
+    //      // this IFontFamily value is added to the TypefaceMetrics cache. 
+    //      IFontFamily cachedValue = TypefaceMetricsCache.ReadonlyLookup(sourceFontFamily.FamilyIdentifier) as IFontFamily;
+
+    //      if (cachedValue != null)
+    //      {
+    //        firstFontFamily = cachedValue;
+    //      }
+    //      else
+    //      {
+    //        TypefaceMetricsCache.Add(sourceFontFamily.FamilyIdentifier, firstFontFamily);
+    //      }
+    //    }
+
+    //    ITypefaceMetrics typefaceMetrics = firstFontFamily.GetTypefaceMetrics(canonicalStyle, canonicalWeight, canonicalStretch);
+
+    //    return new CachedTypeface(
+    //        canonicalStyle,
+    //        canonicalWeight,
+    //        canonicalStretch,
+    //        firstFontFamily,
+    //        typefaceMetrics,
+    //        sourceFontFamily == null
+    //        );
+    //  }
+    //}
+  }
+}
diff --git a/lib/PdfSharp/PdfSharp.Drawing/XUnit.cs b/lib/PdfSharp/PdfSharp.Drawing/XUnit.cs
index ce5e9a0..439ea7b 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/XUnit.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/XUnit.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -66,7 +66,11 @@ namespace PdfSharp.Drawing
     public XUnit(double value, XGraphicsUnit type)
     {
       if (!Enum.IsDefined(typeof(XGraphicsUnit), type))
+#if !SILVERLIGHT
         throw new System.ComponentModel.InvalidEnumArgumentException("type");
+#else
+        throw new ArgumentException("type");
+#endif
 
       this.value = value;
       this.type = type;
@@ -75,7 +79,7 @@ namespace PdfSharp.Drawing
     /// <summary>
     /// Gets the raw value of the object without any conversion.
     /// To determine the XGraphicsUnit use property <code>Type</code>.
-    /// To get the value in point use the implicit convertion to double.
+    /// To get the value in point use the implicit conversion to double.
     /// </summary>
     public double Value
     {
@@ -87,7 +91,7 @@ namespace PdfSharp.Drawing
     /// </summary>
     public XGraphicsUnit Type
     {
-      get { return (XGraphicsUnit)type; }
+      get { return this.type; }
     }
 
     /// <summary>
@@ -269,7 +273,7 @@ namespace PdfSharp.Drawing
     /// Returns the object as string using the format information.
     /// The unit of measure is appended to the end of the string.
     /// </summary>
-    public string ToString(System.IFormatProvider formatProvider)
+    public string ToString(IFormatProvider formatProvider)
     {
       string valuestring;
       valuestring = this.value.ToString(formatProvider) + GetSuffix();
@@ -280,7 +284,7 @@ namespace PdfSharp.Drawing
     /// Returns the object as string using the specified format and format information.
     /// The unit of measure is appended to the end of the string.
     /// </summary>
-    string System.IFormattable.ToString(string format, IFormatProvider formatProvider)
+    string IFormattable.ToString(string format, IFormatProvider formatProvider)
     {
       string valuestring;
       valuestring = this.value.ToString(format, formatProvider) + GetSuffix();
@@ -604,14 +608,14 @@ namespace PdfSharp.Drawing
         //          break;
 
         default:
-          throw new ArgumentException("Unknown unit type: '" + type.ToString() + "'");
+          throw new ArgumentException("Unknown unit type: '" + type + "'");
       }
     }
 
     /// <summary>
     /// Represents a unit with all values zero.
     /// </summary>
-    public static readonly XUnit Zero = new XUnit();
+    public static readonly XUnit Zero;
 
     double value;
     XGraphicsUnit type;
diff --git a/lib/PdfSharp/PdfSharp.Drawing/XVector.cs b/lib/PdfSharp/PdfSharp.Drawing/XVector.cs
index f536351..6c7e028 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/XVector.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/XVector.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -46,7 +46,6 @@ namespace PdfSharp.Drawing
   /// </summary>
   [Serializable]
   [StructLayout(LayoutKind.Sequential)]
-  // [TypeConverter(typeof(VectorConverter)), ValueSerializer(typeof(VectorValueSerializer))]
   public struct XVector : IFormattable
   {
     public XVector(double x, double y)
@@ -129,7 +128,7 @@ namespace PdfSharp.Drawing
 
     internal string ConvertToString(string format, IFormatProvider provider)
     {
-      char numericListSeparator = ','; // TokenizerHelper.GetNumericListSeparator(provider);
+      const char numericListSeparator = ',';
       return string.Format(provider, "{1:" + format + "}{0}{2:" + format + "}", new object[] { numericListSeparator, this.x, this.y });
     }
 
@@ -145,8 +144,8 @@ namespace PdfSharp.Drawing
 
     public void Normalize()
     {
-      this = (XVector)(this / Math.Max(Math.Abs(this.x), Math.Abs(this.y)));
-      this = (XVector)(this / this.Length);
+      this = this / Math.Max(Math.Abs(this.x), Math.Abs(this.y));
+      this = this / Length;
     }
 
     public static double CrossProduct(XVector vector1, XVector vector2)
@@ -270,4 +269,4 @@ namespace PdfSharp.Drawing
     internal double x;
     internal double y;
   }
-}
\ No newline at end of file
+}
diff --git a/lib/PdfSharp/PdfSharp.Drawing/enums/PathStart.cs b/lib/PdfSharp/PdfSharp.Drawing/enums/PathStart.cs
index 182cd1e..44acc51 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/enums/PathStart.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/enums/PathStart.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Drawing/enums/XColorSpace.cs b/lib/PdfSharp/PdfSharp.Drawing/enums/XColorSpace.cs
index 5d7b664..d4bafab 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/enums/XColorSpace.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/enums/XColorSpace.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Drawing/enums/XCombineMode.cs b/lib/PdfSharp/PdfSharp.Drawing/enums/XCombineMode.cs
index 6e8ce05..b072084 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/enums/XCombineMode.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/enums/XCombineMode.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Drawing/enums/XDashStyle.cs b/lib/PdfSharp/PdfSharp.Drawing/enums/XDashStyle.cs
index d06f9db..77def01 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/enums/XDashStyle.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/enums/XDashStyle.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Drawing/enums/XFillMode.cs b/lib/PdfSharp/PdfSharp.Drawing/enums/XFillMode.cs
index f6163d9..ccd54b7 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/enums/XFillMode.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/enums/XFillMode.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Drawing/enums/XFontStyle.cs b/lib/PdfSharp/PdfSharp.Drawing/enums/XFontStyle.cs
index f844bb7..6ebaf4f 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/enums/XFontStyle.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/enums/XFontStyle.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Drawing/enums/XGraphicRenderTarget.cs b/lib/PdfSharp/PdfSharp.Drawing/enums/XGraphicRenderTarget.cs
index 236f39a..b4bcafe 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/enums/XGraphicRenderTarget.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/enums/XGraphicRenderTarget.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -41,7 +41,7 @@ namespace PdfSharp.Drawing
     GDI = 1,
 
     /// <summary>
-    /// Renders using WPF.
+    /// Renders using WPF (including Silverlight).
     /// </summary>
     WPF = 2,
   }
diff --git a/lib/PdfSharp/PdfSharp.Drawing/enums/XGraphicsPathItemType.cs b/lib/PdfSharp/PdfSharp.Drawing/enums/XGraphicsPathItemType.cs
index 031c7b0..fdbbe4a 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/enums/XGraphicsPathItemType.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/enums/XGraphicsPathItemType.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Drawing/enums/XGraphicsPdfPageOptions.cs b/lib/PdfSharp/PdfSharp.Drawing/enums/XGraphicsPdfPageOptions.cs
index b1a9004..256527b 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/enums/XGraphicsPdfPageOptions.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/enums/XGraphicsPdfPageOptions.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -30,7 +30,7 @@
 namespace PdfSharp.Drawing
 {
   /// <summary>
-  /// Specifies how the content of an exisiting PDF page and new content is combined.
+  /// Specifies how the content of an existing PDF page and new content is combined.
   /// </summary>
   public enum XGraphicsPdfPageOptions
   {
diff --git a/lib/PdfSharp/PdfSharp.Drawing/enums/XGraphicsUnit.cs b/lib/PdfSharp/PdfSharp.Drawing/enums/XGraphicsUnit.cs
index 57a6124..522cc06 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/enums/XGraphicsUnit.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/enums/XGraphicsUnit.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Drawing/enums/XKnownColor.cs b/lib/PdfSharp/PdfSharp.Drawing/enums/XKnownColor.cs
index a955e45..31d34c4 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/enums/XKnownColor.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/enums/XKnownColor.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Drawing/enums/XLineAlignment.cs b/lib/PdfSharp/PdfSharp.Drawing/enums/XLineAlignment.cs
index 4470366..bcc41eb 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/enums/XLineAlignment.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/enums/XLineAlignment.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Drawing/enums/XLineCap.cs b/lib/PdfSharp/PdfSharp.Drawing/enums/XLineCap.cs
index 0c5ccce..4b7d734 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/enums/XLineCap.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/enums/XLineCap.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Drawing/enums/XLineJoin.cs b/lib/PdfSharp/PdfSharp.Drawing/enums/XLineJoin.cs
index c77a627..3863995 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/enums/XLineJoin.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/enums/XLineJoin.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Drawing/enums/XLinearGradientMode.cs b/lib/PdfSharp/PdfSharp.Drawing/enums/XLinearGradientMode.cs
index 5918575..a6e466b 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/enums/XLinearGradientMode.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/enums/XLinearGradientMode.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Drawing/enums/XMatrixOrder.cs b/lib/PdfSharp/PdfSharp.Drawing/enums/XMatrixOrder.cs
index aebdad1..aa782f5 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/enums/XMatrixOrder.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/enums/XMatrixOrder.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Drawing/enums/XPageDirection.cs b/lib/PdfSharp/PdfSharp.Drawing/enums/XPageDirection.cs
index 5c9eb33..2a2af79 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/enums/XPageDirection.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/enums/XPageDirection.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Drawing/enums/XSmoothingMode.cs b/lib/PdfSharp/PdfSharp.Drawing/enums/XSmoothingMode.cs
index ff8bdec..48c2aad 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/enums/XSmoothingMode.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/enums/XSmoothingMode.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Drawing/enums/XStringAlignment.cs b/lib/PdfSharp/PdfSharp.Drawing/enums/XStringAlignment.cs
index 69ba911..c6c1034 100644
--- a/lib/PdfSharp/PdfSharp.Drawing/enums/XStringAlignment.cs
+++ b/lib/PdfSharp/PdfSharp.Drawing/enums/XStringAlignment.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Fonts.OpenType/ExternalHelper.cs b/lib/PdfSharp/PdfSharp.Fonts.OpenType/ExternalHelper.cs
new file mode 100644
index 0000000..90455a2
--- /dev/null
+++ b/lib/PdfSharp/PdfSharp.Fonts.OpenType/ExternalHelper.cs
@@ -0,0 +1,77 @@
+#region PDFsharp - A .NET library for processing PDF
+//
+// Authors:
+//   Stefan Lange (mailto:Stefan Lange pdfsharp com)
+//
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
+//
+// http://www.pdfsharp.com
+// http://sourceforge.net/projects/pdfsharp
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+// DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+using System.Text;
+#if GDI
+using System.Drawing;
+using System.Drawing.Drawing2D;
+#endif
+#if WPF
+using System.Windows;
+using System.Windows.Media;
+#endif
+using PdfSharp.Pdf;
+using PdfSharp.Pdf.Internal;
+using PdfSharp.Drawing;
+
+namespace PdfSharp.Fonts.OpenType
+{
+  /// <summary>
+  /// PDFsharp internal stuff.
+  /// For more information see Andrew Schulman "Undocumented PDFsharp"  :-))
+  /// </summary>
+  public static class ExternalHelper
+  {
+    /// <summary>
+    /// This is an external helper function.
+    /// </summary>
+    public static byte[] F74167FFE4044F53B28A4AF049E9EF25(XFont font, XPdfFontOptions options, bool subset)
+    {
+      byte[] data = null;
+      if (subset)
+      {
+        OpenTypeDescriptor descriptor = new OpenTypeDescriptor(font, options);
+        FontData image = descriptor.fontData;
+        CMapInfo cmapInfo = new CMapInfo(descriptor);
+        cmapInfo.AddAnsiChars();
+        image = image.CreateFontSubSet(cmapInfo.GlyphIndices, false);
+        data = image.Data;
+      }
+      else
+      {
+        FontData fontData = new FontData(font, options);
+        data = fontData.Data;
+      }
+      return data;
+    }
+  }
+}
\ No newline at end of file
diff --git a/lib/PdfSharp/PdfSharp.Fonts.OpenType/FontData.cs b/lib/PdfSharp/PdfSharp.Fonts.OpenType/FontData.cs
new file mode 100644
index 0000000..efb18e4
Binary files /dev/null and b/lib/PdfSharp/PdfSharp.Fonts.OpenType/FontData.cs differ
diff --git a/lib/PdfSharp/PdfSharp.Fonts.OpenType/FontDataStock.cs b/lib/PdfSharp/PdfSharp.Fonts.OpenType/FontDataStock.cs
new file mode 100644
index 0000000..160b840
--- /dev/null
+++ b/lib/PdfSharp/PdfSharp.Fonts.OpenType/FontDataStock.cs
@@ -0,0 +1,145 @@
+#region PDFsharp - A .NET library for processing PDF
+//
+// Authors:
+//   Stefan Lange (mailto:Stefan Lange pdfsharp com)
+//
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
+//
+// http://www.pdfsharp.com
+// http://sourceforge.net/projects/pdfsharp
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+// DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Diagnostics;
+using System.Collections.Generic;
+using PdfSharp.Drawing;
+using PdfSharp.Fonts.OpenType;
+
+namespace PdfSharp.Fonts.OpenType
+{
+  /// <summary>
+  /// Global table of TrueType font faces.
+  /// </summary>
+  class FontDataStock  // TODO: rename
+  {
+    FontDataStock()
+    {
+      this.fontDataTable = new Dictionary<string, FontData>();
+    }
+
+    public FontData RegisterFontData(byte[] data)
+    {
+      uint checksum = CalcChecksum(data);
+      string key = String.Format("??{0:X}", checksum);
+
+      FontData fontData;
+      if (!this.fontDataTable.TryGetValue(key, out fontData))
+      {
+        lock (typeof(FontDataStock))
+        {
+          // may be created by other thread meanwhile
+          if (!this.fontDataTable.TryGetValue(key, out fontData))
+          {
+            fontData = new FontData(data);
+            this.fontDataTable.Add(key, fontData);
+            this.lastEntry = fontData;
+          }
+        }
+      }
+      return fontData;
+    }
+    private FontData lastEntry;
+
+    public bool UnregisterFontData(FontData fontData)
+    {
+      Debug.Assert(false);
+      return false;
+    }
+
+    internal FontData[] GetFontDataList()
+    {
+      int count = fontDataTable.Values.Count;
+      FontData[] fontDataArray = new FontData[count];
+      fontDataTable.Values.CopyTo(fontDataArray, 0);
+      return fontDataArray;
+    }
+
+    //internal FontData FindFont(XTypefaceHack typeface)
+    //{
+    //  // HACK: 
+    //  if (this.fontDataTable.Count > 1)
+    //    return this.lastEntry;
+    //  return null;
+    //}
+
+    /// <summary>
+    /// Calculates an Adler32 checksum.
+    /// </summary>
+    static uint CalcChecksum(byte[] buffer)
+    {
+      if (buffer == null)
+        throw new ArgumentNullException("buffer");
+
+      const uint BASE = 65521; // largest prime smaller than 65536
+      uint s1 = 0;
+      uint s2 = 0;
+      int length = buffer.Length;
+      int offset = 0;
+      while (length > 0)
+      {
+        int n = 3800;
+        if (n > length)
+          n = length;
+        length -= n;
+        while (--n >= 0)
+        {
+          s1 = s1 + (uint)(buffer[offset++] & 0xFF);
+          s2 = s2 + s1;
+        }
+        s1 %= BASE;
+        s2 %= BASE;
+      }
+      return (s2 << 16) | s1;
+    }
+
+    /// <summary>
+    /// Gets the singleton.
+    /// </summary>
+    public static FontDataStock Global
+    {
+      get
+      {
+        if (global == null)
+        {
+          lock (typeof(FontDataStock))
+          {
+            if (global == null)
+              global = new FontDataStock();
+          }
+        }
+        return global;
+      }
+    }
+    static FontDataStock global;
+
+    Dictionary<string, FontData> fontDataTable;
+  }
+}
diff --git a/lib/PdfSharp/PdfSharp.Fonts.OpenType/GenericFontTable.cs b/lib/PdfSharp/PdfSharp.Fonts.OpenType/GenericFontTable.cs
new file mode 100644
index 0000000..478336c
--- /dev/null
+++ b/lib/PdfSharp/PdfSharp.Fonts.OpenType/GenericFontTable.cs
@@ -0,0 +1,74 @@
+#region PDFsharp - A .NET library for processing PDF
+//
+// Authors:
+//   Stefan Lange (mailto:Stefan Lange pdfsharp com)
+//
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
+//
+// http://www.pdfsharp.com
+// http://sourceforge.net/projects/pdfsharp
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+// DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+using PdfSharp.Drawing;
+using PdfSharp.Internal;
+
+using Fixed = System.Int32;
+using FWord = System.Int16;
+using UFWord = System.UInt16;
+
+namespace PdfSharp.Fonts.OpenType
+{
+  /// <summary>
+  /// Generic font table. Not yet used
+  /// </summary>
+  internal class GenericFontTable : OpenTypeFontTable
+  {
+    public GenericFontTable(OpenTypeFontTable fontTable)
+      : base(null, "xxxx")
+    {
+      DirectoryEntry.Tag = fontTable.DirectoryEntry.Tag;
+      int length = fontTable.DirectoryEntry.Length;
+      if (length > 0)
+      {
+        this.table = new byte[length];
+        Buffer.BlockCopy(fontTable.FontData.Data, fontTable.DirectoryEntry.Offset, this.table, 0, length);
+      }
+    }
+
+    public GenericFontTable(FontData fontData, string tag)
+      : base(fontData, tag)
+    {
+      this.fontData = fontData;
+    }
+
+    protected override OpenTypeFontTable DeepCopy()
+    {
+      GenericFontTable fontTable = (GenericFontTable)base.DeepCopy();
+      fontTable.table = (byte[])this.table.Clone();
+      return fontTable;
+    }
+
+    byte[] table;
+  }
+}
diff --git a/lib/PdfSharp/PdfSharp.Fonts.OpenType/GlyphDataTable.cs b/lib/PdfSharp/PdfSharp.Fonts.OpenType/GlyphDataTable.cs
new file mode 100644
index 0000000..713d55f
Binary files /dev/null and b/lib/PdfSharp/PdfSharp.Fonts.OpenType/GlyphDataTable.cs differ
diff --git a/lib/PdfSharp/PdfSharp.Fonts.OpenType/IRefFontTable.cs b/lib/PdfSharp/PdfSharp.Fonts.OpenType/IRefFontTable.cs
new file mode 100644
index 0000000..c4d52b1
--- /dev/null
+++ b/lib/PdfSharp/PdfSharp.Fonts.OpenType/IRefFontTable.cs
@@ -0,0 +1,87 @@
+#region PDFsharp - A .NET library for processing PDF
+//
+// Authors:
+//   Stefan Lange (mailto:Stefan Lange pdfsharp com)
+//
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
+//
+// http://www.pdfsharp.com
+// http://sourceforge.net/projects/pdfsharp
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+// DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+using PdfSharp.Drawing;
+using PdfSharp.Internal;
+
+using Fixed = System.Int32;
+using FWord = System.Int16;
+using UFWord = System.UInt16;
+
+namespace PdfSharp.Fonts.OpenType
+{
+  /// <summary>
+  /// Represents an indirect reference to an existing font table in a font image.
+  /// Used to create binary copies of an existing font table that is not modified.
+  /// </summary>
+  internal class IRefFontTable : OpenTypeFontTable
+  {
+    public IRefFontTable(FontData fontData, OpenTypeFontTable fontTable)
+      : base(null, fontTable.DirectoryEntry.Tag)
+    {
+      this.fontData = fontData;
+      this.irefDirectoryEntry = fontTable.DirectoryEntry;
+    }
+
+    TableDirectoryEntry irefDirectoryEntry;
+
+    /// <summary>
+    /// Prepares the font table to be compiled into its binary representation.
+    /// </summary>
+    public override void PrepareForCompilation()
+    {
+      base.PrepareForCompilation();
+      DirectoryEntry.Length = this.irefDirectoryEntry.Length;
+      DirectoryEntry.CheckSum = this.irefDirectoryEntry.CheckSum;
+#if DEBUG
+      // Check the checksum algorithm
+      if (DirectoryEntry.Tag != TableTagNames.Head)
+      {
+        byte[] bytes = new byte[DirectoryEntry.PaddedLength];
+        Buffer.BlockCopy(this.irefDirectoryEntry.FontTable.fontData.Data, this.irefDirectoryEntry.Offset, bytes, 0, DirectoryEntry.PaddedLength);
+        uint checkSum1 = DirectoryEntry.CheckSum;
+        uint checkSum2 = CalcChecksum(bytes);
+        // TODO: Sometimes this Assert fails,
+        //Debug.Assert(checkSum1 == checkSum2, "Bug in checksum algorithm.");
+      }
+#endif
+    }
+
+    /// <summary>
+    /// Converts the font into its binary representation.
+    /// </summary>
+    public override void Write(OpenTypeFontWriter writer)
+    {
+      writer.Write(this.irefDirectoryEntry.FontTable.fontData.Data, this.irefDirectoryEntry.Offset, this.irefDirectoryEntry.PaddedLength);
+    }
+  }
+}
diff --git a/lib/PdfSharp/PdfSharp.Fonts.OpenType/IndexToLocationTable.cs b/lib/PdfSharp/PdfSharp.Fonts.OpenType/IndexToLocationTable.cs
new file mode 100644
index 0000000..26d5391
Binary files /dev/null and b/lib/PdfSharp/PdfSharp.Fonts.OpenType/IndexToLocationTable.cs differ
diff --git a/lib/PdfSharp/PdfSharp.Fonts.OpenType/OpenTypeDescriptor.cs b/lib/PdfSharp/PdfSharp.Fonts.OpenType/OpenTypeDescriptor.cs
new file mode 100644
index 0000000..bd44378
--- /dev/null
+++ b/lib/PdfSharp/PdfSharp.Fonts.OpenType/OpenTypeDescriptor.cs
@@ -0,0 +1,380 @@
+#region PDFsharp - A .NET library for processing PDF
+//
+// Authors:
+//   Stefan Lange (mailto:Stefan Lange pdfsharp com)
+//
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
+//
+// http://www.pdfsharp.com
+// http://sourceforge.net/projects/pdfsharp
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+// DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Diagnostics;
+using System.Globalization;
+using System.Runtime.InteropServices;
+using System.Text;
+#if GDI
+using System.Drawing;
+using System.Drawing.Drawing2D;
+#endif
+#if WPF
+using System.Windows;
+using System.Windows.Media;
+#endif
+using PdfSharp.Pdf.Internal;
+using PdfSharp.Drawing;
+
+namespace PdfSharp.Fonts.OpenType
+{
+  /// <summary>
+  /// The OpenType font descriptor.
+  /// </summary>
+  internal sealed class OpenTypeDescriptor : FontDescriptor
+  {
+    public OpenTypeDescriptor(XFont font, XPdfFontOptions options)
+    {
+      try
+      {
+        this.fontData = new FontData(font, options);
+        this.fontName = font.Name;
+        Initialize();
+      }
+      catch
+      {
+        throw;
+      }
+    }
+
+    //#if WPF
+    //    public TrueTypeDescriptor(XFont font, XPdfFontOptions options)
+    //    {
+    //      try
+    //      {
+    //        this.fontData = new FontData(font, options);
+    //        this.fontName = font.Name;
+    //        Initialize();
+    //      }
+    //      catch (Exception ex)
+    //      {
+    //        throw ex;
+    //      }
+    //    }
+    //#endif
+
+    //internal TrueTypeDescriptor(FontSelector selector)
+    //{
+    //  throw new NotImplementedException("TrueTypeDescriptor(FontSelector selector)");
+    //}
+
+    internal OpenTypeDescriptor(XFont font)
+      : this(font, font.PdfOptions)
+    { }
+
+    internal OpenTypeDescriptor(string idName, byte[] fontData)
+    {
+      try
+      {
+        this.fontData = new FontData(fontData);
+        // Try to get real name form name table
+        if (idName.Contains("XPS-Font-") && this.fontData.name != null && this.fontData.name.Name.Length != 0)
+        {
+          string tag = String.Empty;
+          if (idName.IndexOf('+') == 6)
+            tag = idName.Substring(0, 6);
+          idName = tag + "+" + this.fontData.name.Name;
+          if (this.fontData.name.Style.Length != 0)
+            idName += "," + this.fontData.name.Style;
+          idName = idName.Replace(" ", "");
+        }
+        this.fontName = idName;
+        Initialize();
+      }
+      catch (Exception ex)
+      {
+        throw ex;
+      }
+    }
+
+    internal OpenTypeDescriptor(byte[] fontData)
+    {
+      try
+      {
+        this.fontData = new FontData(fontData);
+        // Try to get real name form name table
+        string name = this.fontData.name.Name;
+        if (this.fontData.name.Style.Length != 0)
+          name += "," + this.fontData.name.Style;
+        name = name.Replace(" ", "");
+        this.fontName = name;
+        Initialize();
+      }
+      catch
+      {
+        throw;
+      }
+    }
+
+    internal FontData fontData;
+
+    void Initialize()
+    {
+      //bool embeddingRestricted = this.fontData.os2.fsType == 0x0002;
+
+      //this.fontName = image.n
+      this.italicAngle = this.fontData.post.italicAngle;
+
+      this.xMin = this.fontData.head.xMin;
+      this.yMin = this.fontData.head.yMin;
+      this.xMax = this.fontData.head.xMax;
+      this.yMax = this.fontData.head.yMax;
+
+      this.underlinePosition = this.fontData.post.underlinePosition;
+      this.underlineThickness = this.fontData.post.underlineThickness;
+      this.strikeoutPosition = this.fontData.os2.yStrikeoutPosition;
+      this.strikeoutSize = this.fontData.os2.yStrikeoutSize;
+
+      // No documetation found how to get the set vertical stems width from the
+      // TrueType tables.
+      // The following formula comes from PDFlib Lite source code. Acrobat 5.0 sets
+      // /StemV to 0 always. I think the value doesn't matter.
+      //float weight = (float)(this.image.os2.usWeightClass / 65.0f);
+      //this.stemV = (int)(50 + weight * weight);  // MAGIC
+      this.stemV = 0;
+
+      // PDFlib states that some Apple fonts miss the OS/2 table.
+      Debug.Assert(fontData.os2 != null, "TrueType font has no OS/2 table.");
+
+      this.unitsPerEm = fontData.head.unitsPerEm;
+
+      // PDFlib takes sTypoAscender and sTypoDescender from OS/2 tabel, but GDI+ uses usWinAscent and usWinDescent
+      if (fontData.os2.sTypoAscender != 0)
+        this.ascender = fontData.os2.usWinAscent;
+      else
+        this.ascender = fontData.hhea.ascender;
+      Debug.Assert(this.ascender > 0, "PDFsharp internal: Ascender should be greater than 0.");
+
+      if (fontData.os2.sTypoDescender != 0)
+      {
+        this.descender = fontData.os2.usWinDescent;
+        Debug.Assert(this.descender > 0, "PDFsharp internal: Font with non positive ascender value found.");
+#if true_
+        Debug.WriteLine(String.Format(CultureInfo.InvariantCulture,
+          "os2.usWinDescent={0}, hhea.descender={1}, os2.sTypoDescender={2}", fontData.os2.usWinDescent, fontData.hhea.descender, fontData.os2.sTypoDescender));
+#endif
+        // Force sign from hhea.descender
+        // TODO:
+        this.descender = Math.Abs(this.descender) * Math.Sign(fontData.hhea.descender);
+      }
+      else
+        this.descender = fontData.hhea.descender;
+      Debug.Assert(this.descender < 0, "PDFsharp internal: Ascender should be less than 0.");
+
+      this.leading = fontData.hhea.lineGap;
+
+      // sCapHeight and sxHeight are only valid if version >= 2
+      if (fontData.os2.version >= 2 && fontData.os2.sCapHeight != 0)
+        this.capHeight = fontData.os2.sCapHeight;
+      else
+        this.capHeight = fontData.hhea.ascender;
+
+      if (fontData.os2.version >= 2 && fontData.os2.sxHeight != 0)
+        this.xHeight = fontData.os2.sxHeight;
+      else
+        this.xHeight = (int)(0.66f * this.ascender);
+
+      //this.flags = this.image.
+
+      Encoding ansi = PdfEncoders.WinAnsiEncoding; // System.Text.Encoding.Default;
+      Encoding unicode = Encoding.Unicode;
+      byte[] bytes = new byte[256];
+
+      bool symbol = this.fontData.cmap.symbol;
+      this.widths = new int[256];
+      for (int idx = 0; idx < 256; idx++)
+      {
+        bytes[idx] = (byte)idx;
+        // PDFlib handles some font flaws here...
+        // We wait for bug reports.
+
+        char ch = (char)idx;
+        string s = ansi.GetString(bytes, idx, 1);
+        if (s.Length != 0)
+        {
+          if (s[0] != ch)
+            ch = s[0];
+        }
+#if DEBUG
+        if (idx == 'S')
+          GetType();
+#endif
+        int glyphIndex;
+        if (symbol)
+        {
+          glyphIndex = idx + (this.fontData.os2.usFirstCharIndex & 0xFF00);
+          glyphIndex = CharCodeToGlyphIndex((char)glyphIndex);
+        }
+        else
+        {
+          //Debug.Assert(idx + (this.fontData.os2.usFirstCharIndex & 0xFF00) == idx);
+          //glyphIndex = CharCodeToGlyphIndex((char)idx);
+          glyphIndex = CharCodeToGlyphIndex(ch);
+        }
+        this.widths[idx] = GlyphIndexToPdfWidth(glyphIndex);
+      }
+    }
+    public int[] widths;
+
+    /// <summary>
+    /// Gets a value indicating whether this instance belongs to a bold font.
+    /// </summary>
+    public override bool IsBoldFace
+    {
+      get
+      {
+        // usWeightClass 700 is Bold
+        //Debug.Assert((this.fontData.os2.usWeightClass >= 700) == ((this.fontData.os2.fsSelection & (ushort)OS2Table.FontSelectionFlags.Bold) != 0));
+        return (this.fontData.os2.fsSelection & (ushort)OS2Table.FontSelectionFlags.Bold) != 0;
+      }
+    }
+
+    /// <summary>
+    /// Gets a value indicating whether this instance belongs to an italic font.
+    /// </summary>
+    public override bool IsItalicFace
+    {
+      get { return (this.fontData.os2.fsSelection & (ushort)OS2Table.FontSelectionFlags.Italic) != 0; }
+    }
+
+    internal int DesignUnitsToPdf(double value)
+    {
+      return (int)Math.Round(value * 1000.0 / this.fontData.head.unitsPerEm);
+    }
+
+    /// <summary>
+    /// Maps a unicode to the index of the corresponding glyph.
+    /// See OpenType spec "cmap - Character To Glyph Index Mapping Table / Format 4: Segment mapping to delta values"
+    /// for details about this a little bit strange looking algorithm.
+    /// </summary>
+    public int CharCodeToGlyphIndex(char value)
+    {
+      try
+      {
+        CMap4 cmap = this.fontData.cmap.cmap4;
+        int segCount = cmap.segCountX2 / 2;
+        int seg;
+        for (seg = 0; seg < segCount; seg++)
+        {
+          if (value <= cmap.endCount[seg])
+            break;
+        }
+        Debug.Assert(seg < segCount);
+
+        if (value < cmap.startCount[seg])
+          return 0;
+
+        if (cmap.idRangeOffs[seg] == 0)
+          return (value + cmap.idDelta[seg]) & 0xFFFF;
+
+        int idx = cmap.idRangeOffs[seg] / 2 + (value - cmap.startCount[seg]) - (segCount - seg);
+        Debug.Assert(idx >= 0 && idx < cmap.glyphCount);
+
+        if (cmap.glyphIdArray[idx] == 0)
+          return 0;
+        
+        return (cmap.glyphIdArray[idx] + cmap.idDelta[seg]) & 0xFFFF;
+      }
+      catch
+      {
+        throw;
+      }
+    }
+
+    /// <summary>
+    /// Converts the width of a glyph identified by its index to PDF design units.
+    /// </summary>
+    public int GlyphIndexToPdfWidth(int glyphIndex)
+    {
+      try
+      {
+        int numberOfHMetrics = this.fontData.hhea.numberOfHMetrics;
+        int unitsPerEm = this.fontData.head.unitsPerEm;
+
+        // glyphIndex >= numberOfHMetrics means the font is mono-spaced and all glyphs have the same width
+        if (glyphIndex >= numberOfHMetrics)
+          glyphIndex = numberOfHMetrics - 1;
+
+        int width = this.fontData.hmtx.metrics[glyphIndex].advanceWidth;
+
+        // Sometimes the unitsPerEm is 1000, sometimes a power of 2.
+        if (unitsPerEm == 1000)
+          return width;
+        return width * 1000 / unitsPerEm; // normalize
+      }
+      catch (Exception ex)
+      {
+        throw ex;
+      }
+    }
+
+    public int PdfWidthFromCharCode(char ch)
+    {
+      int idx = CharCodeToGlyphIndex(ch);
+      int width = GlyphIndexToPdfWidth(idx);
+      return width;
+    }
+
+#if DEBUG_
+    public static void Test()
+    {
+      Font font = new Font("Times New Roman", 10);
+      FontData image = new FontData(font);
+
+//      Font font = new Font("Isabelle", 12);
+//      LOGFONT logFont = new LOGFONT();
+//      font.ToLogFont(logFont);
+//
+//      IntPtr hfont = CreateFontIndirect(logFont);
+////      IntPtr hfont2 = font.ToHfont();
+////      System.Windows.Forms.MessageBox.Show(hfont2.ToString());
+//
+//      Graphics gfx = Graphics.FromHwnd(IntPtr.Zero);
+//      IntPtr hdc = gfx.GetHdc();
+//      IntPtr oldFont =  SelectObject(hdc, hfont);
+//      int size = GetFontData(hdc, 0, 0, null, 0);
+//
+//      byte[] fontbits = new byte[size];
+//      int xx = GetFontData(hdc, 0, 0, fontbits, size);
+//      SelectObject(hdc, oldFont);
+//      DeleteObject(hfont);
+//      gfx.ReleaseHdc(hdc);
+//
+//      FontData image = new FontData(fontbits);
+//      //image.Read();
+//
+//
+//      //HandleRef
+//
+//      font.GetType();
+    }
+#endif
+  }
+}
\ No newline at end of file
diff --git a/lib/PdfSharp/PdfSharp.Fonts.OpenType/OpenTypeFontTable.cs b/lib/PdfSharp/PdfSharp.Fonts.OpenType/OpenTypeFontTable.cs
new file mode 100644
index 0000000..3c086dd
--- /dev/null
+++ b/lib/PdfSharp/PdfSharp.Fonts.OpenType/OpenTypeFontTable.cs
@@ -0,0 +1,118 @@
+#region PDFsharp - A .NET library for processing PDF
+//
+// Authors:
+//   Stefan Lange (mailto:Stefan Lange pdfsharp com)
+//
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
+//
+// http://www.pdfsharp.com
+// http://sourceforge.net/projects/pdfsharp
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+// DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+using PdfSharp.Drawing;
+using PdfSharp.Internal;
+
+using Fixed = System.Int32;
+using FWord = System.Int16;
+using UFWord = System.UInt16;
+
+namespace PdfSharp.Fonts.OpenType
+{
+  /// <summary>
+  /// Base class for all OpenType fonts.
+  /// </summary>
+  internal class OpenTypeFontTable : ICloneable
+  {
+    public OpenTypeFontTable(FontData fontData, string tag)
+    {
+      this.fontData = fontData;
+      if (fontData != null && fontData.tableDictionary.ContainsKey(tag))
+        this.DirectoryEntry = fontData.tableDictionary[tag];
+      else
+        this.DirectoryEntry = new TableDirectoryEntry(tag);
+      this.DirectoryEntry.FontTable = this;
+    }
+
+    /// <summary>
+    /// Creates a deep copy of the current instance.
+    /// </summary>
+    public object Clone()
+    {
+      return DeepCopy();
+    }
+
+    protected virtual OpenTypeFontTable DeepCopy()
+    {
+      OpenTypeFontTable fontTable = (OpenTypeFontTable)MemberwiseClone();
+      fontTable.DirectoryEntry.Offset = 0;
+      fontTable.DirectoryEntry.FontTable = fontTable;
+      return fontTable;
+    }
+
+    /// <summary>
+    /// Gets the font image the table belongs to.
+    /// </summary>
+    public FontData FontData
+    {
+      get { return this.fontData; }
+    }
+    internal FontData fontData;
+
+    public TableDirectoryEntry DirectoryEntry;
+
+    /// <summary>
+    /// When overridden in a derived class, prepares the font table to be compiled into its binary representation.
+    /// </summary>
+    public virtual void PrepareForCompilation()
+    {
+    }
+
+    /// <summary>
+    /// When overridden in a derived class, converts the font into its binary representation.
+    /// </summary>
+    public virtual void Write(OpenTypeFontWriter writer)
+    {
+    }
+
+    /// <summary>
+    /// Calculates the checksum of a table represented by its bytes.
+    /// </summary>
+    public static uint CalcChecksum(byte[] bytes)
+    {
+      Debug.Assert((bytes.Length & 3) == 0);
+      // Cannot use Buffer.BlockCopy because 32-bit values are Big-endian
+      uint byte3, byte2, byte1, byte0;
+      byte3 = byte2 = byte1 = byte0 = 0;
+      int length = bytes.Length;
+      for (int idx = 0; idx < length;)
+      {
+        byte3 += bytes[idx++];
+        byte2 += bytes[idx++];
+        byte1 += bytes[idx++];
+        byte0 += bytes[idx++];
+      }
+      return (byte3 << 24) + (byte2 << 16) + (byte1 << 8) + byte0;
+    }
+  }
+}
diff --git a/lib/PdfSharp/PdfSharp.Fonts.OpenType/OpenTypeFontWriter.cs b/lib/PdfSharp/PdfSharp.Fonts.OpenType/OpenTypeFontWriter.cs
new file mode 100644
index 0000000..170f3b6
--- /dev/null
+++ b/lib/PdfSharp/PdfSharp.Fonts.OpenType/OpenTypeFontWriter.cs
@@ -0,0 +1,62 @@
+#region PDFsharp - A .NET library for processing PDF
+//
+// Authors:
+//   Stefan Lange (mailto:Stefan Lange pdfsharp com)
+//
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
+//
+// http://www.pdfsharp.com
+// http://sourceforge.net/projects/pdfsharp
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+// DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Diagnostics;
+using System.Collections.Generic;
+using System.Text;
+using System.IO;
+
+namespace PdfSharp.Fonts.OpenType
+{
+  /// <summary>
+  /// Represents a writer for True Type font files. 
+  /// </summary>
+  internal class OpenTypeFontWriter : FontWriter
+  {
+    /// <summary>
+    /// Initializes a new instance of the <see cref="OpenTypeFontWriter"/> class.
+    /// </summary>
+    public OpenTypeFontWriter(Stream stream)
+      : base(stream)
+    { }
+
+    /// <summary>
+    /// Writes a table name.
+    /// </summary>
+    public void WriteTag(string tag)
+    {
+      Debug.Assert(tag.Length == 4);
+      WriteByte((byte)(tag[0]));
+      WriteByte((byte)(tag[1]));
+      WriteByte((byte)(tag[2]));
+      WriteByte((byte)(tag[3]));
+    }
+  }
+}
diff --git a/lib/PdfSharp/PdfSharp.Fonts.OpenType/OpenTypeStructures.cs b/lib/PdfSharp/PdfSharp.Fonts.OpenType/OpenTypeStructures.cs
new file mode 100644
index 0000000..cb3922f
Binary files /dev/null and b/lib/PdfSharp/PdfSharp.Fonts.OpenType/OpenTypeStructures.cs differ
diff --git a/lib/PdfSharp/PdfSharp.Fonts.OpenType/TableDirectoryEntry.cs b/lib/PdfSharp/PdfSharp.Fonts.OpenType/TableDirectoryEntry.cs
new file mode 100644
index 0000000..5deb496
Binary files /dev/null and b/lib/PdfSharp/PdfSharp.Fonts.OpenType/TableDirectoryEntry.cs differ
diff --git a/lib/PdfSharp/PdfSharp.Fonts.OpenType/enums/FontTechnology.cs b/lib/PdfSharp/PdfSharp.Fonts.OpenType/enums/FontTechnology.cs
new file mode 100644
index 0000000..de3245f
--- /dev/null
+++ b/lib/PdfSharp/PdfSharp.Fonts.OpenType/enums/FontTechnology.cs
@@ -0,0 +1,55 @@
+#region PDFsharp - A .NET library for processing PDF
+//
+// Authors:
+//   Stefan Lange (mailto:Stefan Lange pdfsharp com)
+//
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
+//
+// http://www.pdfsharp.com
+// http://sourceforge.net/projects/pdfsharp
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+// DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Diagnostics;
+
+namespace PdfSharp.Fonts.OpenType
+{
+  /// <summary>
+  /// Identifies the technology of an OpenType font file.
+  /// </summary>
+  enum FontTechnology
+  {
+    /// <summary>
+    /// Font is Adobe Postscript font in CFF.
+    /// </summary>
+    PostscriptOutlines,
+
+    /// <summary>
+    /// Font is a TrueType font.
+    /// </summary>
+    TrueTypeOutlines,
+
+    /// <summary>
+    /// Font is a TrueType font collection.
+    /// </summary>
+    TrueTypeCollection
+  }
+}
\ No newline at end of file
diff --git a/lib/PdfSharp/PdfSharp.Fonts.OpenType/enums/TableTag.cs b/lib/PdfSharp/PdfSharp.Fonts.OpenType/enums/TableTag.cs
new file mode 100644
index 0000000..03b8290
--- /dev/null
+++ b/lib/PdfSharp/PdfSharp.Fonts.OpenType/enums/TableTag.cs
@@ -0,0 +1,38 @@
+#region PDFsharp - A .NET library for processing PDF
+//
+// Authors:
+//   Stefan Lange (mailto:Stefan Lange pdfsharp com)
+//
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
+//
+// http://www.pdfsharp.com
+// http://sourceforge.net/projects/pdfsharp
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+// DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Diagnostics;
+
+namespace PdfSharp.Fonts.OpenType
+{
+  //enum TableTag
+  //{
+  //}
+}
\ No newline at end of file
diff --git a/lib/PdfSharp/PdfSharp.Fonts.OpenType/enums/TableTagNames.cs b/lib/PdfSharp/PdfSharp.Fonts.OpenType/enums/TableTagNames.cs
new file mode 100644
index 0000000..b387ceb
--- /dev/null
+++ b/lib/PdfSharp/PdfSharp.Fonts.OpenType/enums/TableTagNames.cs
@@ -0,0 +1,212 @@
+#region PDFsharp - A .NET library for processing PDF
+//
+// Authors:
+//   Stefan Lange (mailto:Stefan Lange pdfsharp com)
+//
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
+//
+// http://www.pdfsharp.com
+// http://sourceforge.net/projects/pdfsharp
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+// DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Diagnostics;
+
+namespace PdfSharp.Fonts.OpenType
+{
+  /// <summary>
+  /// TrueType font table names.
+  /// </summary>
+  static class TableTagNames
+  {
+    // --- Required Tables ---
+
+    /// <summary>
+    /// Character to glyph mapping.
+    /// </summary>
+    public const  string CMap = "cmap";
+
+    /// <summary>
+    /// Font header .
+    /// </summary>
+    public const string Head = "head"; 
+
+    /// <summary>
+    /// Horizontal header.
+    /// </summary>
+    public const string HHea = "hhea";
+
+    /// <summary>
+    /// Horizontal metrics.
+    /// </summary>
+    public const string HMtx = "hmtx";
+
+    /// <summary>
+    /// Maximum profile.
+    /// </summary>
+    public const string MaxP = "maxp";
+
+    /// <summary>
+    /// Naming table.
+    /// </summary>
+    public const string Name = "name";
+
+    /// <summary>
+    /// OS/2 and Windows specific metrics.
+    /// </summary>
+    public const  string OS2 = "OS/2";
+
+    /// <summary>
+    /// PostScript information.
+    /// </summary>
+    public const string Post = "post";
+
+    // --- Tables Related to TrueType Outlines ---
+    
+    /// <summary>
+    /// Control Value Table.
+    /// </summary>
+    public const string Cvt = "cvt ";
+    
+    /// <summary>
+    /// Font program.
+    /// </summary>
+    public const string Fpgm = "fpgm";
+    
+    /// <summary>
+    /// Glyph data.
+    /// </summary>
+    public const string Glyf = "glyf";
+    
+    /// <summary>
+    /// Index to location.
+    /// </summary>
+    public const string Loca = "loca";
+    
+    /// <summary>
+    /// CVT Program.
+    /// </summary>
+    public const string Prep = "prep";
+
+    // --- Tables Related to PostScript Outlines ---
+    
+    /// <summary>
+    /// PostScript font program (compact font format).
+    /// </summary>
+    public const string Cff = "CFF";
+    
+    /// <summary>
+    /// Vertical Origin.
+    /// </summary>
+    public const string VOrg = "VORG";
+
+    // --- Tables Related to Bitmap Glyphs ---
+    
+    /// <summary>
+    /// Embedded bitmap data.
+    /// </summary>
+    public const string EBDT = "EBDT";
+    
+    /// <summary>
+    /// Embedded bitmap location data.
+    /// </summary>
+    public const string EBLC = "EBLC";
+    
+    /// <summary>
+    /// Embedded bitmap scaling data.
+    /// </summary>
+    public const string EBSC = "EBSC";
+
+    // --- Advanced Typographic Tables ---
+    
+    /// <summary>
+    /// Baseline data.
+    /// </summary>
+    public const string BASE = "BASE";
+    
+    /// <summary>
+    /// Glyph definition data.
+    /// </summary>
+    public const string GDEF = "GDEF";
+    
+    /// <summary>
+    /// Glyph positioning data.
+    /// </summary>
+    public const string GPOS = "GPOS";
+    
+    /// <summary>
+    /// Glyph substitution data.
+    /// </summary>
+    public const string GSUB = "GSUB";
+    
+    /// <summary>
+    /// Justification data.
+    /// </summary>
+    public const string JSTF = "JSTF";
+
+    // --- Other OpenType Tables ---
+    
+    /// <summary>
+    /// Digital signature.
+    /// </summary>
+    public const string DSIG = "DSIG";
+    
+    /// <summary>
+    /// Grid-fitting/Scan-conversion.
+    /// </summary>
+    public const string Gasp = "gasp";
+    
+    /// <summary>
+    /// Horizontal device metrics.
+    /// </summary>
+    public const string Hdmx = "hdmx";
+    
+    /// <summary>
+    /// Kerning.
+    /// </summary>
+    public const string Kern = "kern";
+    
+    /// <summary>
+    /// Linear threshold data.
+    /// </summary>
+    public const string LTSH = "LTSH";
+    
+    /// <summary>
+    /// PCL 5 data.
+    /// </summary>
+    public const string PCLT = "PCLT";
+    
+    /// <summary>
+    /// Vertical device metrics.
+    /// </summary>
+    public const string VDMX = "VDMX";
+    
+    /// <summary>
+    /// Vertical Header.
+    /// </summary>
+    public const string VHea = "vhea";
+    
+    /// <summary>
+    /// Vertical Metrics.
+    /// </summary>
+    public const string VMtx = "vmtx";
+  }
+}
\ No newline at end of file
diff --git a/lib/PdfSharp/PdfSharp.Fonts/AdobeGlyphList20.cs b/lib/PdfSharp/PdfSharp.Fonts/AdobeGlyphList20.cs
index 76a1717..b85e4fa 100644
--- a/lib/PdfSharp/PdfSharp.Fonts/AdobeGlyphList20.cs
+++ b/lib/PdfSharp/PdfSharp.Fonts/AdobeGlyphList20.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -27,10 +27,8 @@
 // DEALINGS IN THE SOFTWARE.
 #endregion
 
-//#pragma warning disable 1591
-
 using System;
-#if DEBUG
+#if DEBUG_
 namespace PdfSharp.Fonts
 {
   /// <summary>
diff --git a/lib/PdfSharp/PdfSharp.Fonts/AdobeGlyphListForNewFonts.cs b/lib/PdfSharp/PdfSharp.Fonts/AdobeGlyphListForNewFonts.cs
index acacb9c..d752fd8 100644
--- a/lib/PdfSharp/PdfSharp.Fonts/AdobeGlyphListForNewFonts.cs
+++ b/lib/PdfSharp/PdfSharp.Fonts/AdobeGlyphListForNewFonts.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -38,6 +38,8 @@ namespace PdfSharp.Fonts
   {
     AdobeGlyphListForNewFonts() { }
 
+    // ReSharper disable InconsistentNaming
+
     /// <summary>
     /// LATIN CAPITAL LETTER A
     /// </summary>
diff --git a/lib/PdfSharp/PdfSharp.Fonts/CMapInfo.cs b/lib/PdfSharp/PdfSharp.Fonts/CMapInfo.cs
index 3285b07..e15e4f7 100644
--- a/lib/PdfSharp/PdfSharp.Fonts/CMapInfo.cs
+++ b/lib/PdfSharp/PdfSharp.Fonts/CMapInfo.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -32,7 +32,7 @@ using System.Diagnostics;
 using System.Text;
 using System.Collections;
 using System.Collections.Generic;
-using PdfSharp.Fonts.TrueType;
+using PdfSharp.Fonts.OpenType;
 using PdfSharp.Pdf.Internal;
 
 namespace PdfSharp.Fonts
@@ -42,15 +42,15 @@ namespace PdfSharp.Fonts
   /// </summary>
   internal class CMapInfo
   {
-    public CMapInfo(TrueTypeDescriptor descriptor)
+    public CMapInfo(OpenTypeDescriptor descriptor)
     {
       Debug.Assert(descriptor != null);
       this.descriptor = descriptor;
     }
-    internal TrueTypeDescriptor descriptor;
+    internal OpenTypeDescriptor descriptor;
 
     /// <summary>
-    /// Adds the characters of the specifed string the the hashtable.
+    /// Adds the characters of the specified string to the hashtable.
     /// </summary>
     public void AddChars(string text)
     {
@@ -68,7 +68,7 @@ namespace PdfSharp.Fonts
             {
               if (symbol)
               {
-                glyphIndex = (int)ch + (descriptor.fontData.os2.usFirstCharIndex & 0xFF00); // @@@
+                glyphIndex = ch + (descriptor.fontData.os2.usFirstCharIndex & 0xFF00); // @@@
                 glyphIndex = descriptor.CharCodeToGlyphIndex((char)glyphIndex);
               }
               else
@@ -86,6 +86,22 @@ namespace PdfSharp.Fonts
     }
 
     /// <summary>
+    /// Adds the glyphIndices to the hashtable.
+    /// </summary>
+    public void AddGlyphIndices(string glyphIndices)
+    {
+      if (glyphIndices != null)
+      {
+        int length = glyphIndices.Length;
+        for (int idx = 0; idx < length; idx++)
+        {
+          int glyphIndex = glyphIndices[idx];
+          GlyphIndices[glyphIndex] = null;
+        }
+      }
+    }
+
+    /// <summary>
     /// Adds a ANSI characters.
     /// </summary>
     internal void AddAnsiChars()
@@ -93,7 +109,7 @@ namespace PdfSharp.Fonts
       byte[] ansi = new byte[256 - 32];
       for (int idx = 0; idx < 256 - 32; idx++)
         ansi[idx] = (byte)(idx + 32);
-      string text = PdfEncoders.WinAnsiEncoding.GetString(ansi);
+      string text = PdfEncoders.WinAnsiEncoding.GetString(ansi, 0, ansi.Length);  // AGHACK
       AddChars(text);
     }
 
@@ -113,6 +129,14 @@ namespace PdfSharp.Fonts
       }
     }
 
+    public int[] GetGlyphIndices()
+    {
+      int[] indices = new int[GlyphIndices.Count];
+      GlyphIndices.Keys.CopyTo(indices, 0);
+      Array.Sort(indices);
+      return indices;
+    }
+
     public char MinChar = Char.MaxValue;
     public char MaxChar = Char.MinValue;
     public Dictionary<char, int> CharacterToGlyphIndex = new Dictionary<char, int>();
diff --git a/lib/PdfSharp/PdfSharp.Fonts/FontDescriptor.cs b/lib/PdfSharp/PdfSharp.Fonts/FontDescriptor.cs
new file mode 100644
index 0000000..ad5a794
--- /dev/null
+++ b/lib/PdfSharp/PdfSharp.Fonts/FontDescriptor.cs
@@ -0,0 +1,330 @@
+#region PDFsharp - A .NET library for processing PDF
+//
+// Authors:
+//   Stefan Lange (mailto:Stefan Lange pdfsharp com)
+//
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
+//
+// http://www.pdfsharp.com
+// http://sourceforge.net/projects/pdfsharp
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+// DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+using System.Text;
+#if GDI
+using System.Drawing;
+using System.Drawing.Drawing2D;
+#endif
+#if WPF
+using System.Windows;
+using System.Windows.Media;
+#endif
+using PdfSharp.Pdf.Internal;
+using PdfSharp.Drawing;
+
+namespace PdfSharp.Fonts
+{
+  /// <summary>
+  /// Base class for all font descriptors.
+  /// </summary>
+  internal class FontDescriptor
+  {
+    /// <summary>
+    /// 
+    /// </summary>
+    public string FontFile
+    {
+      get { return this.fontFile; }
+    }
+    protected string fontFile;
+
+    /// <summary>
+    /// 
+    /// </summary>
+    public string FontType
+    {
+      get { return this.fontType; }
+    }
+    protected string fontType;
+
+    /// <summary>
+    /// 
+    /// </summary>
+    public string FontName
+    {
+      get { return this.fontName; }
+    }
+    protected string fontName;
+
+    /// <summary>
+    /// 
+    /// </summary>
+    public string FullName
+    {
+      get { return this.fullName; }
+    }
+    protected string fullName;
+
+    /// <summary>
+    /// 
+    /// </summary>
+    public string FamilyName
+    {
+      get { return this.familyName; }
+    }
+    protected string familyName;
+
+    /// <summary>
+    /// 
+    /// </summary>
+    public string Weight
+    {
+      get { return this.weight; }
+    }
+    protected string weight;
+
+    /// <summary>
+    /// Gets a value indicating whether this instance belongs to a bold font.
+    /// </summary>
+    public virtual bool IsBoldFace
+    {
+      get { return false; }
+    }
+
+    /// <summary>
+    /// 
+    /// </summary>
+    public float ItalicAngle
+    {
+      get { return this.italicAngle; }
+    }
+    protected float italicAngle;
+
+    /// <summary>
+    /// Gets a value indicating whether this instance belongs to an italic font.
+    /// </summary>
+    public virtual bool IsItalicFace
+    {
+      get { return false; }
+    }
+
+    /// <summary>
+    /// 
+    /// </summary>
+    public int XMin
+    {
+      get { return this.xMin; }
+    }
+    protected int xMin;
+
+    /// <summary>
+    /// 
+    /// </summary>
+    public int YMin
+    {
+      get { return this.yMin; }
+    }
+    protected int yMin;
+
+    /// <summary>
+    /// 
+    /// </summary>
+    public int XMax
+    {
+      get { return this.xMax; }
+    }
+    protected int xMax;
+
+    /// <summary>
+    /// 
+    /// </summary>
+    public int YMax
+    {
+      get { return this.yMax; }
+    }
+    protected int yMax;
+
+    /// <summary>
+    /// 
+    /// </summary>
+    public bool IsFixedPitch
+    {
+      get { return this.isFixedPitch; }
+    }
+    protected bool isFixedPitch;
+
+    //Rect FontBBox;
+
+    /// <summary>
+    /// 
+    /// </summary>
+    public int UnderlinePosition
+    {
+      get { return this.underlinePosition; }
+    }
+    protected int underlinePosition;
+
+    /// <summary>
+    /// 
+    /// </summary>
+    public int UnderlineThickness
+    {
+      get { return this.underlineThickness; }
+    }
+    protected int underlineThickness;
+
+    /// <summary>
+    /// 
+    /// </summary>
+    public int StrikeoutPosition
+    {
+      get { return this.strikeoutPosition; }
+    }
+    protected int strikeoutPosition;
+
+    /// <summary>
+    /// 
+    /// </summary>
+    public int StrikeoutSize
+    {
+      get { return this.strikeoutSize; }
+    }
+    protected int strikeoutSize;
+
+    /// <summary>
+    /// 
+    /// </summary>
+    public string Version
+    {
+      get { return this.version; }
+    }
+    protected string version;
+
+    ///// <summary>
+    ///// 
+    ///// </summary>
+    //public string Notice
+    //{
+    //  get { return this.Notice; }
+    //}
+    //protected string notice;
+
+    /// <summary>
+    /// 
+    /// </summary>
+    public string EncodingScheme
+    {
+      get { return this.encodingScheme; }
+    }
+    protected string encodingScheme;
+
+    /// <summary>
+    /// 
+    /// </summary>
+    public int UnitsPerEm
+    {
+      get { return this.unitsPerEm; }
+    }
+    protected int unitsPerEm;
+
+    /// <summary>
+    /// 
+    /// </summary>
+    public int CapHeight
+    {
+      get { return this.capHeight; }
+    }
+    protected int capHeight;
+
+    /// <summary>
+    /// 
+    /// </summary>
+    public int XHeight
+    {
+      get { return this.xHeight; }
+    }
+    protected int xHeight;
+
+    /// <summary>
+    /// 
+    /// </summary>
+    public int Ascender
+    {
+      get { return this.ascender; }
+    }
+    protected int ascender;
+
+    /// <summary>
+    /// 
+    /// </summary>
+    public int Descender
+    {
+      get { return this.descender; }
+    }
+    protected int descender;
+
+    /// <summary>
+    /// 
+    /// </summary>
+    public int Leading
+    {
+      get { return this.leading; }
+    }
+    protected int leading;
+
+    /// <summary>
+    /// 
+    /// </summary>
+    public int Flags
+    {
+      get { return this.flags; }
+    }
+    protected int flags;
+
+    /// <summary>
+    /// 
+    /// </summary>
+    public int StemV
+    {
+      get { return this.stemV; }
+    }
+    protected int stemV;
+
+    /// <summary>
+    /// Under Construction
+    /// </summary>
+    public XFontMetrics FontMetrics
+    {
+      get
+      {
+        if (this.fontMetrics == null)
+        {
+          this.fontMetrics = new XFontMetrics(this.fontName, this.unitsPerEm, this.ascender, this.descender, this.leading, this.capHeight,
+            this.xHeight, this.stemV, 0, 0, 0);
+        }
+        return this.fontMetrics;
+      }
+    }
+    XFontMetrics fontMetrics;
+  }
+}
\ No newline at end of file
diff --git a/lib/PdfSharp/PdfSharp.Fonts/FontDescriptorStock.cs b/lib/PdfSharp/PdfSharp.Fonts/FontDescriptorStock.cs
new file mode 100644
index 0000000..6845520
--- /dev/null
+++ b/lib/PdfSharp/PdfSharp.Fonts/FontDescriptorStock.cs
@@ -0,0 +1,548 @@
+#region PDFsharp - A .NET library for processing PDF
+//
+// Authors:
+//   Stefan Lange (mailto:Stefan Lange pdfsharp com)
+//
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
+//
+// http://www.pdfsharp.com
+// http://sourceforge.net/projects/pdfsharp
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+// DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Diagnostics;
+using System.Collections.Generic;
+using PdfSharp.Drawing;
+using PdfSharp.Fonts.OpenType;
+
+namespace PdfSharp.Fonts
+{
+#if true
+  /// <summary>
+  /// Global table of TrueType fontdescriptor objects.
+  /// </summary>
+  class FontDescriptorStock
+  {
+    FontDescriptorStock()
+    {
+      this.table = new Dictionary<FontSelector, FontDescriptor>();
+    }
+
+    /// <summary>
+    /// Gets the FontDescriptor identified by the specified FontSelector. Returns null if no
+    /// such objects exists.
+    /// </summary>
+    public FontDescriptor FindDescriptor(FontSelector selector)
+    {
+      if (selector == null)
+        return null;
+
+      FontDescriptor descriptor = this.table[selector] as FontDescriptor;
+      return descriptor;
+    }
+
+    ///// <summary>
+    ///// Gets the FontDescriptor identified by the specified FontSelector. If no such objects 
+    ///// exists, a new FontDescriptor is created and added to the stock.
+    ///// </summary>
+    //public FontDescriptor CreateDescriptor(FontSelector selector)
+    //{
+    //  if (selector == null)
+    //    throw new ArgumentNullException("selector");
+
+    //  FontDescriptor descriptor = this.table[selector] as FontDescriptor;
+    //  if (descriptor == null)
+    //  {
+    //    descriptor = new TrueTypeDescriptor(selector);
+    //    this.table.Add(selector, descriptor);
+    //  }
+    //  return descriptor;
+    //}
+
+    /// <summary>
+    /// Gets the FontDescriptor identified by the specified FontSelector. If no such objects 
+    /// exists, a new FontDescriptor is created and added to the stock.
+    /// </summary>
+    public FontDescriptor CreateDescriptor(XFont font)
+    {
+      if (font == null)
+        throw new ArgumentNullException("font");
+
+      FontSelector selector = new FontSelector(font);
+      FontDescriptor descriptor;
+      if (!this.table.TryGetValue(selector, out descriptor))
+      {
+        lock (typeof(FontDescriptorStock))
+        {
+          // may be created by other thread meanwhile
+          if (!this.table.TryGetValue(selector, out descriptor))
+          {
+            descriptor = new OpenTypeDescriptor(font);
+            this.table.Add(selector, descriptor);
+          }
+        }
+      }
+      return descriptor;
+    }
+
+    /// <summary>
+    /// Gets the FontDescriptor identified by the specified FontSelector. If no such objects 
+    /// exists, a new FontDescriptor is created and added to the stock.
+    /// </summary>
+    public FontDescriptor CreateDescriptor(XFontFamily family, XFontStyle style)
+    {
+      if (family == null)
+        throw new ArgumentNullException("family");
+
+      FontSelector selector = new FontSelector(family, style);
+      FontDescriptor descriptor;
+      if (!this.table.TryGetValue(selector, out descriptor))
+      {
+        lock (typeof(FontDescriptorStock))
+        {
+          // may be created by other thread meanwhile
+          if (!this.table.TryGetValue(selector, out descriptor))
+          {
+            XFont font = new XFont(family.Name, 10, style);
+            descriptor = new OpenTypeDescriptor(font);
+            if (this.table.ContainsKey(selector))
+              GetType();
+            else
+              this.table.Add(selector, descriptor);
+          }
+        }
+      }
+      return descriptor;
+    }
+
+    public FontDescriptor CreateDescriptor(string idName, byte[] fontData)
+    {
+      FontSelector selector = new FontSelector(idName);
+      FontDescriptor descriptor;
+      if (!this.table.TryGetValue(selector, out descriptor))
+      {
+        lock (typeof(FontDescriptorStock))
+        {
+          // may be created by other thread meanwhile
+          if (!this.table.TryGetValue(selector, out descriptor))
+          {
+            descriptor = new OpenTypeDescriptor(idName, fontData);
+            this.table.Add(selector, descriptor);
+          }
+        }
+      }
+      return descriptor;
+    }
+
+    //public FontDescriptor RegisterFontDate(byte[] fontData)
+    //{
+    //  uint checksum = CalcChecksum(fontData);
+    //  string name = String.Format("??{0:X}", checksum);
+    //  FontSelector selector = new FontSelector(name); // HACK: font data distinguished only by checksum
+    //  FontDescriptor descriptor = this.table[selector] as FontDescriptor;
+    //  if (descriptor == null)
+    //  {
+    //    lock (typeof(FontDescriptorStock))
+    //    {
+    //      // may be created by other thread meanwhile
+    //      descriptor = this.table[selector] as FontDescriptor;
+    //      if (descriptor == null)
+    //      {
+    //        descriptor = new TrueTypeDescriptor(fontData);
+    //        this.table.Add(selector, descriptor);
+    //      }
+    //    }
+    //  }
+    //  return descriptor;
+    //}
+
+    ///// <summary>
+    ///// Calculates an Adler32 checksum.
+    ///// </summary>
+    //uint CalcChecksum(byte[] buffer)
+    //{
+    //  if (buffer == null)
+    //    throw new ArgumentNullException("buffer");
+
+    //  const uint BASE = 65521; // largest prime smaller than 65536
+    //  uint s1 = 0;
+    //  uint s2 = 0;
+    //  int length = buffer.Length;
+    //  int offset = 0;
+    //  while (length > 0)
+    //  {
+    //    int n = 3800;
+    //    if (n > length)
+    //      n = length;
+    //    length -= n;
+    //    while (--n >= 0)
+    //    {
+    //      s1 = s1 + (uint)(buffer[offset++] & 0xFF);
+    //      s2 = s2 + s1;
+    //    }
+    //    s1 %= BASE;
+    //    s2 %= BASE;
+    //  }
+    //  return (s2 << 16) | s1;
+    //}
+
+    public static FontDescriptorStock Global
+    {
+      get
+      {
+        if (global == null)
+        {
+          lock (typeof(FontDescriptorStock))
+          {
+            if (global == null)
+              global = new FontDescriptorStock();
+          }
+        }
+        return global;
+      }
+    }
+    static FontDescriptorStock global;
+
+    Dictionary<FontSelector, FontDescriptor> table;
+
+    /// <summary>
+    /// A collection of information that uniquely identifies a particular font.
+    /// Used to map XFont to PdfFont.
+    /// There is a one to one relationship between a FontSelector and a TrueType/OpenType file.
+    /// </summary>
+    internal class FontSelector
+    {
+      public FontSelector(XFont font)
+      {
+        this.name = font.Name;
+        this.style = font.Style;
+      }
+
+      public FontSelector(XFontFamily family, XFontStyle style)
+      {
+        this.name = family.Name;
+        this.style = style;
+      }
+
+      public FontSelector(string idName)
+      {
+        this.name = idName;
+        this.style = XFontStyle.Regular;
+      }
+
+      public string Name
+      {
+        get { return this.name; }
+      }
+      string name;
+
+      public XFontStyle Style
+      {
+        get { return this.style; }
+      }
+      XFontStyle style;
+
+      public static bool operator ==(FontSelector selector1, FontSelector selector2)
+      {
+        if (!Equals(selector1, null))
+          selector1.Equals(selector2);
+        return Equals(selector2, null);
+      }
+
+      public static bool operator !=(FontSelector selector1, FontSelector selector2)
+      {
+        return !(selector1 == selector2);
+      }
+
+      public override bool Equals(object obj)
+      {
+        if (obj == null)  // removing this can lead to stack overflow
+          return false;
+        FontSelector selector = obj as FontSelector;
+        if (!Equals(selector, null))
+          return this.name == selector.name && this.style == selector.style;
+        return false;
+      }
+
+      public override int GetHashCode()
+      {
+        return this.name.GetHashCode() ^ this.style.GetHashCode();
+      }
+
+      /// <summary>
+      /// Returns a string for diagnostic purposes only.
+      /// </summary>
+      public override string ToString()
+      {
+        string variation = "";
+        switch (this.style)
+        {
+          case XFontStyle.Regular:
+            variation = "(Regular)";
+            break;
+
+          case XFontStyle.Bold:
+            variation = "(Bold)";
+            break;
+
+          case XFontStyle.Italic:
+            variation = "(Italic)";
+            break;
+
+          case XFontStyle.Bold | XFontStyle.Italic:
+            variation = "(BoldItalic)";
+            break;
+        }
+        return this.name + variation;
+      }
+    }
+  }
+#else
+  /// <summary>
+  /// Global table of TrueType fontdescriptor objects.
+  /// </summary>
+  class FontDescriptorStock
+  {
+    private FontDescriptorStock()
+    {
+      this.table = new Hashtable();
+    }
+
+    /// <summary>
+    /// Gets the FontDescriptor identified by the specified FontSelector. Returns null if no
+    /// such objects exists.
+    /// </summary>
+    public FontDescriptor FindDescriptor(FontSelector selector)
+    {
+      if (selector == null)
+        return null;
+
+      FontDescriptor descriptor = this.table[selector] as FontDescriptor;
+      return descriptor;
+    }
+
+    ///// <summary>
+    ///// Gets the FontDescriptor identified by the specified FontSelector. If no such objects 
+    ///// exists, a new FontDescriptor is created and added to the stock.
+    ///// </summary>
+    //public FontDescriptor CreateDescriptor(FontSelector selector)
+    //{
+    //  if (selector == null)
+    //    throw new ArgumentNullException("selector");
+
+    //  FontDescriptor descriptor = this.table[selector] as FontDescriptor;
+    //  if (descriptor == null)
+    //  {
+    //    descriptor = new TrueTypeDescriptor(selector);
+    //    this.table.Add(selector, descriptor);
+    //  }
+    //  return descriptor;
+    //}
+
+    /// <summary>
+    /// Gets the FontDescriptor identified by the specified FontSelector. If no such objects 
+    /// exists, a new FontDescriptor is created and added to the stock.
+    /// </summary>
+    public FontDescriptor CreateDescriptor(XFont font)
+    {
+      if (font == null)
+        throw new ArgumentNullException("font");
+
+      FontSelector selector = new FontSelector(font);
+      FontDescriptor descriptor = this.table[selector] as FontDescriptor;
+      if (descriptor == null)
+      {
+        lock (typeof(FontDescriptorStock))
+        {
+          // may be created by other thread meanwhile
+          descriptor = this.table[selector] as FontDescriptor;
+          if (descriptor == null)
+          {
+            descriptor = new TrueTypeDescriptor(font, font.privateFontCollection);
+            this.table.Add(selector, descriptor);
+          }
+        }
+      }
+      return descriptor;
+    }
+
+    /// <summary>
+    /// Gets the FontDescriptor identified by the specified FontSelector. If no such objects 
+    /// exists, a new FontDescriptor is created and added to the stock.
+    /// </summary>
+    public FontDescriptor CreateDescriptor(XFontFamily family, XFontStyle style)
+    {
+      if (family == null)
+        throw new ArgumentNullException("family");
+
+      FontSelector selector = new FontSelector(family, style);
+      FontDescriptor descriptor = this.table[selector] as FontDescriptor;
+      if (descriptor == null)
+      {
+        lock (typeof(FontDescriptorStock))
+        {
+          // may be created by other thread meanwhile
+          descriptor = this.table[selector] as FontDescriptor;
+          if (descriptor == null)
+          {
+            XFont font = new XFont(family.Name, 10, style);
+            descriptor = new TrueTypeDescriptor(font, font.privateFontCollection);
+            if (this.table.ContainsKey(selector))
+              GetType();
+            else
+              this.table.Add(selector, descriptor);
+          }
+        }
+      }
+      return descriptor;
+    }
+
+    public FontDescriptor CreateDescriptor(string idName, byte[] fontData)
+    {
+      FontSelector selector = new FontSelector(idName);
+      FontDescriptor descriptor = this.table[selector] as FontDescriptor;
+      if (descriptor == null)
+      {
+        lock (typeof(FontDescriptorStock))
+        {
+          // may be created by other thread meanwhile
+          descriptor = this.table[selector] as FontDescriptor;
+          if (descriptor == null)
+          {
+            descriptor = new TrueTypeDescriptor(idName, fontData);
+            this.table.Add(selector, descriptor);
+          }
+        }
+      }
+      return descriptor;
+    }
+
+    public static FontDescriptorStock Global
+    {
+      get
+      {
+        if (FontDescriptorStock.global == null)
+        {
+          lock (typeof(FontDescriptorStock))
+          {
+            if (FontDescriptorStock.global == null)
+              FontDescriptorStock.global = new FontDescriptorStock();
+          }
+        }
+        return FontDescriptorStock.global;
+      }
+    }
+    static FontDescriptorStock global;
+
+    H ashtable table;
+
+    /// <summary>
+    /// A collection of information that uniquely identifies a particular font.
+    /// Used to map XFont to PdfFont.
+    /// There is a one to one relationship between a FontSelector and a TrueType/OpenType file.
+    /// </summary>
+    internal class FontSelector
+    {
+      public FontSelector(XFont font)
+      {
+        this.name = font.Name;
+        this.style = font.Style;
+      }
+
+      public FontSelector(XFontFamily family, XFontStyle style)
+      {
+        this.name = family.Name;
+        this.style = style;
+      }
+
+      public FontSelector(string idName)
+      {
+        this.name = idName;
+        this.style = XFontStyle.Regular;
+      }
+
+      public string Name
+      {
+        get { return this.name; }
+      }
+      string name;
+
+      public XFontStyle Style
+      {
+        get { return this.style; }
+      }
+      XFontStyle style;
+
+      public static bool operator ==(FontSelector selector1, FontSelector selector2)
+      {
+        if (selector1 != null)
+          selector1.Equals(selector2);
+        return selector2 == null;
+      }
+
+      public static bool operator !=(FontSelector selector1, FontSelector selector2)
+      {
+        return !(selector1 == selector2);
+      }
+
+      public override bool Equals(object obj)
+      {
+        FontSelector selector = obj as FontSelector;
+        if (obj != null && this.name == selector.name)
+          return this.style == selector.style;
+        return false;
+      }
+
+      public override int GetHashCode()
+      {
+        return this.name.GetHashCode() ^ this.style.GetHashCode();
+      }
+
+      /// <summary>
+      /// Returns a string for diagnostic purposes only.
+      /// </summary>
+      public override string ToString()
+      {
+        string variation = "";
+        switch (this.style)
+        {
+          case XFontStyle.Regular:
+            variation = "(Regular)";
+            break;
+
+          case XFontStyle.Bold:
+            variation = "(Bold)";
+            break;
+
+          case XFontStyle.Italic:
+            variation = "(Italic)";
+            break;
+
+          case XFontStyle.Bold | XFontStyle.Italic:
+            variation = "(BoldItalic)";
+            break;
+        }
+        return this.name + variation;
+      }
+    }
+  }
+#endif
+}
\ No newline at end of file
diff --git a/lib/PdfSharp/PdfSharp.Fonts/FontWriter.cs b/lib/PdfSharp/PdfSharp.Fonts/FontWriter.cs
index 1097eda..9c9cefa 100644
--- a/lib/PdfSharp/PdfSharp.Fonts/FontWriter.cs
+++ b/lib/PdfSharp/PdfSharp.Fonts/FontWriter.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -168,6 +168,7 @@ namespace PdfSharp.Fonts
     {
       get { return this.stream; }
     }
-    Stream stream;
+    
+    readonly Stream stream;
   }
 }
diff --git a/lib/PdfSharp/PdfSharp.Forms/ColorComboBox.cs b/lib/PdfSharp/PdfSharp.Forms/ColorComboBox.cs
index 7b27a8f..fa88e8e 100644
--- a/lib/PdfSharp/PdfSharp.Forms/ColorComboBox.cs
+++ b/lib/PdfSharp/PdfSharp.Forms/ColorComboBox.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Forms/DeviceInfos.cs b/lib/PdfSharp/PdfSharp.Forms/DeviceInfos.cs
index a1a18ee..e358b81 100644
--- a/lib/PdfSharp/PdfSharp.Forms/DeviceInfos.cs
+++ b/lib/PdfSharp/PdfSharp.Forms/DeviceInfos.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Forms/PagePreview.cs b/lib/PdfSharp/PdfSharp.Forms/PagePreview.cs
index f887c03..8d3eca2 100644
--- a/lib/PdfSharp/PdfSharp.Forms/PagePreview.cs
+++ b/lib/PdfSharp/PdfSharp.Forms/PagePreview.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -67,14 +67,14 @@ namespace PdfSharp.Forms
   /// Represents a preview control for an XGraphics page. Can be used as an alternative to
   /// System.Windows.Forms.PrintPreviewControl.
   /// </summary>
-  public class PagePreview : System.Windows.Forms.UserControl
+  public class PagePreview : UserControl
   {
     /// <summary>
     /// A delegate for invoking the render function.
     /// </summary>
     public delegate void RenderEvent(XGraphics gfx);
 
-    private System.ComponentModel.Container components = null;
+    private Container components = null;
 
     /// <summary>
     /// Initializes a new instance of the <see cref="PagePreview"/> class.
@@ -86,14 +86,14 @@ namespace PdfSharp.Forms
 
       this.hScrollBar = new HScrollBar();
       this.hScrollBar.Visible = this.showScrollbars;
-      this.hScrollBar.Scroll += new ScrollEventHandler(OnScroll);
-      this.hScrollBar.ValueChanged += new EventHandler(OnValueChanged);
+      this.hScrollBar.Scroll += OnScroll;
+      this.hScrollBar.ValueChanged += OnValueChanged;
       Controls.Add(this.hScrollBar);
 
       this.vScrollBar = new VScrollBar();
       this.vScrollBar.Visible = this.showScrollbars;
-      this.vScrollBar.Scroll += new ScrollEventHandler(OnScroll);
-      this.vScrollBar.ValueChanged += new EventHandler(OnValueChanged);
+      this.vScrollBar.Scroll += OnScroll;
+      this.vScrollBar.ValueChanged += OnValueChanged;
       Controls.Add(this.vScrollBar);
 
       InitializeComponent();
@@ -113,9 +113,10 @@ namespace PdfSharp.Forms
       this.posOffset = new Point();
       this.virtualPage = new Rectangle();
     }
-    PagePreviewCanvas canvas;
-    HScrollBar hScrollBar;
-    VScrollBar vScrollBar;
+
+    readonly PagePreviewCanvas canvas;
+    readonly HScrollBar hScrollBar;
+    readonly VScrollBar vScrollBar;
 
 
     /// <summary> 
@@ -320,6 +321,21 @@ namespace PdfSharp.Forms
     }
 
     /// <summary>
+    /// This is a hack for Visual Studio 2008. The designer uses reflection for setting the PageSize property.
+    /// This fails, even an implicit operator that converts Size to XSize exits.
+    /// </summary>
+    public Size PageSizeF
+    {
+      get { return new Size(Convert.ToInt32(this.pageSize.Width), Convert.ToInt32(this.pageSize.Height)); }
+      set
+      {
+        this.pageSize = value;
+        CalculatePreviewDimension();
+        Invalidate();
+      }
+    }
+
+    /// <summary>
     /// Sets a delagate that is invoked when the preview wants to be painted.
     /// </summary>
     public void SetRenderEvent(RenderEvent renderEvent)
@@ -362,7 +378,7 @@ namespace PdfSharp.Forms
     {
       // Accurate drawing prevents flickering
       Graphics gfx = e.Graphics;
-      Rectangle clientRect = this.ClientRectangle;
+      Rectangle clientRect = ClientRectangle;
       int d = 0;
       switch (this.borderStyle)
       {
@@ -381,7 +397,7 @@ namespace PdfSharp.Forms
         int cxScrollbar = SystemInformation.VerticalScrollBarWidth;
         int cyScrollbar = SystemInformation.HorizontalScrollBarHeight;
 
-        gfx.FillRectangle(new SolidBrush(this.BackColor),
+        gfx.FillRectangle(new SolidBrush(BackColor),
           clientRect.Width - cxScrollbar - d, clientRect.Height - cyScrollbar - d, cxScrollbar, cyScrollbar);
       }
     }
@@ -486,20 +502,20 @@ namespace PdfSharp.Forms
       gfx.Dispose();
       int xdpiScreen = devInfo.LogicalDpiX;
       int ydpiScreen = devInfo.LogicalDpiY;
-      int cxScrollbar = SystemInformation.VerticalScrollBarWidth;
-      int cyScrollbar = SystemInformation.HorizontalScrollBarHeight;
+      //int cxScrollbar = SystemInformation.VerticalScrollBarWidth;
+      //int cyScrollbar = SystemInformation.HorizontalScrollBarHeight;
       Rectangle rcCanvas = this.canvas.ClientRectangle;
 
       Zoom zoomOld = this.zoom;
       int zoomPercentOld = this.zoomPercent;
 
       // Border around virtual page in pixel.
-      int leftBorder = 2;
-      int rightBorder = 4;  // because of shadow
-      int topBorder = 2;
-      int bottomBorder = 4;  // because of shadow
-      int horzBorders = leftBorder + rightBorder;
-      int vertBorders = topBorder + bottomBorder;
+      const int leftBorder = 2;
+      const int rightBorder = 4;  // because of shadow
+      const int topBorder = 2;
+      const int bottomBorder = 4;  // because of shadow
+      const int horzBorders = leftBorder + rightBorder;
+      const int vertBorders = topBorder + bottomBorder;
 
       // Calculate new zoom factor.
       switch (this.zoom)
@@ -894,7 +910,7 @@ namespace PdfSharp.Forms
         }
       }
 
-      if (this.ShowScrollbars && this.vScrollBar != null)
+      if (ShowScrollbars && this.vScrollBar != null)
       {
         if (this.posOffset.Y > dy)
           this.vScrollBar.Value = this.posOffset.Y = dy;
@@ -1029,6 +1045,6 @@ namespace PdfSharp.Forms
     /// <summary>
     /// Printable area in point.
     /// </summary>
-    RectangleF printableArea;
+    readonly RectangleF printableArea;
   }
 }
\ No newline at end of file
diff --git a/lib/PdfSharp/PdfSharp.Forms/PagePreviewCanvas.cs b/lib/PdfSharp/PdfSharp.Forms/PagePreviewCanvas.cs
index eeacfe1..d737fc8 100644
--- a/lib/PdfSharp/PdfSharp.Forms/PagePreviewCanvas.cs
+++ b/lib/PdfSharp/PdfSharp.Forms/PagePreviewCanvas.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Forms/enums/RenderMode.cs b/lib/PdfSharp/PdfSharp.Forms/enums/RenderMode.cs
index cd32bb9..5c6069b 100644
--- a/lib/PdfSharp/PdfSharp.Forms/enums/RenderMode.cs
+++ b/lib/PdfSharp/PdfSharp.Forms/enums/RenderMode.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Forms/enums/Zoom.cs b/lib/PdfSharp/PdfSharp.Forms/enums/Zoom.cs
index c56aba1..e40f421 100644
--- a/lib/PdfSharp/PdfSharp.Forms/enums/Zoom.cs
+++ b/lib/PdfSharp/PdfSharp.Forms/enums/Zoom.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -95,23 +95,23 @@ namespace PdfSharp.Forms
     Percent10 = 10,
 
     /// <summary>
-    /// Sets the percent value such that the document fits horizontally into the window.
+    /// Sets the zoom factor so that the document fits horizontally into the window.
     /// </summary>
     BestFit = -1,
 
     /// <summary>
-    /// Sets the percent value such that the printable area of the document fits horizontally into the window.
+    /// Sets the zoom factor so that the printable area of the document fits horizontally into the window.
     /// Currently not yet implemented and the same as ZoomBestFit.
     /// </summary>
     TextFit = -2,
 
     /// <summary>
-    /// Sets the percent value such that the whole document fits completely into the window.
+    /// Sets the zoom factor so that the whole document fits completely into the window.
     /// </summary>
     FullPage = -3,
 
     /// <summary>
-    /// Sets the percent value such that the document is displayed in its real physical size.
+    /// Sets the zoom factor so that the document is displayed in its real physical size (based on the DPI information returned from the OS for the current monitor).
     /// </summary>
     OriginalSize = -4,
   }
diff --git a/lib/PdfSharp/PdfSharp.Internal/Calc.cs b/lib/PdfSharp/PdfSharp.Internal/Calc.cs
index ffffdd3..8037dc4 100644
--- a/lib/PdfSharp/PdfSharp.Internal/Calc.cs
+++ b/lib/PdfSharp/PdfSharp.Internal/Calc.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Internal/ColorHelper.cs b/lib/PdfSharp/PdfSharp.Internal/ColorHelper.cs
index c9a3dd8..79091fd 100644
--- a/lib/PdfSharp/PdfSharp.Internal/ColorHelper.cs
+++ b/lib/PdfSharp/PdfSharp.Internal/ColorHelper.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Internal/DoubleUtil.cs b/lib/PdfSharp/PdfSharp.Internal/DoubleUtil.cs
index 12b2184..8b9e136 100644
--- a/lib/PdfSharp/PdfSharp.Internal/DoubleUtil.cs
+++ b/lib/PdfSharp/PdfSharp.Internal/DoubleUtil.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Internal/NativeMethods.cs b/lib/PdfSharp/PdfSharp.Internal/NativeMethods.cs
index 9df6eed..d1f93a5 100644
--- a/lib/PdfSharp/PdfSharp.Internal/NativeMethods.cs
+++ b/lib/PdfSharp/PdfSharp.Internal/NativeMethods.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -42,7 +42,7 @@ namespace PdfSharp.Internal
     /// <summary>
     /// Reflected from System.Drawing.SafeNativeMethods+LOGFONT
     /// </summary>
-    [SuppressUnmanagedCodeSecurity]
+    //[SuppressUnmanagedCodeSecurity]
     [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
     public class LOGFONT
     {
diff --git a/lib/PdfSharp/PdfSharp.Internal/TokenizerHelper.cs b/lib/PdfSharp/PdfSharp.Internal/TokenizerHelper.cs
index 97c1641..38e7bcc 100644
--- a/lib/PdfSharp/PdfSharp.Internal/TokenizerHelper.cs
+++ b/lib/PdfSharp/PdfSharp.Internal/TokenizerHelper.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -33,14 +33,11 @@ using System.Collections.Generic;
 using System.Text;
 using System.Globalization;
 
-#pragma warning disable 1591
-
-
 namespace PdfSharp.Internal
 {
   // Relected from WPF to ensure compatibility
   // Use netmassdownloader -d "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.0" -output g:\cachetest -v
-  public class TokenizerHelper
+  class TokenizerHelper
   {
     internal char PeekNextCharacter()
     {
@@ -50,7 +47,7 @@ namespace PdfSharp.Internal
       return ch;
     }
 
-    static IFormatProvider NeutralCulture = CultureInfo.GetCultureInfo("en-us");
+    private static readonly IFormatProvider NeutralCulture = CultureInfo.InvariantCulture; //.GetCultureInfo("en-us");
 
     public TokenizerHelper(string str)
       : this(str, NeutralCulture)
@@ -64,7 +61,7 @@ namespace PdfSharp.Internal
 
     public TokenizerHelper(string str, char quoteChar, char separator)
     {
-      this.Initialize(str, quoteChar, separator);
+      Initialize(str, quoteChar, separator);
     }
 
     internal string GetCurrentToken()
@@ -83,7 +80,7 @@ namespace PdfSharp.Internal
       return ch;
     }
 
-    private void Initialize(string str, char quoteChar, char separator)
+    void Initialize(string str, char quoteChar, char separator)
     {
       this.str = str;
       this.strLen = (str == null) ? 0 : str.Length;
@@ -106,12 +103,12 @@ namespace PdfSharp.Internal
 
     internal bool NextToken()
     {
-      return this.NextToken(false);
+      return NextToken(false);
     }
 
     internal bool NextToken(bool allowQuotedToken)
     {
-      return this.NextToken(allowQuotedToken, this.argSeparator);
+      return NextToken(allowQuotedToken, this.argSeparator);
     }
 
     internal bool NextToken(bool allowQuotedToken, char separator)
@@ -157,7 +154,7 @@ namespace PdfSharp.Internal
       }
       if (charCount > 0)
         throw new InvalidOperationException("Missing end quote"); //SR.Get(SRID.TokenizerHelperMissingEndQuote, new object[0]));
-      this.ScanToNextToken(separator);
+      ScanToNextToken(separator);
       this.currentTokenIndex = index;
       this.currentTokenLength = num3;
       if (this.currentTokenLength < 1)
diff --git a/lib/PdfSharp/PdfSharp.Pdf.AcroForms/PdfAcroField.cs b/lib/PdfSharp/PdfSharp.Pdf.AcroForms/PdfAcroField.cs
index 5dad46a..5514d3b 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.AcroForms/PdfAcroField.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.AcroForms/PdfAcroField.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -28,6 +28,7 @@
 #endregion
 
 using System;
+using System.Collections.Generic;
 using System.Diagnostics;
 using System.Collections;
 using PdfSharp.Pdf.Advanced;
@@ -150,23 +151,26 @@ namespace PdfSharp.Pdf.AcroForms
     }
 
     /// <summary>
-    /// Gets all descendant's names of this field.
+    /// Gets the names of all descendants of this field.
     /// </summary>
     public string[] DescendantNames
     {
       get
       {
-        ArrayList names = new ArrayList();
+        List<PdfName> names = new List<PdfName>();
         if (HasKids)
         {
           PdfAcroFieldCollection fields = Fields;
           fields.GetDescendantNames(ref names, null);
         }
-        return (string[])names.ToArray(typeof(string));
+        List<string> temp = new List<string>();
+        foreach (PdfName name in names)
+          temp.Add(name.ToString());
+        return temp.ToArray();
       }
     }
 
-    internal virtual void GetDescendantNames(ref ArrayList names, string partialName)
+    internal virtual void GetDescendantNames(ref List<PdfName> names, string partialName)
     {
       if (HasKids)
       {
@@ -188,10 +192,10 @@ namespace PdfSharp.Pdf.AcroForms
         Debug.Assert(t != "");
         if (t.Length > 0)
         {
-          if (partialName != null && partialName.Length > 0)
-            names.Add(partialName + "." + t);
+          if (!String.IsNullOrEmpty(partialName))
+            names.Add(new PdfName(partialName + "." + t));
           else
-            names.Add(t);
+            names.Add(new PdfName(t));
         }
       }
     }
@@ -245,13 +249,16 @@ namespace PdfSharp.Pdf.AcroForms
       {
         get
         {
-          ArrayList names = new ArrayList();
+          List<PdfName> names = new List<PdfName>();
           GetDescendantNames(ref names, null);
-          return (string[])names.ToArray(typeof(string));
+          List<string> temp = new List<string>();
+          foreach (PdfName name in names)
+            temp.Add(name.ToString());
+          return temp.ToArray();
         }
       }
 
-      internal void GetDescendantNames(ref ArrayList names, string partialName)
+      internal void GetDescendantNames(ref List<PdfName> names, string partialName)
       {
         int count = Elements.Count;
         for (int idx = 0; idx < count; idx++)
@@ -265,7 +272,7 @@ namespace PdfSharp.Pdf.AcroForms
 
       /// <summary>
       /// Gets a field from the collection. For your convenience an instance of a derived class like
-      /// PdfTextFiled or PdfCheckBoxis returned if PDFsharp can guess the actual type of the dictionary.
+      /// PdfTextField or PdfCheckBox is returned if PDFsharp can guess the actual type of the dictionary.
       /// If the actual type cannot be guessed by PDFsharp the function returns an instance
       /// of PdfGenericField.
       /// </summary>
@@ -316,7 +323,7 @@ namespace PdfSharp.Pdf.AcroForms
       }
 
       /// <summary>
-      /// Create a derived type like PdfTextFiled or PdfCheckBox if possible.
+      /// Create a derived type like PdfTextField or PdfCheckBox if possible.
       /// If the actual cannot be guessed by PDFsharp the function returns an instance
       /// of PdfGenericField.
       /// </summary>
diff --git a/lib/PdfSharp/PdfSharp.Pdf.AcroForms/PdfAcroForm.cs b/lib/PdfSharp/PdfSharp.Pdf.AcroForms/PdfAcroForm.cs
index babd1a0..ad8ffa0 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.AcroForms/PdfAcroForm.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.AcroForms/PdfAcroForm.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -48,7 +48,7 @@ namespace PdfSharp.Pdf.AcroForms
       this.document = document;
     }
 
-    PdfAcroForm(PdfDictionary dictionary) : base(dictionary)
+    internal PdfAcroForm(PdfDictionary dictionary) : base(dictionary)
     {
     }
 
diff --git a/lib/PdfSharp/PdfSharp.Pdf.AcroForms/PdfButtonField.cs b/lib/PdfSharp/PdfSharp.Pdf.AcroForms/PdfButtonField.cs
index 4dab41e..fcf0a48 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.AcroForms/PdfButtonField.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.AcroForms/PdfButtonField.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -28,6 +28,7 @@
 #endregion
 
 using System;
+using System.Collections.Generic;
 using System.Diagnostics;
 using System.Collections;
 using PdfSharp.Pdf.Annotations;
@@ -76,19 +77,19 @@ namespace PdfSharp.Pdf.AcroForms
       return null;
     }
 
-    internal override void GetDescendantNames(ref ArrayList names, string partialName)
+    internal override void GetDescendantNames(ref List<PdfName> names, string partialName)
     {
-      string t = Elements.GetString(Keys.T);
+      string t = Elements.GetString(PdfAcroField.Keys.T);
       // HACK: ??? 
       if (t == "")
         t = "???";
       Debug.Assert(t != "");
       if (t.Length > 0)
       {
-        if (partialName != null && partialName.Length > 0)
-          names.Add(partialName + "." + t);
+        if (!String.IsNullOrEmpty(partialName))
+          names.Add(new PdfName(partialName + "." + t));
         else
-          names.Add(t);
+          names.Add(new PdfName(t));
       }
     }
 
diff --git a/lib/PdfSharp/PdfSharp.Pdf.AcroForms/PdfCheckBoxField.cs b/lib/PdfSharp/PdfSharp.Pdf.AcroForms/PdfCheckBoxField.cs
index e4c85e7..9cbd90e 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.AcroForms/PdfCheckBoxField.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.AcroForms/PdfCheckBoxField.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Pdf.AcroForms/PdfChoiceField.cs b/lib/PdfSharp/PdfSharp.Pdf.AcroForms/PdfChoiceField.cs
new file mode 100644
index 0000000..8788994
--- /dev/null
+++ b/lib/PdfSharp/PdfSharp.Pdf.AcroForms/PdfChoiceField.cs
@@ -0,0 +1,170 @@
+#region PDFsharp - A .NET library for processing PDF
+//
+// Authors:
+//   Stefan Lange (mailto:Stefan Lange pdfsharp com)
+//
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
+//
+// http://www.pdfsharp.com
+// http://sourceforge.net/projects/pdfsharp
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+// DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Diagnostics;
+using System.Collections;
+using PdfSharp.Pdf.Internal;
+
+namespace PdfSharp.Pdf.AcroForms
+{
+  /// <summary>
+  /// Represents the base class for all choice field dictionaries.
+  /// </summary>
+  public abstract class PdfChoiceField : PdfAcroField
+  {
+    /// <summary>
+    /// Initializes a new instance of the <see cref="PdfChoiceField"/> class.
+    /// </summary>
+    protected PdfChoiceField(PdfDocument document)
+      : base(document)
+    {
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="PdfChoiceField"/> class.
+    /// </summary>
+    protected PdfChoiceField(PdfDictionary dict)
+      : base(dict)
+    {
+    }
+
+    /// <summary>
+    /// Gets the index of the specified string in the /Opt array or -1, if no such string exists.
+    /// </summary>
+    protected int IndexInOptArray(string value)
+    {
+      PdfArray opt = Elements[Keys.Opt] as PdfArray;
+      if (opt != null)
+      {
+        int count = opt.Elements.Count;
+        for (int idx = 0; idx < count; idx++)
+        {
+          PdfItem item = opt.Elements[idx];
+          if (item is PdfString)
+          {
+            if (item.ToString() == value)
+              return idx;
+          }
+          else if (item is PdfArray)
+          {
+            PdfArray array = (PdfArray)item;
+            if (array.Elements.Count != 0)
+            {
+              if (array.Elements[idx].ToString() == value)
+                return idx;
+            }
+          }
+        }
+      }
+      return -1;
+    }
+
+    /// <summary>
+    /// Gets the value from the index in the /Opt array.
+    /// </summary>
+    protected string ValueInOptArray(int index)
+    {
+      PdfArray opt = Elements[Keys.Opt] as PdfArray;
+      if (opt != null)
+      {
+        int count = opt.Elements.Count;
+        if (index < 0 || index >= count)
+          throw new ArgumentOutOfRangeException("index");
+
+        PdfItem item = opt.Elements[index];
+        if (item is PdfString)
+          return item.ToString();
+        else if (item is PdfArray)
+        {
+          PdfArray array = (PdfArray)item;
+          return array.Elements[0].ToString();
+        }
+      }
+      return "";
+    }
+
+    /// <summary>
+    /// Predefined keys of this dictionary. 
+    /// The description comes from PDF 1.4 Reference.
+    /// </summary>
+    public new class Keys : PdfAcroField.Keys
+    {
+      /// <summary>
+      /// (Required; inheritable) An array of options to be presented to the user. Each element of
+      /// the array is either a text string representing one of the available options or a two-element
+      /// array consisting of a text string together with a default appearance string for constructing
+      /// the item?s appearance dynamically at viewing time.
+      /// </summary>
+      [KeyInfo(KeyType.Array | KeyType.Optional)]
+      public const string Opt = "/Opt";
+
+      /// <summary>
+      /// (Optional; inheritable) For scrollable list boxes, the top index (the index in the Opt array
+      /// of the first option visible in the list).
+      /// </summary>
+      [KeyInfo(KeyType.Integer | KeyType.Optional)]
+      public const string TI = "/TI";
+
+      /// <summary>
+      /// (Sometimes required, otherwise optional; inheritable; PDF 1.4) For choice fields that allow
+      /// multiple selection (MultiSelect flag set), an array of integers, sorted in ascending order,
+      /// representing the zero-based indices in the Opt array of the currently selected option
+      /// items. This entry is required when two or more elements in the Opt array have different
+      /// names but the same export value, or when the value of the choice field is an array; in
+      /// other cases, it is permitted but not required. If the items identified by this entry differ
+      /// from those in the V entry of the field dictionary (see below), the V entry takes precedence.
+      /// </summary>
+      [KeyInfo(KeyType.Array | KeyType.Optional)]
+      public const string I = "/I";
+
+      /// <summary>
+      /// Gets the KeysMeta for these keys.
+      /// </summary>
+      internal static DictionaryMeta Meta
+      {
+        get
+        {
+          if (Keys.meta == null)
+            Keys.meta = CreateMeta(typeof(Keys));
+          return Keys.meta;
+        }
+      }
+      static DictionaryMeta meta;
+    }
+
+    /// <summary>
+    /// Gets the KeysMeta of this dictionary type.
+    /// </summary>
+    internal override DictionaryMeta Meta
+    {
+      get { return Keys.Meta; }
+    }
+  }
+}
diff --git a/lib/PdfSharp/PdfSharp.Pdf.AcroForms/PdfComboBoxField.cs b/lib/PdfSharp/PdfSharp.Pdf.AcroForms/PdfComboBoxField.cs
index ef40bd9..471aa57 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.AcroForms/PdfComboBoxField.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.AcroForms/PdfComboBoxField.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -37,7 +37,7 @@ namespace PdfSharp.Pdf.AcroForms
   /// <summary>
   /// Represents the combo box field.
   /// </summary>
-  public sealed class PdfComboBoxField : PdfChoiseField
+  public sealed class PdfComboBoxField : PdfChoiceField
   {
     /// <summary>
     /// Initializes a new instance of PdfComboBoxField.
diff --git a/lib/PdfSharp/PdfSharp.Pdf.AcroForms/PdfGenericField.cs b/lib/PdfSharp/PdfSharp.Pdf.AcroForms/PdfGenericField.cs
index d14aed9..f0da29a 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.AcroForms/PdfGenericField.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.AcroForms/PdfGenericField.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Pdf.AcroForms/PdfListBoxField.cs b/lib/PdfSharp/PdfSharp.Pdf.AcroForms/PdfListBoxField.cs
index 7cc66ab..c8437f1 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.AcroForms/PdfListBoxField.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.AcroForms/PdfListBoxField.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -37,7 +37,7 @@ namespace PdfSharp.Pdf.AcroForms
   /// <summary>
   /// Represents the list box field.
   /// </summary>
-  public sealed class PdfListBoxField : PdfChoiseField
+  public sealed class PdfListBoxField : PdfChoiceField
   {
     /// <summary>
     /// Initializes a new instance of PdfListBoxField.
diff --git a/lib/PdfSharp/PdfSharp.Pdf.AcroForms/PdfPushButtonField.cs b/lib/PdfSharp/PdfSharp.Pdf.AcroForms/PdfPushButtonField.cs
index 30f5608..292fb3f 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.AcroForms/PdfPushButtonField.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.AcroForms/PdfPushButtonField.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Pdf.AcroForms/PdfRadioButtonField.cs b/lib/PdfSharp/PdfSharp.Pdf.AcroForms/PdfRadioButtonField.cs
index 1ebcb0c..9bea35e 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.AcroForms/PdfRadioButtonField.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.AcroForms/PdfRadioButtonField.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -35,7 +35,7 @@ using PdfSharp.Pdf.Internal;
 namespace PdfSharp.Pdf.AcroForms
 {
   /// <summary>
-  /// Represents the radion button field.
+  /// Represents the radio button field.
   /// </summary>
   public sealed class PdfRadioButtonField : PdfButtonField
   {
diff --git a/lib/PdfSharp/PdfSharp.Pdf.AcroForms/PdfSignatureField.cs b/lib/PdfSharp/PdfSharp.Pdf.AcroForms/PdfSignatureField.cs
index 6dc2fa8..2d8b124 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.AcroForms/PdfSignatureField.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.AcroForms/PdfSignatureField.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -51,7 +51,7 @@ namespace PdfSharp.Pdf.AcroForms
     }
 
     /// <summary>
-    /// Predefined keys of this dictionary. 
+    /// Predefined keys of this dictionary.
     /// The description comes from PDF 1.4 Reference.
     /// </summary>
     public new class Keys : PdfAcroField.Keys
@@ -79,7 +79,7 @@ namespace PdfSharp.Pdf.AcroForms
 
       /// <summary>
       /// (Required) An array of pairs of integers (starting byte offset, length in bytes)
-      /// describing the exact byte range for the digest calculation. Multiple discontiguous
+      /// describing the exact byte range for the digest calculation. Multiple discontinuous
       /// byte ranges may be used to describe a digest that does not include the
       /// signature token itself.
       /// </summary>
diff --git a/lib/PdfSharp/PdfSharp.Pdf.AcroForms/PdfTextField.cs b/lib/PdfSharp/PdfSharp.Pdf.AcroForms/PdfTextField.cs
index 7a9cd4c..20d675a 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.AcroForms/PdfTextField.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.AcroForms/PdfTextField.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -61,7 +61,7 @@ namespace PdfSharp.Pdf.AcroForms
     public string Text
     {
       get { return Elements.GetString(Keys.V); }
-      set { Elements.SetString(Keys.V, value); RenderAppearance(); } //HACK
+      set { Elements.SetString(Keys.V, value); RenderAppearance(); } //HACK in PdfTextField
     }
 
     /// <summary>
diff --git a/lib/PdfSharp/PdfSharp.Pdf.AcroForms/enums/PdfAcroFieldFlags.cs b/lib/PdfSharp/PdfSharp.Pdf.AcroForms/enums/PdfAcroFieldFlags.cs
index 844b1b9..0d3ebc4 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.AcroForms/enums/PdfAcroFieldFlags.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.AcroForms/enums/PdfAcroFieldFlags.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -30,7 +30,7 @@
 namespace PdfSharp.Pdf.AcroForms
 {
   /// <summary>
-  /// Specified the flags of AcroForm fields.
+  /// Specifies the flags of AcroForm fields.
   /// </summary>
   public enum PdfAcroFieldFlags
   {
@@ -111,7 +111,7 @@ namespace PdfSharp.Pdf.AcroForms
     /// </summary>
     DoNotScroll = 1 << (24 - 1),
 
-    // ----- Specific to choise fields ------------------------------------------------------------
+    // ----- Specific to choice fields ------------------------------------------------------------
 
     /// <summary>
     /// If set, the field is a combo box; if clear, the field is a list box.
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Actions/PdfAction.cs b/lib/PdfSharp/PdfSharp.Pdf.Actions/PdfAction.cs
index 296603a..b089a4f 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Actions/PdfAction.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Actions/PdfAction.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -44,7 +44,7 @@ namespace PdfSharp.Pdf.Actions
     /// <summary>
     /// Initializes a new instance of the <see cref="PdfAction"/> class.
     /// </summary>
-    public PdfAction()
+    protected PdfAction()
     {
       Elements.SetName(Keys.Type, "/Action");
     }
@@ -53,7 +53,7 @@ namespace PdfSharp.Pdf.Actions
     /// Initializes a new instance of the <see cref="PdfAction"/> class.
     /// </summary>
     /// <param name="document">The document that owns this object.</param>
-    public PdfAction(PdfDocument document) : base(document)
+    protected PdfAction(PdfDocument document) : base(document)
     {
       Elements.SetName(Keys.Type, "/Action");
     }
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Actions/enums/PdfNamedActionNames.cs b/lib/PdfSharp/PdfSharp.Pdf.Actions/enums/PdfNamedActionNames.cs
index 19aac4f..27f5e92 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Actions/enums/PdfNamedActionNames.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Actions/enums/PdfNamedActionNames.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Advanced/IContentStream.cs b/lib/PdfSharp/PdfSharp.Pdf.Advanced/IContentStream.cs
index c29a59b..1d8af25 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Advanced/IContentStream.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Advanced/IContentStream.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfCIDFont.cs b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfCIDFont.cs
index e152f40..c70c784 100644
Binary files a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfCIDFont.cs and b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfCIDFont.cs differ
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfCatalog.cs b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfCatalog.cs
index c02dbd4..b995798 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfCatalog.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfCatalog.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -50,7 +50,7 @@ namespace PdfSharp.Pdf.Advanced
     {
       Elements.SetName(Keys.Type, "/Catalog");
 
-      this.version = "1.4";  // HACK
+      this.version = "1.4";  // HACK in PdfCatalog
     }
 
     PdfCatalog(PdfDictionary dictionary)
@@ -153,7 +153,7 @@ namespace PdfSharp.Pdf.Advanced
     PdfOutline outline;
 
     /// <summary>
-    /// Gets the AcroFrom dictionary of this document.
+    /// Gets the AcroForm dictionary of this document.
     /// </summary>
     public PdfAcroForm AcroForm
     {
@@ -357,7 +357,7 @@ namespace PdfSharp.Pdf.Advanced
 
       /// <summary>
       /// (Optional; PDF 1.4) A language identifier specifying the natural language for all 
-      /// text in the document except where overridden by language specificationsfor structure 
+      /// text in the document except where overridden by language specifications for structure 
       /// elements or marked content. If this entry is absent, the language is considered unknown.
       /// </summary>
       [KeyInfo("1.4", KeyType.String | KeyType.Optional)]
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfContent.cs b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfContent.cs
index 8edf532..ea5d2e6 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfContent.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfContent.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -69,7 +69,7 @@ namespace PdfSharp.Pdf.Advanced
     /// Initializes a new instance of the <see cref="PdfContent"/> class.
     /// </summary>
     /// <param name="dict">The dict.</param>
-    public PdfContent(PdfDictionary dict) // HACK
+    public PdfContent(PdfDictionary dict) // HACK PdfContent
       : base(dict)
     {
       // A PdfContent dictionary is always unfiltered.
@@ -123,7 +123,7 @@ namespace PdfSharp.Pdf.Advanced
     /// </summary>
     internal void PreserveGraphicsState()
     {
-      // If a conent stream is touched by PDFsharp it is typically because graphical operations are
+      // If a content stream is touched by PDFsharp it is typically because graphical operations are
       // prepended or appended. Some nasty PDF tools does not preserve the graphical state correctly.
       // Therefore we try to relieve the problem by surrounding the content stream with push/restore 
       // graphic state operation.
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfContents.cs b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfContents.cs
index 453e488..1b16eee 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfContents.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfContents.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfDictionaryWithContentStream.cs b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfDictionaryWithContentStream.cs
index 0e906ba..deeb27f 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfDictionaryWithContentStream.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfDictionaryWithContentStream.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -40,7 +40,7 @@ using System.Drawing.Imaging;
 using System.Windows.Media;
 #endif
 using PdfSharp.Drawing;
-using PdfSharp.Fonts.TrueType;
+using PdfSharp.Fonts.OpenType;
 using PdfSharp.Internal;
 using PdfSharp.Pdf.Internal;
 
@@ -48,7 +48,7 @@ namespace PdfSharp.Pdf.Advanced
 {
   /// <summary>
   /// Represents a base class for dictionaries with a content stream.
-  /// Implement IContentStream for use with a conent writer.
+  /// Implement IContentStream for use with a content writer.
   /// </summary>
   public abstract class PdfDictionaryWithContentStream : PdfDictionary, IContentStream
   {
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfExtGState.cs b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfExtGState.cs
index 72570a3..999b5f9 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfExtGState.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfExtGState.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -40,7 +40,7 @@ using System.Drawing.Imaging;
 using System.Windows.Media;
 #endif
 using PdfSharp.Drawing;
-using PdfSharp.Fonts.TrueType;
+using PdfSharp.Fonts.OpenType;
 using PdfSharp.Internal;
 
 namespace PdfSharp.Pdf.Advanced
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfExtGStateTable.cs b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfExtGStateTable.cs
index 57cbf18..6b80687 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfExtGStateTable.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfExtGStateTable.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -29,7 +29,7 @@
 
 using System;
 using System.Diagnostics;
-using System.Collections;
+using System.Collections.Generic;
 using System.Globalization;
 using System.Text;
 using System.IO;
@@ -48,8 +48,7 @@ namespace PdfSharp.Pdf.Advanced
     /// </summary>
     public PdfExtGStateTable(PdfDocument document)
       : base(document)
-    {
-    }
+    { }
 
     /// <summary>
     /// Gets a PdfExtGState with the keys 'CA' and 'ca' set to the specified alpha value.
@@ -57,8 +56,8 @@ namespace PdfSharp.Pdf.Advanced
     public PdfExtGState GetExtGState(double alpha)
     {
       string key = MakeKey(alpha);
-      PdfExtGState extGState = this.alphaValues[key] as PdfExtGState;
-      if (extGState == null)
+      PdfExtGState extGState;
+      if (!this.alphaValues.TryGetValue(key, out extGState))
       {
         extGState = new PdfExtGState(this.owner);
         extGState.Elements[PdfExtGState.Keys.CA] = new PdfReal(alpha);
@@ -75,8 +74,8 @@ namespace PdfSharp.Pdf.Advanced
     public PdfExtGState GetExtGStateStroke(double alpha)
     {
       string key = MakeKey(alpha);
-      PdfExtGState extGState = this.strokeAlphaValues[key] as PdfExtGState;
-      if (extGState == null)
+      PdfExtGState extGState;
+      if (!this.strokeAlphaValues.TryGetValue(key, out extGState))
       {
         extGState = new PdfExtGState(this.owner);
         extGState.Elements[PdfExtGState.Keys.CA] = new PdfReal(alpha);
@@ -92,8 +91,8 @@ namespace PdfSharp.Pdf.Advanced
     public PdfExtGState GetExtGStateNonStroke(double alpha)
     {
       string key = MakeKey(alpha);
-      PdfExtGState extGState = this.nonStrokeAlphaValues[key] as PdfExtGState;
-      if (extGState == null)
+      PdfExtGState extGState; ;
+      if (!this.nonStrokeAlphaValues.TryGetValue(key, out extGState))
       {
         extGState = new PdfExtGState(this.owner);
         extGState.Elements[PdfExtGState.Keys.ca] = new PdfReal(alpha);
@@ -131,7 +130,7 @@ namespace PdfSharp.Pdf.Advanced
     //  //return extGState;
     //}
 
-    string MakeKey(double alpha)
+    static string MakeKey(double alpha)
     {
       return ((int)(1000 * alpha)).ToString();
     }
@@ -139,8 +138,8 @@ namespace PdfSharp.Pdf.Advanced
     /// <summary>
     /// Maps from alpha values (range "0" to "1000") to PdfExtGState objects.
     /// </summary>
-    Hashtable alphaValues = new Hashtable();
-    Hashtable strokeAlphaValues = new Hashtable();
-    Hashtable nonStrokeAlphaValues = new Hashtable();
+    Dictionary<string, PdfExtGState> alphaValues = new Dictionary<string, PdfExtGState>();
+    Dictionary<string, PdfExtGState> strokeAlphaValues = new Dictionary<string, PdfExtGState>();
+    Dictionary<string, PdfExtGState> nonStrokeAlphaValues = new Dictionary<string, PdfExtGState>();
   }
 }
\ No newline at end of file
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfFont.cs b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfFont.cs
index 69b7116..d0d63ee 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfFont.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfFont.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -34,7 +34,7 @@ using System.Text;
 using System.IO;
 using PdfSharp.Pdf.Advanced;
 using PdfSharp.Drawing;
-using PdfSharp.Fonts.TrueType;
+using PdfSharp.Fonts.OpenType;
 using PdfSharp.Fonts;
 using PdfSharp.Internal;
 using PdfSharp.Pdf.Filters;
@@ -121,6 +121,12 @@ namespace PdfSharp.Pdf.Advanced
         this.cmapInfo.AddChars(text);
     }
 
+    internal void AddGlyphIndices(string glyphIndices)
+    {
+      if (this.cmapInfo != null)
+        this.cmapInfo.AddGlyphIndices(glyphIndices);
+    }
+
     /// <summary>
     /// Gets or sets the CMapInfo.
     /// </summary>
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfFontDescriptor.cs b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfFontDescriptor.cs
index 4e68d28..367d800 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfFontDescriptor.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfFontDescriptor.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -33,7 +33,7 @@ using System.Globalization;
 using System.Text;
 using System.IO;
 using PdfSharp.Internal;
-using PdfSharp.Fonts.TrueType;
+using PdfSharp.Fonts.OpenType;
 
 namespace PdfSharp.Pdf.Advanced
 {
@@ -104,7 +104,7 @@ namespace PdfSharp.Pdf.Advanced
   /// </summary>
   public sealed class PdfFontDescriptor : PdfDictionary
   {
-    internal PdfFontDescriptor(PdfDocument document, TrueTypeDescriptor descriptor)
+    internal PdfFontDescriptor(PdfDocument document, OpenTypeDescriptor descriptor)
       : base(document)
     {
       this.descriptor = descriptor;
@@ -126,8 +126,8 @@ namespace PdfSharp.Pdf.Advanced
       Elements.SetInteger(Keys.XHeight, this.descriptor.DesignUnitsToPdf(this.descriptor.XHeight));
     }
 
-    //HACK
-    internal TrueTypeDescriptor descriptor;
+    //HACK OpenTypeDescriptor descriptor
+    internal OpenTypeDescriptor descriptor;
 
     //    public string DefaultName
     //    {
@@ -205,8 +205,8 @@ namespace PdfSharp.Pdf.Advanced
     //      return true;
     //    }
 
-    // HACK
-    PdfFontDescriptorFlags FlagsFromDescriptor(TrueTypeDescriptor descriptor)
+    // HACK FlagsFromDescriptor(OpenTypeDescriptor descriptor)
+    PdfFontDescriptorFlags FlagsFromDescriptor(OpenTypeDescriptor descriptor)
     {
       PdfFontDescriptorFlags flags = 0;
       this.isSymbolFont = descriptor.fontData.cmap.symbol;
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfFontTable.cs b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfFontTable.cs
index 7f56b03..9aebd96 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfFontTable.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfFontTable.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -29,13 +29,13 @@
 
 using System;
 using System.Diagnostics;
-using System.Collections;
+using System.Collections.Generic;
 using System.Globalization;
 using System.Text;
 using System.IO;
 using PdfSharp.Drawing;
 using PdfSharp.Internal;
-using PdfSharp.Fonts.TrueType;
+using PdfSharp.Fonts.OpenType;
 
 namespace PdfSharp.Pdf.Advanced
 {
@@ -47,7 +47,7 @@ namespace PdfSharp.Pdf.Advanced
     TrueType = 1,
 
     /// <summary>
-    /// TrueType with Identity-H encoding (unicode).
+    /// TrueType with Identity-H or Identity-V encoding (unicode).
     /// </summary>
     Type0 = 2,
   }
@@ -78,11 +78,11 @@ namespace PdfSharp.Pdf.Advanced
         selector = new FontSelector(font);
         font.selector = selector;
       }
-      PdfFont pdfFont = this.fonts[selector] as PdfFont;
-      if (pdfFont == null)
+      PdfFont pdfFont;
+      if (!this.fonts.TryGetValue(selector, out pdfFont))
       {
         if (font.Unicode)
-          pdfFont = new PdfType0Font(this.owner, font);
+          pdfFont = new PdfType0Font(this.owner, font, font.IsVertical);
         else
           pdfFont = new PdfTrueTypeFont(this.owner, font);
         //pdfFont.Document = this.document;
@@ -190,11 +190,11 @@ namespace PdfSharp.Pdf.Advanced
     public PdfFont GetFont(string idName, byte[] fontData)
     {
       PdfFontTable.FontSelector selector = new FontSelector(idName);
-      PdfFont pdfFont = this.fonts[selector] as PdfFont;
-      if (pdfFont == null)
+      PdfFont pdfFont;
+      if (!this.fonts.TryGetValue(selector, out pdfFont))
       {
         //if (font.Unicode)
-        pdfFont = new PdfType0Font(this.owner, idName, fontData);
+        pdfFont = new PdfType0Font(this.owner, idName, fontData, false);
         //else
         //  pdfFont = new PdfTrueTypeFont(this.owner, font);
         //pdfFont.Document = this.document;
@@ -211,15 +211,16 @@ namespace PdfSharp.Pdf.Advanced
     /// </summary>
     public PdfFont TryGetFont(string idName)
     {
-      PdfFontTable.FontSelector selector = new FontSelector(idName);
-      PdfFont pdfFont = this.fonts[selector] as PdfFont;
+      FontSelector selector = new FontSelector(idName);
+      PdfFont pdfFont;
+      this.fonts.TryGetValue(selector, out pdfFont);
       return pdfFont;
     }
 
     /// <summary>
     /// Map from PdfFontSelector to PdfFont.
     /// </summary>
-    Hashtable fonts = new Hashtable();
+    readonly Dictionary<FontSelector, PdfFont> fonts = new Dictionary<FontSelector, PdfFont>();
 
     public void PrepareForSave()
     {
@@ -228,8 +229,8 @@ namespace PdfSharp.Pdf.Advanced
     }
 
     /// <summary>
-    /// A collection of information that uniquely idendifies a particular PDF font.
-    /// ... more docu...
+    /// A collection of information that uniquely identifies a particular PDF font.
+    /// ... more docu... TODO
     /// Two PDF fonts are equal if and only if their font selector objects are equal.
     /// </summary>
     public class FontSelector
@@ -250,11 +251,15 @@ namespace PdfSharp.Pdf.Advanced
           this.style &= ~XFontStyle.Italic;
 #endif
 #if WPF && !GDI
+#if !SILVERLIGHT
         Debug.Assert(font.typeface != null);
         if ((this.style & XFontStyle.Bold) == XFontStyle.Bold && font.typeface.IsBoldSimulated)
           this.style &= ~XFontStyle.Bold;
         if ((this.style & XFontStyle.Italic) == XFontStyle.Italic && font.typeface.IsObliqueSimulated)
           this.style &= ~XFontStyle.Italic;
+#else
+        // AGHACK
+#endif
 #endif
 #if WPF && GDI
         Debug.Assert(font.typeface != null);
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfFormXObject.cs b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfFormXObject.cs
index d0dee01..2cfa76f 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfFormXObject.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfFormXObject.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -40,14 +40,14 @@ using System.Drawing.Imaging;
 using System.Windows.Media;
 #endif
 using PdfSharp.Drawing;
-using PdfSharp.Fonts.TrueType;
+using PdfSharp.Fonts.OpenType;
 using PdfSharp.Internal;
 using PdfSharp.Pdf.Internal;
 
 namespace PdfSharp.Pdf.Advanced
 {
   /// <summary>
-  /// Represents an external form object (an imported page e.g).
+  /// Represents an external form object (e.g. an imported page).
   /// </summary>
   public sealed class PdfFormXObject : PdfXObject, IContentStream
   {
@@ -218,7 +218,7 @@ namespace PdfSharp.Pdf.Advanced
         this.Elements["/BBox"] = rect;
 
         // Rotate the image such that it is upright
-        XMatrix matrix = XMatrix.Identity;
+        XMatrix matrix = new XMatrix();  //XMatrix.Identity;
         double width = rect.Width;
         double height = rect.Height;
         matrix.RotateAtPrepend(-rotate, new XPoint(width / 2, height / 2));
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfFormXObjectTable.cs b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfFormXObjectTable.cs
index 435e758..31c1170 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfFormXObjectTable.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfFormXObjectTable.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -29,13 +29,13 @@
 
 using System;
 using System.Diagnostics;
-using System.Collections;
+using System.Collections.Generic;
 using System.Globalization;
 using System.Text;
 using System.IO;
 using PdfSharp.Drawing;
 using PdfSharp.Internal;
-using PdfSharp.Fonts.TrueType;
+using PdfSharp.Fonts.OpenType;
 
 namespace PdfSharp.Pdf.Advanced
 {
@@ -57,12 +57,11 @@ namespace PdfSharp.Pdf.Advanced
     /// </summary>
     public PdfFormXObjectTable(PdfDocument document)
       : base(document)
-    {
-    }
+    { }
 
     /// <summary>
     /// Gets a PdfFormXObject from an XPdfForm. Because the returned objects must be unique, always
-    /// a new instance of PdfFormXObject is created if none exists for the specifed form. 
+    /// a new instance of PdfFormXObject is created if none exists for the specified form. 
     /// </summary>
     public PdfFormXObject GetForm(XForm form)
     {
@@ -83,8 +82,8 @@ namespace PdfSharp.Pdf.Advanced
       {
         // Is the external PDF file from which is imported already known for the current document?
         Selector selector = new Selector(form);
-        PdfImportedObjectTable importedObjectTable = this.forms[selector] as PdfImportedObjectTable;
-        if (importedObjectTable == null)
+        PdfImportedObjectTable importedObjectTable;
+        if (!this.forms.TryGetValue(selector, out importedObjectTable))
         {
           // No: Get the external document from the form and create ImportedObjectTable.
           PdfDocument doc = pdfForm.ExternalDocument;
@@ -106,16 +105,14 @@ namespace PdfSharp.Pdf.Advanced
     }
 
     /// <summary>
-    /// 
+    /// Gets the imported object table.
     /// </summary>
-    /// <param name="page"></param>
-    /// <returns></returns>
     public PdfImportedObjectTable GetImportedObjectTable(PdfPage page)
     {
       // Is the external PDF file from which is imported already known for the current document?
       Selector selector = new Selector(page);
-      PdfImportedObjectTable importedObjectTable = this.forms[selector] as PdfImportedObjectTable;
-      if (importedObjectTable == null)
+      PdfImportedObjectTable importedObjectTable;
+      if (!this.forms.TryGetValue(selector, out importedObjectTable))
       {
         importedObjectTable = new PdfImportedObjectTable(this.owner, page.Owner);
         this.forms[selector] = importedObjectTable;
@@ -145,7 +142,7 @@ namespace PdfSharp.Pdf.Advanced
         itemRemoved = false;
         foreach (Selector selector in this.forms.Keys)
         {
-          PdfImportedObjectTable table = (PdfImportedObjectTable)this.forms[selector];
+          PdfImportedObjectTable table = this.forms[selector];
           if (table.ExternalDocument == null)
           {
             this.forms.Remove(selector);
@@ -157,12 +154,12 @@ namespace PdfSharp.Pdf.Advanced
     }
 
     /// <summary>
-    /// Map from FormSelector to ImportedObjectTable.
+    /// Map from Selector to PdfImportedObjectTable.
     /// </summary>
-    Hashtable forms = new Hashtable();
+    readonly Dictionary<Selector, PdfImportedObjectTable> forms = new Dictionary<Selector, PdfImportedObjectTable>();
 
     /// <summary>
-    /// A collection of information that uniquely idendifies a particular ImportedObjectTable.
+    /// A collection of information that uniquely identifies a particular ImportedObjectTable.
     /// </summary>
     public class Selector
     {
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfGroupAttributes.cs b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfGroupAttributes.cs
index 24616f7..1867a37 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfGroupAttributes.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfGroupAttributes.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -40,7 +40,7 @@ using System.Drawing.Imaging;
 using System.Windows.Media;
 #endif
 using PdfSharp.Drawing;
-using PdfSharp.Fonts.TrueType;
+using PdfSharp.Fonts.OpenType;
 using PdfSharp.Internal;
 using PdfSharp.Pdf.Internal;
 
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfImage.FaxEncode.cs b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfImage.FaxEncode.cs
new file mode 100644
index 0000000..5bc031d
--- /dev/null
+++ b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfImage.FaxEncode.cs
@@ -0,0 +1,900 @@
+#region PDFsharp - A .NET library for processing PDF
+//
+// Authors:
+//   Stefan Lange (mailto:Stefan Lange pdfsharp com)
+//   Thomas Hövel (mailto:Thomas Hoevel pdfsharp com)
+//
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
+//
+// http://www.pdfsharp.com
+// http://sourceforge.net/projects/pdfsharp
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+// DEALINGS IN THE SOFTWARE.
+
+// Some routines were translated from LibTiff.
+// LibTiff copyright notice:
+// Copyright (c) 1988-1997 Sam Leffler
+// Copyright (c) 1991-1997 Silicon Graphics, Inc.
+//
+// Permission to use, copy, modify, distribute, and sell this software and 
+// its documentation for any purpose is hereby granted without fee, provided
+// that (i) the above copyright notices and this permission notice appear in
+// all copies of the software and related documentation, and (ii) the names of
+// Sam Leffler and Silicon Graphics may not be used in any advertising or
+// publicity relating to the software without the specific, prior written
+// permission of Sam Leffler and Silicon Graphics.
+//
+// THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
+// EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
+// WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
+//
+// IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+// ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+// OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+// WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
+// LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
+// OF THIS SOFTWARE.
+
+#endregion
+
+#define USE_GOTO
+using System;
+using System.Diagnostics;
+
+namespace PdfSharp.Pdf.Advanced
+{
+  partial class PdfImage
+  {
+    internal readonly static uint[] WhiteTerminatingCodes =
+    {
+      0x35, 8, //00110101 // 0
+      0x07, 6, //000111
+      0x07, 4, //0111
+      0x08, 4, //1000
+      0x0b, 4, //1011
+      0x0c, 4, //1100
+      0x0e, 4, //1110
+      0x0f, 4, //1111
+      0x13, 5, //10011
+      0x14, 5, //10100
+      0x07, 5, //00111    // 10
+      0x08, 5, //01000
+      0x08, 6, //001000
+      0x03, 6, //000011
+      0x34, 6, //110100
+      0x35, 6, //110101
+      0x2a, 6, //101010   // 16
+      0x2b, 6, //101011
+      0x27, 7, //0100111
+      0x0c, 7, //0001100
+      0x08, 7, //0001000  // 20
+      0x17, 7, //0010111
+      0x03, 7, //0000011
+      0x04, 7, //0000100
+      0x28, 7, //0101000
+      0x2b, 7, //0101011
+      0x13, 7, //0010011
+      0x24, 7, //0100100
+      0x18, 7, //0011000
+      0x02, 8, //00000010
+      0x03, 8, //00000011 // 30
+      0x1a, 8, //00011010
+      0x1b, 8, //00011011 // 32
+      0x12, 8, //00010010
+      0x13, 8, //00010011
+      0x14, 8, //00010100
+      0x15, 8, //00010101
+      0x16, 8, //00010110
+      0x17, 8, //00010111
+      0x28, 8, //00101000
+      0x29, 8, //00101001 // 40
+      0x2a, 8, //00101010
+      0x2b, 8, //00101011
+      0x2c, 8, //00101100
+      0x2d, 8, //00101101
+      0x04, 8, //00000100
+      0x05, 8, //00000101
+      0x0a, 8, //00001010
+      0x0b, 8, //00001011 // 48
+      0x52, 8, //01010010
+      0x53, 8, //01010011 // 50
+      0x54, 8, //01010100
+      0x55, 8, //01010101
+      0x24, 8, //00100100
+      0x25, 8, //00100101
+      0x58, 8, //01011000
+      0x59, 8, //01011001
+      0x5a, 8, //01011010
+      0x5b, 8, //01011011
+      0x4a, 8, //01001010
+      0x4b, 8, //01001011 // 60
+      0x32, 8, //00110010
+      0x33, 8, //00110011
+      0x34, 8, //00110100 // 63
+    };
+
+    internal readonly static uint[] BlackTerminatingCodes =
+    {
+      0x37, 10, //0000110111   // 0
+      0x02,  3, //010
+      0x03,  2, //11
+      0x02,  2, //10
+      0x03,  3, //011
+      0x03,  4, //0011
+      0x02,  4, //0010
+      0x03,  5, //00011
+      0x05,  6, //000101
+      0x04,  6, //000100
+      0x04,  7, //0000100
+      0x05,  7, //0000101
+      0x07,  7, //0000111
+      0x04,  8, //00000100
+      0x07,  8, //00000111
+      0x18,  9, //000011000
+      0x17, 10, //0000010111   // 16
+      0x18, 10, //0000011000
+      0x08, 10, //0000001000
+      0x67, 11, //00001100111
+      0x68, 11, //00001101000
+      0x6c, 11, //00001101100
+      0x37, 11, //00000110111
+      0x28, 11, //00000101000
+      0x17, 11, //00000010111
+      0x18, 11, //00000011000
+      0xca, 12, //000011001010
+      0xcb, 12, //000011001011
+      0xcc, 12, //000011001100
+      0xcd, 12, //000011001101
+      0x68, 12, //000001101000 // 30
+      0x69, 12, //000001101001
+      0x6a, 12, //000001101010 // 32
+      0x6b, 12, //000001101011
+      0xd2, 12, //000011010010
+      0xd3, 12, //000011010011
+      0xd4, 12, //000011010100
+      0xd5, 12, //000011010101
+      0xd6, 12, //000011010110
+      0xd7, 12, //000011010111
+      0x6c, 12, //000001101100
+      0x6d, 12, //000001101101
+      0xda, 12, //000011011010
+      0xdb, 12, //000011011011
+      0x54, 12, //000001010100
+      0x55, 12, //000001010101
+      0x56, 12, //000001010110
+      0x57, 12, //000001010111
+      0x64, 12, //000001100100 // 48
+      0x65, 12, //000001100101
+      0x52, 12, //000001010010
+      0x53, 12, //000001010011
+      0x24, 12, //000000100100
+      0x37, 12, //000000110111
+      0x38, 12, //000000111000
+      0x27, 12, //000000100111
+      0x28, 12, //000000101000
+      0x58, 12, //000001011000
+      0x59, 12, //000001011001
+      0x2b, 12, //000000101011
+      0x2c, 12, //000000101100
+      0x5a, 12, //000001011010
+      0x66, 12, //000001100110
+      0x67, 12, //000001100111 // 63
+    };
+
+    internal readonly static uint[] WhiteMakeUpCodes =
+    {
+      0x1b,  5, //11011 64          // 0
+      0x12,  5, //10010 128
+      0x17,  6, //010111 192
+      0x37,  7, //0110111 256
+      0x36,  8, //00110110 320
+      0x37,  8, //00110111 384
+      0x64,  8, //01100100 448
+      0x65,  8, //01100101 512
+      0x68,  8, //01101000 576
+      0x67,  8, //01100111 640
+      0xcc,  9, //011001100 704     // 10
+      0xcd,  9, //011001101 768
+      0xd2,  9, //011010010 832
+      0xd3,  9, //011010011 896
+      0xd4,  9, //011010100 960
+      0xd5,  9, //011010101 1024
+      0xd6,  9, //011010110 1088    // 16
+      0xd7,  9, //011010111 1152
+      0xd8,  9, //011011000 1216
+      0xd9,  9, //011011001 1280
+      0xda,  9, //011011010 1344
+      0xdb,  9, //011011011 1408
+      0x98,  9, //010011000 1472
+      0x99,  9, //010011001 1536
+      0x9a,  9, //010011010 1600
+      0x18,  6, //011000    1664
+      0x9b,  9, //010011011 1728
+      // Common codes for white and black:
+      0x08, 11, //00000001000 1792
+      0x0c, 11, //00000001100 1856
+      0x0d, 11, //00000001101 1920
+      0x12, 12, //000000010010 1984
+      0x13, 12, //000000010011 2048
+      0x14, 12, //000000010100 2112 // 32
+      0x15, 12, //000000010101 2176
+      0x16, 12, //000000010110 2240
+      0x17, 12, //000000010111 2304
+      0x1c, 12, //000000011100 2368
+      0x1d, 12, //000000011101 2432
+      0x1e, 12, //000000011110 2496
+      0x1f, 12, //000000011111 2560
+      0x01, 12, //000000000001 EOL  // 40
+    };
+
+    internal readonly static uint[] BlackMakeUpCodes =
+    {
+      0x0f, 10, //0000001111    64   // 0
+      0xc8, 12, //000011001000  128
+      0xc9, 12, //000011001001  192
+      0x5b, 12, //000001011011  256
+      0x33, 12, //000000110011  320
+      0x34, 12, //000000110100  384
+      0x35, 12, //000000110101  448
+      0x6c, 13, //0000001101100 512
+      0x6d, 13, //0000001101101 576
+      0x4a, 13, //0000001001010 640
+      0x4b, 13, //0000001001011 704
+      0x4c, 13, //0000001001100 768
+      0x4d, 13, //0000001001101 832
+      0x72, 13, //0000001110010 896
+      0x73, 13, //0000001110011 960
+      0x74, 13, //0000001110100 1024
+      0x75, 13, //0000001110101 1088 // 16
+      0x76, 13, //0000001110110 1152
+      0x77, 13, //0000001110111 1216
+      0x52, 13, //0000001010010 1280
+      0x53, 13, //0000001010011 1344
+      0x54, 13, //0000001010100 1408
+      0x55, 13, //0000001010101 1472
+      0x5a, 13, //0000001011010 1536
+      0x5b, 13, //0000001011011 1600
+      0x64, 13, //0000001100100 1664
+      0x65, 13, //0000001100101 1728
+      // Common codes for white and black:
+      0x08, 11, //00000001000 1792
+      0x0c, 11, //00000001100 1856
+      0x0d, 11, //00000001101 1920
+      0x12, 12, //000000010010 1984
+      0x13, 12, //000000010011 2048
+      0x14, 12, //000000010100 2112  // 32
+      0x15, 12, //000000010101 2176
+      0x16, 12, //000000010110 2240
+      0x17, 12, //000000010111 2304
+      0x1c, 12, //000000011100 2368
+      0x1d, 12, //000000011101 2432
+      0x1e, 12, //000000011110 2496
+      0x1f, 12, //000000011111 2560
+      0x01, 12, //000000000001 EOL   // 40
+    };
+
+    internal readonly static uint[] HorizontalCodes = { 0x1, 3 }; /* 001 */
+    internal readonly static uint[] PassCodes = { 0x1, 4, }; /* 0001 */
+    internal readonly static uint[] VerticalCodes =
+    {
+      0x03, 7, /* 0000 011 */
+      0x03, 6, /* 0000 11 */
+      0x03, 3, /* 011 */
+      0x1,  1, /* 1 */
+      0x2,  3, /* 010 */
+      0x02, 6, /* 0000 10 */
+      0x02, 7, /* 0000 010 */
+    };
+
+    readonly static uint[] ZeroRuns =
+    {
+      8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,	/* 0x00 - 0x0f */
+      3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,	/* 0x10 - 0x1f */
+      2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,	/* 0x20 - 0x2f */
+      2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,	/* 0x30 - 0x3f */
+      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	/* 0x40 - 0x4f */
+      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	/* 0x50 - 0x5f */
+      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	/* 0x60 - 0x6f */
+      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	/* 0x70 - 0x7f */
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x80 - 0x8f */
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x90 - 0x9f */
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0xa0 - 0xaf */
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0xb0 - 0xbf */
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0xc0 - 0xcf */
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0xd0 - 0xdf */
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0xe0 - 0xef */
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0xf0 - 0xff */
+    };
+
+    readonly static uint[] OneRuns =
+    {
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x00 - 0x0f */
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x10 - 0x1f */
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x20 - 0x2f */
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x30 - 0x3f */
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x40 - 0x4f */
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x50 - 0x5f */
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x60 - 0x6f */
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x70 - 0x7f */
+      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	/* 0x80 - 0x8f */
+      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	/* 0x90 - 0x9f */
+      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	/* 0xa0 - 0xaf */
+      1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	/* 0xb0 - 0xbf */
+      2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,	/* 0xc0 - 0xcf */
+      2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,	/* 0xd0 - 0xdf */
+      3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,	/* 0xe0 - 0xef */
+      4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8,	/* 0xf0 - 0xff */
+    };
+
+    /// <summary>
+    /// Counts the consecutive one bits in an image line.
+    /// </summary>
+    /// <param name="reader">The reader.</param>
+    /// <param name="bitsLeft">The bits left.</param>
+    private static uint CountOneBits(BitReader reader, uint bitsLeft)
+    {
+      uint found = 0;
+      for (; ; )
+      {
+        uint bits;
+        int @byte = reader.PeekByte(out bits);
+        uint hits = OneRuns[ byte];
+        if (hits < bits)
+        {
+          if (hits > 0)
+            reader.SkipBits(hits);
+          return found + hits;
+        }
+        found += bits;
+        if (found >= bitsLeft)
+          return bitsLeft;
+        reader.NextByte();
+      }
+    }
+
+    /// <summary>
+    /// Counts the consecutive zero bits in an image line.
+    /// </summary>
+    /// <param name="reader">The reader.</param>
+    /// <param name="bitsLeft">The bits left.</param>
+    private static uint CountZeroBits(BitReader reader, uint bitsLeft)
+    {
+      uint found = 0;
+      for (; ; )
+      {
+        uint bits;
+        int @byte = reader.PeekByte(out bits);
+        uint hits = ZeroRuns[ byte];
+        if (hits < bits)
+        {
+          if (hits > 0)
+            reader.SkipBits(hits);
+          return found + hits;
+        }
+        found += bits;
+        if (found >= bitsLeft)
+          return bitsLeft;
+        reader.NextByte();
+      }
+    }
+
+    /// <summary>
+    /// Returns the offset of the next bit in the range
+    /// [bitStart..bitEnd] that is different from the
+    /// specified color.  The end, bitEnd, is returned
+    /// if no such bit exists.
+    /// </summary>
+    /// <param name="reader">The reader.</param>
+    /// <param name="bitStart">The offset of the start bit.</param>
+    /// <param name="bitEnd">The offset of the end bit.</param>
+    /// <param name="searchOne">If set to <c>true</c> searches "one" (i. e. white), otherwise searches black.</param>
+    /// <returns>The offset of the first non-matching bit.</returns>
+    private static uint FindDifference(BitReader reader, uint bitStart, uint bitEnd, bool searchOne)
+    {
+      // Translated from LibTiff
+      reader.SetPosition(bitStart);
+      return (bitStart + (searchOne ? CountOneBits(reader, bitEnd - bitStart) : CountZeroBits(reader, bitEnd - bitStart)));
+    }
+
+    /// <summary>
+    /// Returns the offset of the next bit in the range
+    /// [bitStart..bitEnd] that is different from the
+    /// specified color.  The end, bitEnd, is returned
+    /// if no such bit exists.
+    /// Like FindDifference, but also check the
+    /// starting bit against the end in case start > end.
+    /// </summary>
+    /// <param name="reader">The reader.</param>
+    /// <param name="bitStart">The offset of the start bit.</param>
+    /// <param name="bitEnd">The offset of the end bit.</param>
+    /// <param name="searchOne">If set to <c>true</c> searches "one" (i. e. white), otherwise searches black.</param>
+    /// <returns>The offset of the first non-matching bit.</returns>
+    private static uint FindDifferenceWithCheck(BitReader reader, uint bitStart, uint bitEnd, bool searchOne)
+    {
+      // Translated from LibTiff
+      return ((bitStart < bitEnd) ? FindDifference(reader, bitStart, bitEnd, searchOne) : bitEnd);
+    }
+
+    /// <summary>
+    /// 2d-encode a row of pixels. Consult the CCITT documentation for the algorithm.
+    /// </summary>
+    /// <param name="writer">The writer.</param>
+    /// <param name="bytesFileOffset">Offset of image data in bitmap file.</param>
+    /// <param name="imageBits">The bitmap file.</param>
+    /// <param name="currentRow">Index of the current row.</param>
+    /// <param name="referenceRow">Index of the reference row (0xffffffff if there is none).</param>
+    /// <param name="width">The width of the image.</param>
+    /// <param name="height">The height of the image.</param>
+    /// <param name="bytesPerLineBmp">The bytes per line in the bitmap file.</param>
+    static void FaxEncode2DRow(BitWriter writer, uint bytesFileOffset, byte[] imageBits, uint currentRow, uint referenceRow, uint width, uint height, uint bytesPerLineBmp)
+    {
+      // Translated from LibTiff
+      uint bytesOffsetRead = bytesFileOffset + (height - 1 - currentRow) * bytesPerLineBmp;
+      BitReader reader = new BitReader(imageBits, bytesOffsetRead, width);
+      BitReader readerReference;
+      if (referenceRow != 0xffffffff)
+      {
+        uint bytesOffsetReadReference = bytesFileOffset + (height - 1 - referenceRow) * bytesPerLineBmp;
+        readerReference = new BitReader(imageBits, bytesOffsetReadReference, width);
+      }
+      else
+      {
+        byte[] tmpImageBits = new byte[bytesPerLineBmp];
+        for (int i = 0; i < bytesPerLineBmp; ++i)
+          tmpImageBits[i] = 255;
+        readerReference = new BitReader(tmpImageBits, 0, width);
+      }
+
+      uint a0 = 0;
+      uint a1 = !reader.GetBit(0) ? 0 : FindDifference(reader, 0, width, true);
+      uint b1 = !readerReference.GetBit(0) ? 0 : FindDifference(readerReference, 0, width, true);
+// ReSharper disable TooWideLocalVariableScope
+      uint a2, b2;
+// ReSharper restore TooWideLocalVariableScope
+
+      for (; ; )
+      {
+        b2 = FindDifferenceWithCheck(readerReference, b1, width, readerReference.GetBit(b1));
+        if (b2 >= a1)
+        {
+          int d = (int)b1 - (int)a1;
+          if (!(-3 <= d && d <= 3))
+          { 
+            /* horizontal mode */
+            a2 = FindDifferenceWithCheck(reader, a1, width, reader.GetBit(a1));
+            writer.WriteTableLine(HorizontalCodes, 0);
+
+            if (a0 + a1 == 0 || reader.GetBit(a0))
+            {
+              WriteSample(writer, a1 - a0, true);
+              WriteSample(writer, a2 - a1, false);
+            }
+            else
+            {
+              WriteSample(writer, a1 - a0, false);
+              WriteSample(writer, a2 - a1, true);
+            }
+            a0 = a2;
+          }
+          else
+          { 
+            /* vertical mode */
+            writer.WriteTableLine(VerticalCodes, (uint)(d + 3));
+            a0 = a1;
+          }
+        }
+        else
+        { 
+          /* pass mode */
+          writer.WriteTableLine(PassCodes, 0);
+          a0 = b2;
+        }
+        if (a0 >= width)
+          break;
+        bool bitA0 = reader.GetBit(a0);
+        a1 = FindDifference(reader, a0, width, bitA0/*reader.GetBit(a0)*/);
+        b1 = FindDifference(readerReference, a0, width, !bitA0/*reader.GetBit(a0)*/);
+        b1 = FindDifferenceWithCheck(readerReference, b1, width, bitA0/*reader.GetBit(a0)*/);
+      }
+    }
+
+    /// <summary>
+    /// Encodes a bitonal bitmap using 1D CCITT fax encoding.
+    /// </summary>
+    /// <param name="imageData">Space reserved for the fax encoded bitmap. An exception will be thrown if this buffer is too small.</param>
+    /// <param name="imageBits">The bitmap to be encoded.</param>
+    /// <param name="bytesFileOffset">Offset of image data in bitmap file.</param>
+    /// <param name="width">The width of the image.</param>
+    /// <param name="height">The height of the image.</param>
+    /// <returns>The size of the fax encoded image (0 on failure).</returns>
+    private static int DoFaxEncoding(ref byte[] imageData, byte[] imageBits, uint bytesFileOffset, uint width, uint height)
+    {
+      try
+      {
+        uint bytesPerLineBmp = ((width + 31) / 32) * 4;
+        BitWriter writer = new BitWriter(ref imageData);
+        for (uint y = 0; y < height; ++y)
+        {
+          uint bytesOffsetRead = bytesFileOffset + (height - 1 - y) * bytesPerLineBmp;
+          BitReader reader = new BitReader(imageBits, bytesOffsetRead, width);
+          for (uint bitsRead = 0; bitsRead < width; )
+          {
+            uint white = CountOneBits(reader, width - bitsRead);
+            WriteSample(writer, white, true);
+            bitsRead += white;
+            if (bitsRead < width)
+            {
+              uint black = CountZeroBits(reader, width - bitsRead);
+              WriteSample(writer, black, false);
+              bitsRead += black;
+            }
+          }
+        }
+        writer.FlushBuffer();
+        return writer.BytesWritten();
+      }
+      catch (Exception /*ex*/)
+      {
+        //ex.GetType();
+        return 0;
+      }
+    }
+
+    //[Obsolete]
+    ///// <summary>
+    ///// Encodes a bitonal bitmap using 2D group 3 CCITT fax encoding.
+    ///// </summary>
+    ///// <param name="imageData">Space reserved for the fax encoded bitmap. An exception will be thrown if this buffer is too small.</param>
+    ///// <param name="imageBits">The bitmap to be encoded.</param>
+    ///// <param name="bytesFileOffset">Offset of image data in bitmap file.</param>
+    ///// <param name="width">The width of the image.</param>
+    ///// <param name="height">The height of the image.</param>
+    ///// <param name="dpiY">The horizontal dpi of the image (needed to determine K).</param>
+    ///// <param name="k">The K parameter (passed to the PDF file).</param>
+    ///// <returns>The size of the fax encoded image (0 on failure).</returns>
+    //private static int DoFaxEncoding2D(ref byte[] imageData, byte[] imageBits, uint bytesFileOffset, uint width, uint height, uint dpiY, out uint k)
+    //{
+    //  // It seems that either pure 1D or pure 2D encoding creates smaller files than this mixed 1D/2D encoding.
+    //  // Therefore this routine is not currently in use, but is left here for further research.
+    //  try
+    //  {
+    //    k = (dpiY > 199) ? (uint)4 : (uint)2;
+    //    uint bytesPerLineBmp = ((width + 31) / 32) * 4;
+    //    BitWriter writer = new BitWriter(ref imageData);
+    //    uint kTmp = 0;
+    //    for (uint y = 0; y < height; ++y)
+    //    {
+    //      if (kTmp == 0)
+    //      {
+    //        kTmp = k - 1;
+    //        uint bytesOffsetRead = bytesFileOffset + (height - 1 - y) * bytesPerLineBmp;
+    //        BitReader reader = new BitReader(imageBits, bytesOffsetRead, width);
+    //        for (uint bitsRead = 0; bitsRead < width; )
+    //        {
+    //          uint white = CountOneBits(reader, width - bitsRead);
+    //          WriteSample(writer, white, true);
+    //          bitsRead += white;
+    //          if (bitsRead < width)
+    //          {
+    //            uint black = CountZeroBits(reader, width - bitsRead);
+    //            WriteSample(writer, black, false);
+    //            bitsRead += black;
+    //          }
+    //        }
+    //      }
+    //      else
+    //      {
+    //        uint refLine = y - 1;
+    //        FaxEncode2DRow(writer, bytesFileOffset, imageBits, y, refLine, width, height, bytesPerLineBmp);
+    //        --kTmp;
+    //      }
+    //    }
+    //    writer.FlushBuffer();
+    //    return writer.BytesWritten();
+    //  }
+    //  catch (Exception ex)
+    //  {
+    //    ex.GetType();
+    //    k = 0;
+    //    return 0;
+    //  }
+    //}
+
+    /// <summary>
+    /// Encodes a bitonal bitmap using 2D group 4 CCITT fax encoding.
+    /// </summary>
+    /// <param name="imageData">Space reserved for the fax encoded bitmap. An exception will be thrown if this buffer is too small.</param>
+    /// <param name="imageBits">The bitmap to be encoded.</param>
+    /// <param name="bytesFileOffset">Offset of image data in bitmap file.</param>
+    /// <param name="width">The width of the image.</param>
+    /// <param name="height">The height of the image.</param>
+    /// <returns>The size of the fax encoded image (0 on failure).</returns>
+    private static int DoFaxEncodingGroup4(ref byte[] imageData, byte[] imageBits, uint bytesFileOffset, uint width, uint height)
+    {
+      try
+      {
+        uint bytesPerLineBmp = ((width + 31) / 32) * 4;
+        BitWriter writer = new BitWriter(ref imageData);
+        for (uint y = 0; y < height; ++y)
+        {
+          FaxEncode2DRow(writer, bytesFileOffset, imageBits, y, (y != 0) ? y - 1 : 0xffffffff, width, height, bytesPerLineBmp);
+        }
+        writer.FlushBuffer();
+        return writer.BytesWritten();
+      }
+      catch (Exception ex)
+      {
+        ex.GetType();
+        return 0;
+      }
+    }
+
+    /// <summary>
+    /// Writes the image data.
+    /// </summary>
+    /// <param name="writer">The writer.</param>
+    /// <param name="count">The count of bits (pels) to encode.</param>
+    /// <param name="white">The color of the pels.</param>
+    private static void WriteSample(BitWriter writer, uint count, bool white)
+    {
+      uint[] terminatingCodes = white ? WhiteTerminatingCodes : BlackTerminatingCodes;
+      uint[] makeUpCodes = white ? WhiteMakeUpCodes : BlackMakeUpCodes;
+
+      // The make-up code for 2560 will be written as often as required:
+      while (count >= 2624)
+      {
+        writer.WriteTableLine(makeUpCodes, 39); // Magic: 2560
+        count -= 2560;
+      }
+      // A make-up code for a multiple of 64 will be written if required:
+      if (count > 63)
+      {
+        uint line = count / 64 - 1;
+        writer.WriteTableLine(makeUpCodes, line);
+        count -= (line + 1) * 64;
+      }
+      // And finally the terminating code for the remaining value (0 through 63):
+      writer.WriteTableLine(terminatingCodes, count);
+    }
+  }
+
+  /// <summary>
+  /// The BitReader class is a helper to read bits from an in-memory bitmap file.
+  /// </summary>
+  class BitReader
+  {
+    readonly byte[] imageBits;
+    uint bytesOffsetRead;
+    readonly uint bytesFileOffset;
+    byte buffer;
+    uint bitsInBuffer;
+    readonly uint bitsTotal; // Bits we may read (bits per image line)
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="BitReader"/> class.
+    /// </summary>
+    /// <param name="imageBits">The in-memory bitmap file.</param>
+    /// <param name="bytesFileOffset">The offset of the line to read.</param>
+    /// <param name="bits">The count of bits that may be read (i. e. the width of the image for normal usage).</param>
+    internal BitReader(byte[] imageBits, uint bytesFileOffset, uint bits)
+    {
+      this.imageBits = imageBits;
+      this.bytesFileOffset = bytesFileOffset;
+      bitsTotal = bits;
+      bytesOffsetRead = bytesFileOffset;
+      buffer = imageBits[bytesOffsetRead];
+      bitsInBuffer = 8;
+    }
+
+    /// <summary>
+    /// Sets the position within the line (needed for 2D encoding).
+    /// </summary>
+    /// <param name="position">The new position.</param>
+    internal void SetPosition(uint position)
+    {
+      bytesOffsetRead = bytesFileOffset + (position >> 3);
+      buffer = imageBits[bytesOffsetRead];
+      bitsInBuffer = 8 - (position & 0x07);
+    }
+
+    /// <summary>
+    /// Gets a single bit at the specified position.
+    /// </summary>
+    /// <param name="position">The position.</param>
+    /// <returns>True if bit is set.</returns>
+    internal bool GetBit(uint position)
+    {
+      if (position >= bitsTotal)
+        return false;
+      SetPosition(position);
+      uint dummy;
+      return (PeekByte(out dummy) & 0x80) > 0;
+    }
+
+    /// <summary>
+    /// Returns the bits that are in the buffer (without changing the position).
+    /// Data is MSB aligned.
+    /// </summary>
+    /// <param name="bits">The count of bits that were returned (1 through 8).</param>
+    /// <returns>The MSB aligned bits from the buffer.</returns>
+    internal byte PeekByte(out uint bits)
+    {
+      // TODO: try to make this faster!
+      if (bitsInBuffer == 8)
+      {
+        bits = 8;
+        return buffer;
+      }
+      bits = bitsInBuffer;
+      return (byte)(buffer << (int)(8 - bitsInBuffer));
+    }
+
+    /// <summary>
+    /// Moves the buffer to the next byte.
+    /// </summary>
+    internal void NextByte()
+    {
+      buffer = imageBits[++bytesOffsetRead];
+      bitsInBuffer = 8;
+    }
+
+    /// <summary>
+    /// "Removes" (eats) bits from the buffer.
+    /// </summary>
+    /// <param name="bits">The count of bits that were processed.</param>
+    internal void SkipBits(uint bits)
+    {
+      Debug.Assert(bits <= bitsInBuffer, "Buffer underrun");
+      if (bits == bitsInBuffer)
+      {
+        NextByte();
+        return;
+      }
+      bitsInBuffer -= bits;
+    }
+  }
+
+  /// <summary>
+  /// A helper class for writing groups of bits into an array of bytes.
+  /// </summary>
+  class BitWriter
+  {
+    int bytesOffsetWrite;
+    readonly byte[] imageData;
+    uint buffer;
+    uint bitsInBuffer;
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="BitWriter"/> class.
+    /// </summary>
+    /// <param name="imageData">The byte array to be written to.</param>
+    internal BitWriter(ref byte[] imageData)
+    {
+      this.imageData = imageData;
+    }
+
+    /// <summary>
+    /// Writes the buffered bits into the byte array.
+    /// </summary>
+    internal void FlushBuffer()
+    {
+      if (bitsInBuffer > 0)
+      {
+        uint bits = 8 - bitsInBuffer;
+        WriteBits(0, bits);
+      }
+    }
+
+    /// <summary>
+    /// Masks for n bits in a byte (with n = 0 through 8).
+    /// </summary>
+    static readonly uint[] masks = { 0, 1, 3, 7, 15, 31, 63, 127, 255 };
+
+    /// <summary>
+    /// Writes bits to the byte array.
+    /// </summary>
+    /// <param name="value">The bits to be written (LSB aligned).</param>
+    /// <param name="bits">The count of bits.</param>
+    internal void WriteBits(uint value, uint bits)
+    {
+#if true
+    // TODO: Try to make this faster!
+
+    // If we have to write more bits than fit into the buffer, we fill
+    // the buffer and call the same routine recursively for the rest.
+#if USE_GOTO
+    // Use GOTO instead of end recursion: (is this faster?)
+    SimulateRecursion:
+#endif
+      if (bits + bitsInBuffer > 8)
+      {
+        // We can't add all bits this time.
+        uint bitsNow = 8 - bitsInBuffer;
+        uint bitsRemainder = bits - bitsNow;
+        WriteBits(value >> (int)(bitsRemainder), bitsNow); // that fits
+#if USE_GOTO
+        bits = bitsRemainder;
+        goto SimulateRecursion;
+#else
+        WriteBits(value, bitsRemainder);
+        return;
+#endif
+      }
+
+      buffer = (buffer << (int)bits) + (value & masks[bits]);
+      bitsInBuffer += bits;
+
+      if (bitsInBuffer == 8)
+      {
+        imageData[bytesOffsetWrite] = (byte)buffer;
+        bitsInBuffer = 0;
+        ++bytesOffsetWrite;
+      }
+#else
+      // Simple implementation writing bit by bit:
+      int mask = 1 << (int)(bits - 1);
+      for (int b = 0; b < bits; ++b)
+      {
+        if ((value & mask) != 0)
+          buffer = (buffer << 1) + 1;
+        else
+          buffer = buffer << 1;
+        ++bitsInBuffer;
+        mask /= 2;
+        if (bitsInBuffer == 8)
+        {
+          imageData[bytesOffsetWrite] = (byte)buffer;
+          bitsInBuffer = 0;
+          ++bytesOffsetWrite;
+        }
+      }
+#endif
+    }
+
+    /// <summary>
+    /// Writes a line from a look-up table.
+    /// A "line" in the table are two integers, one containing the values, one containing the bit count.
+    /// </summary>
+    /// <param name="table">The table.</param>
+    /// <param name="line">The line.</param>
+    internal void WriteTableLine(uint[] table, uint line)
+    {
+      uint value = table[line * 2];
+      uint bits = table[line * 2 + 1];
+      WriteBits(value, bits);
+    }
+
+    [Obsolete]
+    internal void WriteEOL()
+    {
+      // Not needed for PDF.
+      WriteTableLine(PdfImage.WhiteMakeUpCodes, 40);
+    }
+
+    /// <summary>
+    /// Flushes the buffer and returns the count of bytes written to the array.
+    /// </summary>
+    /// <returns></returns>
+    internal int BytesWritten()
+    {
+      FlushBuffer();
+      return bytesOffsetWrite;
+    }
+  }
+}
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfImage.cs b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfImage.cs
index 15f2941..8d22234 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfImage.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfImage.cs
@@ -4,7 +4,7 @@
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //   Thomas Hövel (mailto:Thomas Hoevel pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -42,7 +42,7 @@ using System.Windows.Media;
 using System.Windows.Media.Imaging;
 #endif
 using PdfSharp.Drawing;
-using PdfSharp.Fonts.TrueType;
+using PdfSharp.Fonts.OpenType;
 using PdfSharp.Internal;
 using PdfSharp.Pdf.Filters;
 
@@ -51,7 +51,7 @@ namespace PdfSharp.Pdf.Advanced
   /// <summary>
   /// Represents an image.
   /// </summary>
-  public sealed class PdfImage : PdfXObject
+  public sealed partial class PdfImage : PdfXObject
   {
     /// <summary>
     /// Initializes a new instance of PdfImage from an XImage.
@@ -99,9 +99,10 @@ namespace PdfSharp.Pdf.Advanced
     /// </summary>
     public XImage Image
     {
-      get { return this.image; }
+      get { return image; }
     }
-    XImage image;
+
+    readonly XImage image;
 
     /// <summary>
     /// Returns 'Image'.
@@ -117,25 +118,54 @@ namespace PdfSharp.Pdf.Advanced
     void InitializeJpeg()
     {
       // PDF support JPEG, so there's not much to be done
-      MemoryStream memory = new MemoryStream();
+      MemoryStream memory;
+      byte[] imageBits = null;
+      int streamLength = 0;
 #if GDI
+      memory = new MemoryStream();
       image.gdiImage.Save(memory, ImageFormat.Jpeg);
+      if ((int)memory.Length == 0)
+      {
+        Debug.Assert(false, "Internal error? JPEG image, but file not found!");
+      }
 #endif
-#if WPF
-      JpegBitmapEncoder encoder = new JpegBitmapEncoder();
-      encoder.Frames.Add(BitmapFrame.Create(this.image.wpfImage));
-      encoder.Save(memory);
+#if WPF && !SILVERLIGHT
+      // AGHACK
+      //string filename = XImage.GetImageFilename(image.wpfImage);
+      //if (XImage.ReadJpegFile(filename, -1, ref imageBits))
+      //{
+      //  streamLength = imageBits.Length;
+      //}
+      //else
+      //  imageBits = null;
+      memory = image.Memory;
 #endif
-      int streamLength = (int)memory.Length;
-      byte[] imageBits = new byte[streamLength];
-      memory.Seek(0, SeekOrigin.Begin);
-      memory.Read(imageBits, 0, streamLength);
-      memory.Close();
-
-      Stream = new PdfStream(imageBits, this);
+      if (imageBits == null)
+      {
+        streamLength = (int)memory.Length;
+        imageBits = new byte[streamLength];
+        memory.Seek(0, SeekOrigin.Begin);
+        memory.Read(imageBits, 0, streamLength);
+        memory.Close();
+      }
 
-      Elements[Keys.Length] = new PdfInteger(streamLength);
-      Elements[Keys.Filter] = new PdfName("/DCTDecode");
+      FlateDecode fd = new FlateDecode();
+      byte[] imageDataCompressed = fd.Encode(imageBits);
+      if (imageDataCompressed.Length < imageBits.Length)
+      {
+        Stream = new PdfStream(imageDataCompressed, this);
+        Elements[Keys.Length] = new PdfInteger(imageDataCompressed.Length);
+        PdfArray arrayFilters = new PdfArray(document);
+        arrayFilters.Elements.Add(new PdfName("/FlateDecode"));
+        arrayFilters.Elements.Add(new PdfName("/DCTDecode"));
+        Elements[Keys.Filter] = arrayFilters;
+      }
+      else
+      {
+        Stream = new PdfStream(imageBits, this);
+        Elements[Keys.Length] = new PdfInteger(streamLength);
+        Elements[Keys.Filter] = new PdfName("/DCTDecode");
+      }
       Elements[Keys.Width] = new PdfInteger(image.PixelWidth);
       Elements[Keys.Height] = new PdfInteger(image.PixelHeight);
       Elements[Keys.BitsPerComponent] = new PdfInteger(8);
@@ -160,6 +190,28 @@ namespace PdfSharp.Pdf.Advanced
 #if WPF
       // TODOWPF
       // WPFTHHO
+#if !SILVERLIGHT
+      string pixelFormat = image.wpfImage.Format.ToString();
+#else
+      string pixelFormat = "xxx";
+#endif
+      bool isCmyk = image.IsCmyk;
+      bool isGrey = pixelFormat == "Gray8";
+      if (isCmyk)
+      {
+        // TODO: Test with CMYK JPEG files
+        // THHO: I only found ImageFlags.ColorSpaceYcck JPEG files ...
+        Elements[Keys.ColorSpace] = new PdfName("/DeviceCMYK");
+        Elements["/Decode"] = new PdfLiteral("[1 0 1 0 1 0 1 0]");  // Invert colors? Why??
+      }
+      else if (isGrey)
+      {
+        Elements[Keys.ColorSpace] = new PdfName("/DeviceGray");
+      }
+      else
+      {
+        Elements[Keys.ColorSpace] = new PdfName("/DeviceRGB");
+      }
 #endif
     }
 
@@ -169,34 +221,33 @@ namespace PdfSharp.Pdf.Advanced
     void InitializeNonJpeg()
     {
 #if GDI && !WPF
-      bool hasMask = false;
-      int pPdfVersion = this.Owner.Version;
+      //bool hasMask = false;
       switch (image.gdiImage.PixelFormat)
       {
-        case System.Drawing.Imaging.PixelFormat.Format24bppRgb:
+        case PixelFormat.Format24bppRgb:
           ReadTrueColorMemoryBitmap(3, 8, false);
           break;
 
-        case System.Drawing.Imaging.PixelFormat.Format32bppRgb:
+        case PixelFormat.Format32bppRgb:
           ReadTrueColorMemoryBitmap(4, 8, false);
           break;
 
-        case System.Drawing.Imaging.PixelFormat.Format32bppArgb:
-        case System.Drawing.Imaging.PixelFormat.Format32bppPArgb:
-          hasMask = true;
+        case PixelFormat.Format32bppArgb:
+        case PixelFormat.Format32bppPArgb:
+          //hasMask = true;
           ReadTrueColorMemoryBitmap(3, 8, true);
           break;
 
-        case System.Drawing.Imaging.PixelFormat.Format8bppIndexed:
-          ReadIndexedMemoryBitmap(8, ref hasMask);
+        case PixelFormat.Format8bppIndexed:
+          ReadIndexedMemoryBitmap(8/*, ref hasMask*/);
           break;
 
-        case System.Drawing.Imaging.PixelFormat.Format4bppIndexed:
-          ReadIndexedMemoryBitmap(4, ref hasMask);
+        case PixelFormat.Format4bppIndexed:
+          ReadIndexedMemoryBitmap(4/*, ref hasMask*/);
           break;
 
-        case System.Drawing.Imaging.PixelFormat.Format1bppIndexed:
-          ReadIndexedMemoryBitmap(1, ref hasMask);
+        case PixelFormat.Format1bppIndexed:
+          ReadIndexedMemoryBitmap(1/*, ref hasMask*/);
           break;
 
         default:
@@ -208,9 +259,12 @@ namespace PdfSharp.Pdf.Advanced
 #endif
 #if WPF // && !GDI
       // WPFTHHO: Bitte prüfen, siehe System.Windows.Media.PixelFormats
-      bool hasMask = false;
-      int pPdfVersion = this.Owner.Version;
+      //bool hasMask = false;
+#if !SILVERLIGHT
       string format = image.wpfImage.Format.ToString();
+#else
+      string format = "Bgr24";
+#endif
       switch (format)
       {
         case "Bgr24": //Format24bppRgb:
@@ -223,51 +277,54 @@ namespace PdfSharp.Pdf.Advanced
 
         case "Bgra32":  //PixelFormat.Format32bppArgb:
           //case PixelFormat.Format32bppPArgb:
-          hasMask = true;
+          //hasMask = true;
           ReadTrueColorMemoryBitmap(3, 8, true);
           break;
 
         case "Bgr32": // StL: neu
-          hasMask = false;
+          //hasMask = false;
           ReadTrueColorMemoryBitmap(3, 8, true);
           break;
 
         case "Pbgra32": // StL: neu
-          hasMask = false;
+          //hasMask = false;
           ReadTrueColorMemoryBitmap(3, 8, true);
           break;
 
         case "Indexed8":  //Format8bppIndexed:
-          ReadIndexedMemoryBitmap(8, ref hasMask);
+        case "Gray8":
+          ReadIndexedMemoryBitmap(8/*, ref hasMask*/);
           break;
 
         case "Indexed4":  //Format4bppIndexed:
-          ReadIndexedMemoryBitmap(4, ref hasMask);
+        case "Gray4":
+          ReadIndexedMemoryBitmap(4/*, ref hasMask*/);
           break;
 
-        case "Indexed2": // WPFTHHO gibt es das auch?
-          ReadIndexedMemoryBitmap(2, ref hasMask);
+        case "Indexed2":
+          ReadIndexedMemoryBitmap(2/*, ref hasMask*/);
           break;
 
         case "Indexed1":  //Format1bppIndexed:
-          ReadIndexedMemoryBitmap(1, ref hasMask);
+        case "BlackWhite":  //Format1bppIndexed:
+          ReadIndexedMemoryBitmap(1/*, ref hasMask*/);
           break;
 
         default:
 #if DEBUGxxx
           image.image.Save("$$$.bmp", ImageFormat.Bmp);
 #endif
-          throw new NotImplementedException("Image format not supported.");
+          throw new NotImplementedException("Image format \"" + format + "\" not supported.");
       }
 #endif
     }
 
-    private int ReadWord(byte[] ab, int offset)
+    private static int ReadWord(byte[] ab, int offset)
     {
-      return (int)ab[offset] + 256 * (int)ab[offset + 1];
+      return ab[offset] + 256 * ab[offset + 1];
     }
 
-    private int ReadDWord(byte[] ab, int offset)
+    private static int ReadDWord(byte[] ab, int offset)
     {
       return ReadWord(ab, offset) + 0x10000 * ReadWord(ab, offset + 2);
     }
@@ -283,16 +340,20 @@ namespace PdfSharp.Pdf.Advanced
 #if DEBUG_
       image.image.Save("$$$.bmp", ImageFormat.Bmp);
 #endif
-      int pdfVersion = this.Owner.Version;
+      int pdfVersion = Owner.Version;
       MemoryStream memory = new MemoryStream();
 #if GDI
       image.gdiImage.Save(memory, ImageFormat.Bmp);
 #endif
 #if WPF
+#if !SILVERLIGHT
       // WPFTHHO: Bitte prüfen
       BmpBitmapEncoder encoder = new BmpBitmapEncoder();
-      encoder.Frames.Add(BitmapFrame.Create(this.image.wpfImage));
+      encoder.Frames.Add(BitmapFrame.Create(image.wpfImage));
       encoder.Save(memory);
+#else
+      // AGHACK
+#endif
 #endif
       int streamLength = (int)memory.Length;
       Debug.Assert(streamLength > 0, "Bitmap image encoding failed.");
@@ -303,8 +364,8 @@ namespace PdfSharp.Pdf.Advanced
         memory.Read(imageBits, 0, streamLength);
         memory.Close();
 
-        int height = this.image.PixelHeight;
-        int width = this.image.PixelWidth;
+        int height = image.PixelHeight;
+        int width = image.PixelWidth;
 
         // TODO: we could define structures for
         //   BITMAPFILEHEADER
@@ -347,8 +408,12 @@ namespace PdfSharp.Pdf.Advanced
           for (int y = 0; y < height; ++y)
           {
             int nOffsetWrite = 3 * (height - 1 - y) * width;
+            int nOffsetWriteAlpha = 0;
             if (hasAlpha)
+            {
               mask.StartLine(y);
+              nOffsetWriteAlpha = (height - 1 - y) * width;
+            }
 
             for (int x = 0; x < width; ++x)
             {
@@ -358,7 +423,7 @@ namespace PdfSharp.Pdf.Advanced
               if (hasAlpha)
               {
                 mask.AddPel(imageBits[nFileOffset + nOffsetRead + 3]);
-                alphaMask[nOffsetWrite / 3] = imageBits[nFileOffset + nOffsetRead + 3];
+                alphaMask[nOffsetWriteAlpha] = imageBits[nFileOffset + nOffsetRead + 3];
                 if (!hasMask || !hasAlphaMask)
                 {
                   if (imageBits[nFileOffset + nOffsetRead + 3] != 255)
@@ -368,6 +433,7 @@ namespace PdfSharp.Pdf.Advanced
                       hasAlphaMask = true;
                   }
                 }
+                ++nOffsetWriteAlpha;
               }
               nOffsetRead += hasAlpha ? 4 : components;
               nOffsetWrite += 3;
@@ -387,11 +453,11 @@ namespace PdfSharp.Pdf.Advanced
           // monochrome mask is either sufficient or
           // provided for compatibility with older reader versions
           byte[] maskDataCompressed = fd.Encode(mask.MaskData);
-          PdfDictionary pdfMask = new PdfDictionary(this.document);
+          PdfDictionary pdfMask = new PdfDictionary(document);
           pdfMask.Elements.SetName(Keys.Type, "/XObject");
           pdfMask.Elements.SetName(Keys.Subtype, "/Image");
 
-          this.Owner.irefTable.Add(pdfMask);
+          Owner.irefTable.Add(pdfMask);
           pdfMask.Stream = new PdfStream(maskDataCompressed, pdfMask);
           pdfMask.Elements[Keys.Length] = new PdfInteger(maskDataCompressed.Length);
           pdfMask.Elements[Keys.Filter] = new PdfName("/FlateDecode");
@@ -405,11 +471,11 @@ namespace PdfSharp.Pdf.Advanced
         {
           // The image provides an alpha mask (requires Arcrobat 5.0 or higher)
           byte[] alphaMaskCompressed = fd.Encode(alphaMask);
-          PdfDictionary smask = new PdfDictionary(this.document);
+          PdfDictionary smask = new PdfDictionary(document);
           smask.Elements.SetName(Keys.Type, "/XObject");
           smask.Elements.SetName(Keys.Subtype, "/Image");
 
-          this.Owner.irefTable.Add(smask);
+          Owner.irefTable.Add(smask);
           smask.Stream = new PdfStream(alphaMaskCompressed, smask);
           smask.Elements[Keys.Length] = new PdfInteger(alphaMaskCompressed.Length);
           smask.Elements[Keys.Filter] = new PdfName("/FlateDecode");
@@ -451,12 +517,12 @@ namespace PdfSharp.Pdf.Advanced
         } BITMAPINFOHEADER, *PBITMAPINFOHEADER; 
     */
 
-    private void ReadIndexedMemoryBitmap(int bits, ref bool hasAlpha)
+    private void ReadIndexedMemoryBitmap(int bits/*, ref bool hasAlpha*/)
     {
 #if DEBUG_
       image.image.Save("$$$.bmp", ImageFormat.Bmp);
 #endif
-      int pdfVersion = this.Owner.Version;
+      int pdfVersion = Owner.Version;
       int firstMaskColor = -1, lastMaskColor = -1;
       bool segmentedColorMask = false;
 
@@ -465,10 +531,14 @@ namespace PdfSharp.Pdf.Advanced
       image.gdiImage.Save(memory, ImageFormat.Bmp);
 #endif
 #if WPF
+#if !SILVERLIGHT
       // WPFTHHO: StL: keine Ahnung ob das so stimmt.
       BmpBitmapEncoder encoder = new BmpBitmapEncoder();
-      encoder.Frames.Add(BitmapFrame.Create(this.image.wpfImage));
+      encoder.Frames.Add(BitmapFrame.Create(image.wpfImage));
       encoder.Save(memory);
+#else
+      // AGHACK
+#endif
 #endif
       int streamLength = (int)memory.Length;
       Debug.Assert(streamLength > 0, "Bitmap image encoding failed.");
@@ -479,15 +549,16 @@ namespace PdfSharp.Pdf.Advanced
         memory.Read(imageBits, 0, streamLength);
         memory.Close();
 
-        int height = this.image.PixelHeight;
-        int width = this.image.PixelWidth;
+        int height = image.PixelHeight;
+        int width = image.PixelWidth;
 
         if (ReadWord(imageBits, 0) != 0x4d42 || // "BM"
           ReadDWord(imageBits, 2) != streamLength ||
           ReadDWord(imageBits, 14) != 40 || // sizeof BITMAPINFOHEADER
 #if WPF
-          // TODOWPF: bug with height and width
-          false)
+          // TODOWPF: bug with height and width??? With which files???
+          ReadDWord(imageBits, 18) != width ||
+          ReadDWord(imageBits, 22) != height)
 #else
           ReadDWord(imageBits, 18) != width ||
           ReadDWord(imageBits, 22) != height)
@@ -500,6 +571,13 @@ namespace PdfSharp.Pdf.Advanced
         width = ReadDWord(imageBits, 18);
         height = ReadDWord(imageBits, 22);
 #endif
+        int fileBits = ReadWord(imageBits, 28);
+        if (fileBits != bits)
+        {
+          if (fileBits == 1 || fileBits == 4 || fileBits == 8)
+            bits = fileBits;
+        }
+
         if (ReadWord(imageBits, 26) != 1 ||
             ReadWord(imageBits, 28) != bits ||
             ReadDWord(imageBits, 30) != 0)
@@ -517,12 +595,18 @@ namespace PdfSharp.Pdf.Advanced
 
         MonochromeMask mask = new MonochromeMask(width, height);
 
+        bool isGray = bits == 8 && (paletteColors == 256 || paletteColors == 0);
+        int isBitonal = 0; // 0: false; >0: true; <0: true (inverted)
         byte[] paletteData = new byte[3 * paletteColors];
         for (int color = 0; color < paletteColors; ++color)
         {
           paletteData[3 * color] = imageBits[bytesColorPaletteOffset + 4 * color + 2];
           paletteData[3 * color + 1] = imageBits[bytesColorPaletteOffset + 4 * color + 1];
           paletteData[3 * color + 2] = imageBits[bytesColorPaletteOffset + 4 * color + 0];
+          if (isGray)
+            isGray = paletteData[3 * color] == paletteData[3 * color + 1] &&
+              paletteData[3 * color] == paletteData[3 * color + 2];
+
           if (imageBits[bytesColorPaletteOffset + 4 * color + 3] < 128)
           {
             // We treat this as transparency:
@@ -533,9 +617,32 @@ namespace PdfSharp.Pdf.Advanced
             if (lastMaskColor != color)
               segmentedColorMask = true;
           }
-          else
+          //else
+          //{
+          //  // We treat this as opacity:
+          //}
+        }
+
+        if (bits == 1)
+        {
+          if (paletteColors == 0)
+            isBitonal = 1;
+          if (paletteColors == 2)
           {
-            // We treat this as opacity:
+            if (paletteData[0] == 0 &&
+              paletteData[1] == 0 &&
+              paletteData[2] == 0 &&
+              paletteData[3] == 255 &&
+              paletteData[4] == 255 &&
+              paletteData[5] == 255)
+              isBitonal = 1; // Black on white
+            if (paletteData[5] == 0 &&
+              paletteData[4] == 0 &&
+              paletteData[3] == 0 &&
+              paletteData[2] == 255 &&
+              paletteData[1] == 255 &&
+              paletteData[0] == 255)
+              isBitonal = -1; // White on black
           }
         }
 
@@ -544,70 +651,131 @@ namespace PdfSharp.Pdf.Advanced
         // { ... }
 
         FlateDecode fd = new FlateDecode();
-        PdfDictionary colorPalette = new PdfDictionary(this.document);
-        // TODO: decide at run-time if compression makes sense
-#if false
-        // Create uncompressed color palette:
-        colorPalette.CreateStream(paletteData);
-        colorPalette.Elements[Keys.Length] = new PdfInteger(paletteData.Length);
-#else
-        // Create compressed color palette:
-        byte[] packedPaletteData = fd.Encode(paletteData);
-        colorPalette.CreateStream(packedPaletteData);
-        colorPalette.Elements[Keys.Length] = new PdfInteger(packedPaletteData.Length);
-        colorPalette.Elements[Keys.Filter] = new PdfName("/FlateDecode");
-#endif
-        this.Owner.irefTable.Add(colorPalette);
+        PdfDictionary colorPalette = null;
+        if (isBitonal == 0 && !isGray)
+        {
+          colorPalette = new PdfDictionary(this.document);
+          byte[] packedPaletteData = paletteData.Length >= 48 ? fd.Encode(paletteData) : null; // don't compress small palettes
+          if (packedPaletteData != null && packedPaletteData.Length + 20 < paletteData.Length) // +20: compensate for the overhead (estimated value)
+          {
+            // Create compressed color palette:
+            colorPalette.CreateStream(packedPaletteData);
+            colorPalette.Elements[Keys.Length] = new PdfInteger(packedPaletteData.Length);
+            colorPalette.Elements[Keys.Filter] = new PdfName("/FlateDecode");
+          }
+          else
+          {
+            // Create uncompressed color palette:
+            colorPalette.CreateStream(paletteData);
+            colorPalette.Elements[Keys.Length] = new PdfInteger(paletteData.Length);
+          }
+          Owner.irefTable.Add(colorPalette);
+        }
 
-        byte[] imageData = new byte[1 * width * height];
+        bool isFaxEncoding = false;
+        byte[] imageData = new byte[((width * bits + 7) / 8) * height];
+        byte[] imageDataFax = null;
+        int k = 0;
 
-        int bytesOffsetRead = 0;
-        if (bits == 8 || bits == 4 || bits == 1)
+
+        if (bits == 1)
         {
-          int bytesPerLine = (width * bits + 7) / 8;
-          for (int y = 0; y < height; ++y)
+          // TODO: flag/option?
+          // We try Group 3 1D and Group 4 (2D) encoding here and keep the smaller byte array.
+          //byte[] temp = new byte[imageData.Length];
+          //int ccittSize = DoFaxEncoding(ref temp, imageBits, (uint)bytesFileOffset, (uint)width, (uint)height);
+
+          // It seems that Group 3 2D encoding never beats both other encodings, therefore we don't call it here.
+          //byte[] temp2D = new byte[imageData.Length];
+          //uint dpiY = (uint)image.VerticalResolution;
+          //uint kTmp = 0;
+          //int ccittSize2D = DoFaxEncoding2D((uint)bytesFileOffset, ref temp2D, imageBits, (uint)width, (uint)height, dpiY, out kTmp);
+          //k = (int) kTmp;
+
+          byte[] tempG4 = new byte[imageData.Length];
+          int ccittSizeG4 = DoFaxEncodingGroup4(ref tempG4, imageBits, (uint)bytesFileOffset, (uint)width, (uint)height);
+
+          isFaxEncoding = /*ccittSize > 0 ||*/ ccittSizeG4 > 0;
+          if (isFaxEncoding)
           {
-            mask.StartLine(y);
-            int bytesOffsetWrite = (height - 1 - y) * ((width * bits + 7) / 8);
-            for (int x = 0; x < bytesPerLine; ++x)
+            //if (ccittSize == 0)
+            //  ccittSize = 0x7fffffff;
+            if (ccittSizeG4 == 0)
+              ccittSizeG4 = 0x7fffffff;
+            //if (ccittSize <= ccittSizeG4)
+            //{
+            //  Array.Resize(ref temp, ccittSize);
+            //  imageDataFax = temp;
+            //  k = 0;
+            //}
+            //else
             {
-              imageData[bytesOffsetWrite] = imageBits[bytesFileOffset + bytesOffsetRead];
-              if (firstMaskColor != -1)
+              Array.Resize(ref tempG4, ccittSizeG4);
+              imageDataFax = tempG4;
+              k = -1;
+            }
+          }
+        }
+
+        //if (!isFaxEncoding)
+        {
+          int bytesOffsetRead = 0;
+          if (bits == 8 || bits == 4 || bits == 1)
+          {
+            int bytesPerLine = (width * bits + 7) / 8;
+            for (int y = 0; y < height; ++y)
+            {
+              mask.StartLine(y);
+              int bytesOffsetWrite = (height - 1 - y) * ((width * bits + 7) / 8);
+              for (int x = 0; x < bytesPerLine; ++x)
               {
-                int n = imageBits[bytesFileOffset + bytesOffsetRead];
-                if (bits == 8)
+                if (isGray)
                 {
-                  // TODO???: segmentedColorMask == true => falsche Maske NYI
-                  mask.AddPel((n >= firstMaskColor) && (n <= lastMaskColor));
+                  // Lookup the gray value from the palette:
+                  imageData[bytesOffsetWrite] = paletteData[3 * imageBits[bytesFileOffset + bytesOffsetRead]];
                 }
-                else if (bits == 4)
+                else
                 {
-                  // TODO???: segmentedColorMask == true => falsche Maske NYI
-                  int n1 = (n & 0xf0) / 16;
-                  int n2 = (n & 0x0f);
-                  mask.AddPel((n1 >= firstMaskColor) && (n1 <= lastMaskColor));
-                  mask.AddPel((n2 >= firstMaskColor) && (n2 <= lastMaskColor));
+                  // Store the palette index:
+                  imageData[bytesOffsetWrite] = imageBits[bytesFileOffset + bytesOffsetRead];
                 }
-                else if (bits == 1)
+                if (firstMaskColor != -1)
                 {
-                  // TODO???: segmentedColorMask == true => bad mask NYI
-                  for (int bit = 1; bit <= 8; ++bit)
+                  int n = imageBits[bytesFileOffset + bytesOffsetRead];
+                  if (bits == 8)
+                  {
+                    // TODO???: segmentedColorMask == true => bad mask NYI
+                    mask.AddPel((n >= firstMaskColor) && (n <= lastMaskColor));
+                  }
+                  else if (bits == 4)
                   {
-                    int n1 = (n & 0x80) / 128;
+                    // TODO???: segmentedColorMask == true => bad mask NYI
+                    int n1 = (n & 0xf0) / 16;
+                    int n2 = (n & 0x0f);
                     mask.AddPel((n1 >= firstMaskColor) && (n1 <= lastMaskColor));
-                    n *= 2;
+                    mask.AddPel((n2 >= firstMaskColor) && (n2 <= lastMaskColor));
+                  }
+                  else if (bits == 1)
+                  {
+                    // TODO???: segmentedColorMask == true => bad mask NYI
+                    for (int bit = 1; bit <= 8; ++bit)
+                    {
+                      int n1 = (n & 0x80) / 128;
+                      mask.AddPel((n1 >= firstMaskColor) && (n1 <= lastMaskColor));
+                      n *= 2;
+                    }
                   }
                 }
+                bytesOffsetRead += 1;
+                bytesOffsetWrite += 1;
               }
-              bytesOffsetRead += 1;
-              bytesOffsetWrite += 1;
+              bytesOffsetRead = 4 * ((bytesOffsetRead + 3) / 4); // Align to 32 bit boundary
             }
-            bytesOffsetRead = 4 * ((bytesOffsetRead + 3) / 4); // Align to 32 bit boundary
           }
-        }
-        else
-        {
-          throw new NotImplementedException("ReadIndexedMemoryBitmap: unsupported format #3");
+          else
+          {
+            throw new NotImplementedException("ReadIndexedMemoryBitmap: unsupported format #3");
+          }
         }
 
         if (firstMaskColor != -1 &&
@@ -616,7 +784,7 @@ namespace PdfSharp.Pdf.Advanced
           // Color mask requires Reader 4.0 or higher:
           if (!segmentedColorMask && pdfVersion >= 13)
           {
-            PdfArray array = new PdfArray(this.document);
+            PdfArray array = new PdfArray(document);
             array.Elements.Add(new PdfInteger(firstMaskColor));
             array.Elements.Add(new PdfInteger(lastMaskColor));
             Elements[Keys.Mask] = array;
@@ -625,7 +793,7 @@ namespace PdfSharp.Pdf.Advanced
           {
             // Monochrome mask
             byte[] maskDataCompressed = fd.Encode(mask.MaskData);
-            PdfDictionary pdfMask = new PdfDictionary(this.document);
+            PdfDictionary pdfMask = new PdfDictionary(document);
             pdfMask.Elements.SetName(Keys.Type, "/XObject");
             pdfMask.Elements.SetName(Keys.Subtype, "/Image");
 
@@ -642,20 +810,93 @@ namespace PdfSharp.Pdf.Advanced
         }
 
         byte[] imageDataCompressed = fd.Encode(imageData);
+        byte[] imageDataFaxCompressed = isFaxEncoding ? fd.Encode(imageDataFax) : null;
+
+        bool usesCcittEncoding = false;
+        if (isFaxEncoding &&
+          (imageDataFax.Length < imageDataCompressed.Length ||
+          imageDataFaxCompressed.Length < imageDataCompressed.Length))
+        {
+          // /CCITTFaxDecode creates the smaller file (with or without /FlateDecode):
+          usesCcittEncoding = true;
+
+          if (imageDataFax.Length < imageDataCompressed.Length)
+          {
+            Stream = new PdfStream(imageDataFax, this);
+            Elements[Keys.Length] = new PdfInteger(imageDataFax.Length);
+            Elements[Keys.Filter] = new PdfName("/CCITTFaxDecode");
+            //PdfArray array2 = new PdfArray(this.document);
+            PdfDictionary dictionary = new PdfDictionary();
+            if (k != 0)
+              dictionary.Elements.Add("/K", new PdfInteger(k));
+            if (isBitonal < 0)
+              dictionary.Elements.Add("/BlackIs1", new PdfBoolean(true));
+            dictionary.Elements.Add("/EndOfBlock", new PdfBoolean(false));
+            dictionary.Elements.Add("/Columns", new PdfInteger(width));
+            dictionary.Elements.Add("/Rows", new PdfInteger(height));
+            //array2.Elements.Add(dictionary);
+            Elements[Keys.DecodeParms] = dictionary; // array2;
+          }
+          else
+          {
+            Stream = new PdfStream(imageDataFaxCompressed, this);
+            Elements[Keys.Length] = new PdfInteger(imageDataFaxCompressed.Length);
+            PdfArray arrayFilters = new PdfArray(document);
+            arrayFilters.Elements.Add(new PdfName("/FlateDecode"));
+            arrayFilters.Elements.Add(new PdfName("/CCITTFaxDecode"));
+            Elements[Keys.Filter] = arrayFilters;
+            PdfArray arrayDecodeParms = new PdfArray(document);
+
+            PdfDictionary dictFlateDecodeParms = new PdfDictionary();
+            //dictFlateDecodeParms.Elements.Add("/Columns", new PdfInteger(1));
+
+            PdfDictionary dictCcittFaxDecodeParms = new PdfDictionary();
+            if (k != 0)
+              dictCcittFaxDecodeParms.Elements.Add("/K", new PdfInteger(k));
+            if (isBitonal < 0)
+              dictCcittFaxDecodeParms.Elements.Add("/BlackIs1", new PdfBoolean(true));
+            dictCcittFaxDecodeParms.Elements.Add("/EndOfBlock", new PdfBoolean(false));
+            dictCcittFaxDecodeParms.Elements.Add("/Columns", new PdfInteger(width));
+            dictCcittFaxDecodeParms.Elements.Add("/Rows", new PdfInteger(height));
+
+            arrayDecodeParms.Elements.Add(dictFlateDecodeParms); // How to add the "null object"?
+            arrayDecodeParms.Elements.Add(dictCcittFaxDecodeParms);
+            Elements[Keys.DecodeParms] = arrayDecodeParms;
+          }
+        }
+        else
+        {
+          // /FlateDecode creates the smaller file (or no monochrome bitmap):
+          Stream = new PdfStream(imageDataCompressed, this);
+          Elements[Keys.Length] = new PdfInteger(imageDataCompressed.Length);
+          Elements[Keys.Filter] = new PdfName("/FlateDecode");
+        }
 
-        Stream = new PdfStream(imageDataCompressed, this);
-        Elements[Keys.Length] = new PdfInteger(imageDataCompressed.Length);
-        Elements[Keys.Filter] = new PdfName("/FlateDecode");
         Elements[Keys.Width] = new PdfInteger(width);
         Elements[Keys.Height] = new PdfInteger(height);
         Elements[Keys.BitsPerComponent] = new PdfInteger(bits);
-        PdfArray array2 = new PdfArray(this.document);
-        array2.Elements.Add(new PdfName("/Indexed"));
         // TODO: CMYK
-        array2.Elements.Add(new PdfName("/DeviceRGB"));
-        array2.Elements.Add(new PdfInteger(paletteColors - 1));
-        array2.Elements.Add(colorPalette.Reference);
-        Elements[Keys.ColorSpace] = array2;
+
+        // CCITT encoding: we need color palette for isBitonal == 0
+        // FlateDecode: we need color palette for isBitonal <= 0 unless we have grayscales
+        if ((usesCcittEncoding && isBitonal == 0) ||
+          (!usesCcittEncoding && isBitonal <= 0  && !isGray))
+        {
+          PdfArray arrayColorSpace = new PdfArray(document);
+          arrayColorSpace.Elements.Add(new PdfName("/Indexed"));
+          arrayColorSpace.Elements.Add(new PdfName("/DeviceRGB"));
+          arrayColorSpace.Elements.Add(new PdfInteger(paletteColors - 1));
+          // ReSharper disable PossibleNullReferenceException
+          arrayColorSpace.Elements.Add(colorPalette.Reference);
+          // ReSharper restore PossibleNullReferenceException
+          Elements[Keys.ColorSpace] = arrayColorSpace;
+        }
+        else
+        {
+          Elements[Keys.ColorSpace] = new PdfName("/DeviceGray");
+        }
+        if (image.Interpolate)
+          Elements[Keys.Interpolate] = PdfBoolean.True;
       }
     }
 
@@ -773,8 +1014,8 @@ namespace PdfSharp.Pdf.Advanced
       /// source of mask shape or mask opacity values in the transparent imaging model. The alpha 
       /// source parameter in the graphics state determines whether the mask values are interpreted as
       /// shape or opacity. If present, this entry overrides the current soft mask in the graphics state,
-      /// as well as the image?s Mask entry, if any. (However, the other transparencyrelated graphics 
-      /// state parameters?blend mode and alpha constant?remain in effect.) If SMask is absent, the 
+      /// as well as the image?s Mask entry, if any. (However, the other transparency related graphics 
+      /// state parameters ? blend mode and alpha constant ? remain in effect.) If SMask is absent, the 
       /// image has no associated soft mask (although the current soft mask in the graphics state may
       /// still apply).
       /// </summary>
@@ -848,8 +1089,8 @@ namespace PdfSharp.Pdf.Advanced
   /// </summary>
   class MonochromeMask
   {
-    private int sizeX;
-    private int sizeY;
+    private readonly int sizeX;
+    private readonly int sizeY;
     private int writeOffset;
     private int byteBuffer;
     private int bitsWritten;
@@ -861,7 +1102,7 @@ namespace PdfSharp.Pdf.Advanced
     {
       get { return maskData; }
     }
-    private byte[] maskData = null;
+    private readonly byte[] maskData;
 
     /// <summary>
     /// Creates a bitmap mask.
@@ -895,9 +1136,9 @@ namespace PdfSharp.Pdf.Advanced
       {
         // Mask: 0: opaque, 1: transparent (default mapping)
         if (isTransparent)
-          byteBuffer = byteBuffer * 2 + 1;
+          byteBuffer = (byteBuffer << 1) + 1;
         else
-          byteBuffer = byteBuffer * 2;
+          byteBuffer = byteBuffer << 1;
         ++bitsWritten;
         if ((bitsWritten & 7) == 0)
         {
@@ -908,8 +1149,7 @@ namespace PdfSharp.Pdf.Advanced
         else if (bitsWritten == sizeX)
         {
           int n = 8 - (bitsWritten & 7);
-          for (int i = 1; i <= n; ++i)
-            byteBuffer *= 2;
+          byteBuffer = byteBuffer << n;
           maskData[writeOffset] = (byte)byteBuffer;
         }
       }
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfImageTable.cs b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfImageTable.cs
index 5b799b6..ed7ae0c 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfImageTable.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfImageTable.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -29,7 +29,7 @@
 
 using System;
 using System.Diagnostics;
-using System.Collections;
+using System.Collections.Generic;
 using System.Globalization;
 using System.Text;
 using System.IO;
@@ -48,8 +48,7 @@ namespace PdfSharp.Pdf.Advanced
     /// </summary>
     public PdfImageTable(PdfDocument document)
       : base(document)
-    {
-    }
+    { }
 
     /// <summary>
     /// Gets a PdfImage from an XImage. If no PdfImage already exists, a new one is created.
@@ -62,8 +61,8 @@ namespace PdfSharp.Pdf.Advanced
         selector = new ImageSelector(image);
         image.selector = selector;
       }
-      PdfImage pdfImage = this.images[selector] as PdfImage;
-      if (pdfImage == null)
+      PdfImage pdfImage;
+      if (!this.images.TryGetValue(selector, out pdfImage))
       {
         pdfImage = new PdfImage(this.owner, image);
         //pdfImage.Document = this.document;
@@ -82,10 +81,10 @@ namespace PdfSharp.Pdf.Advanced
     /// <summary>
     /// Map from ImageSelector to PdfImage.
     /// </summary>
-    Hashtable images = new Hashtable();
+    readonly Dictionary<ImageSelector, PdfImage> images = new Dictionary<ImageSelector, PdfImage>();
 
     /// <summary>
-    /// A collection of information that uniquely idendifies a particular PdfImage.
+    /// A collection of information that uniquely identifies a particular PdfImage.
     /// </summary>
     public class ImageSelector
     {
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfImportedObjectTable.cs b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfImportedObjectTable.cs
index 5cb161f..0b70c43 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfImportedObjectTable.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfImportedObjectTable.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -28,13 +28,14 @@
 #endregion
 
 using System;
+using System.Collections.Generic;
 using System.Diagnostics;
 using System.Collections;
 using System.Text;
 using System.IO;
 using PdfSharp.Pdf.Advanced;
 using PdfSharp.Drawing;
-using PdfSharp.Fonts.TrueType;
+using PdfSharp.Fonts.OpenType;
 using PdfSharp.Internal;
 
 namespace PdfSharp.Pdf.Advanced
@@ -98,14 +99,14 @@ namespace PdfSharp.Pdf.Advanced
     /// </summary>
     public bool Contains(PdfObjectID externalID)
     {
-      return this.externalIDs.Contains(externalID.ToString());
+      return this.externalIDs.ContainsKey(externalID.ToString());
     }
 
     /// <summary>
     /// Adds a cloned object to this table.
     /// </summary>
-    /// <param name="externalID">The object identifier in the forein object.</param>
-    /// <param name="iref">The cross reference to the clone of the forein object, which belongs to
+    /// <param name="externalID">The object identifier in the foreign object.</param>
+    /// <param name="iref">The cross reference to the clone of the foreign object, which belongs to
     /// this document. In general the clone has a different object identifier.</param>
     public void Add(PdfObjectID externalID, PdfReference iref)
     {
@@ -124,6 +125,6 @@ namespace PdfSharp.Pdf.Advanced
     /// Maps external object identifiers to cross reference entries of the importing document
     /// {PdfObjectID -> PdfReference}.
     /// </summary>
-    Hashtable externalIDs = new Hashtable();
+    Dictionary<string, PdfReference> externalIDs = new Dictionary<string, PdfReference>();
   }
 }
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfInternals.cs b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfInternals.cs
index ba4c7a3..69e75e3 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfInternals.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfInternals.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -41,7 +41,7 @@ namespace PdfSharp.Pdf.Advanced
 {
   /// <summary>
   /// Provides access to the internal document data structures. This class prevents the public
-  /// interfaces from pollution with internal functions.
+  /// interfaces from pollution with to much internal functions.
   /// </summary>
   public class PdfInternals  // TODO: PdfDocumentInternals... PdfPageInterals etc.
   {
@@ -157,17 +157,23 @@ namespace PdfSharp.Pdf.Advanced
     /// <summary>
     /// Gets all indirect objects ordered by their object identifier.
     /// </summary>
+    public PdfObject[] GetAllObjects()
+    {
+      PdfReference[] irefs = this.document.irefTable.AllReferences;
+      int count = irefs.Length;
+      PdfObject[] objects = new PdfObject[count];
+      for (int idx = 0; idx < count; idx++)
+        objects[idx] = irefs[idx].Value;
+      return objects;
+    }
+
+    /// <summary>
+    /// Gets all indirect objects ordered by their object identifier.
+    /// </summary>
+    [Obsolete("Use GetAllObjects.")]  // Properties should not return arrays
     public PdfObject[] AllObjects
     {
-      get
-      {
-        PdfReference[] irefs = this.document.irefTable.AllReferences;
-        int count = irefs.Length;
-        PdfObject[] objects = new PdfObject[count];
-        for (int idx = 0; idx < count; idx++)
-          objects[idx] = irefs[idx].Value;
-        return objects;
-      }
+      get { return GetAllObjects(); }
     }
 
     /// <summary>
@@ -226,9 +232,18 @@ namespace PdfSharp.Pdf.Advanced
     /// as long as no new objects came along. This is e.g. useful for getting all objects belonging 
     /// to the resources of a page.
     /// </summary>
-    public PdfObject[] GetClosure(PdfObject obj) // TODO: "..., bool transitive)"
+    public PdfObject[] GetClosure(PdfObject obj)
+    {
+      return GetClosure(obj, Int32.MaxValue);
+    }
+
+    /// <summary>
+    /// Returns an array containing the specified object as first element follows by its transitive
+    /// closure limited by the specified number of iterations.
+    /// </summary>
+    public PdfObject[] GetClosure(PdfObject obj, int depth)
     {
-      PdfReference[] references = this.document.irefTable.TransitiveClosure(obj);
+      PdfReference[] references = this.document.irefTable.TransitiveClosure(obj, depth);
       int count = references.Length + 1;
       PdfObject[] objects = new PdfObject[count];
       objects[0] = obj;
@@ -250,7 +265,7 @@ namespace PdfSharp.Pdf.Advanced
     }
 
     /// <summary>
-    /// The name of the custuom value key.
+    /// The name of the custom value key.
     /// </summary>
     public string CustomValueKey = "/PdfSharp.CustomValue";
   }
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfObjectInternals.cs b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfObjectInternals.cs
new file mode 100644
index 0000000..ff07a52
--- /dev/null
+++ b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfObjectInternals.cs
@@ -0,0 +1,94 @@
+#region PDFsharp - A .NET library for processing PDF
+//
+// Authors:
+//   Stefan Lange (mailto:Stefan Lange pdfsharp com)
+//
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
+//
+// http://www.pdfsharp.com
+// http://sourceforge.net/projects/pdfsharp
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+// DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Diagnostics;
+using System.Collections;
+using System.Reflection;
+using System.Text;
+using System.IO;
+using PdfSharp.Internal;
+using PdfSharp.Pdf;
+using PdfSharp.Pdf.IO;
+
+namespace PdfSharp.Pdf.Advanced
+{
+  /// <summary>
+  /// Provides access to the internal PDF object data structures. This class prevents the public
+  /// interfaces from pollution with to much internal functions.
+  /// </summary>
+  public class PdfObjectInternals
+  {
+    internal PdfObjectInternals(PdfObject obj)
+    {
+      this.obj = obj;
+    }
+    PdfObject obj;
+
+    /// <summary>
+    /// Gets the object identifier. Returns PdfObjectID.Empty for direct objects.
+    /// </summary>
+    public PdfObjectID ObjectID
+    {
+      get { return this.obj.ObjectID; }
+    }
+
+    /// <summary>
+    /// Gets the object number.
+    /// </summary>
+    public int ObjectNumber
+    {
+      get { return this.obj.ObjectID.ObjectNumber; }
+    }
+
+    /// <summary>
+    /// Gets the generation number.
+    /// </summary>
+    public int GenerationNumber
+    {
+      get { return this.obj.ObjectID.GenerationNumber; }
+    }
+
+    /// <summary>
+    /// Gets the name of the current type.
+    /// Not a very useful property, but can be used for data binding.
+    /// </summary>
+    public string TypeID
+    {
+      get
+      {
+        if (this.obj is PdfArray)
+          return "array";
+        else if (this.obj is PdfDictionary)
+          return "dictionary";
+        return this.obj.GetType().Name;
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfPageInheritableObjects.cs b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfPageInheritableObjects.cs
index 835397d..bf79e16 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfPageInheritableObjects.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfPageInheritableObjects.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfReference.cs b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfReference.cs
index 1bce12e..ad4a094 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfReference.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfReference.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -31,6 +31,7 @@
 #define UNIQUE_IREF
 
 using System;
+using System.Collections.Generic;
 using System.Diagnostics;
 using System.Collections;
 using System.Text;
@@ -174,6 +175,8 @@ namespace PdfSharp.Pdf.Advanced
       get { return this.value; }
       set
       {
+        Debug.Assert(value != null, "The value of a PdfReference must never be null.");
+        Debug.Assert(value.Reference == null || Object.ReferenceEquals(value.Reference, this), "The reference of the value must be null or this.");
         this.value = value;
         // value must never be null
         value.Reference = this;
@@ -215,12 +218,12 @@ namespace PdfSharp.Pdf.Advanced
     /// <summary>
     /// Implements a comparer that compares PdfReference objects by their PdfObjectID.
     /// </summary>
-    internal class PdfReferenceComparer : IComparer
+    internal class PdfReferenceComparer : IComparer<PdfReference>
     {
-      public int Compare(object x, object y)
+      public int Compare(PdfReference x, PdfReference y)
       {
-        PdfReference l = x as PdfReference;
-        PdfReference r = y as PdfReference;
+        PdfReference l = x; // as PdfReference;
+        PdfReference r = y; // as PdfReference;
         if (l != null)
         {
           if (r != null)
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfResourceMap.cs b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfResourceMap.cs
index 01d5cfd..364c403 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfResourceMap.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfResourceMap.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -30,6 +30,7 @@
 using System;
 using System.Diagnostics;
 using System.Collections;
+using System.Collections.Generic;
 
 namespace PdfSharp.Pdf.Advanced
 {
@@ -64,12 +65,12 @@ namespace PdfSharp.Pdf.Advanced
     /// <summary>
     /// Adds all imported resource names to the specified hashtable.
     /// </summary>
-    internal void CollectResourceNames(Hashtable usedResourceNames)
+    internal void CollectResourceNames(Dictionary<string, object> usedResourceNames)
     {
-      // ?TODO: Imported resources (e.g. fonts) can be reused, but I think this is rather difficult.
+      // ?TODO: Imported resources (e.g. fonts) can be reused, but I think this is rather difficult. Will be an issue in PDFsharp 2.0.
       PdfName[] names = Elements.KeyNames;
       foreach (PdfName name in names)
-        usedResourceNames.Add(name, null);
+        usedResourceNames.Add(name.ToString(), null);
     }
   }
 }
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfResourceTable.cs b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfResourceTable.cs
index 314fa24..d432af4 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfResourceTable.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfResourceTable.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -34,7 +34,7 @@ using System.Text;
 using System.IO;
 using PdfSharp.Drawing;
 using PdfSharp.Internal;
-using PdfSharp.Fonts.TrueType;
+using PdfSharp.Fonts.OpenType;
 
 namespace PdfSharp.Pdf.Advanced
 {
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfResources.cs b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfResources.cs
index 0656636..037dac4 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfResources.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfResources.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -28,7 +28,7 @@
 #endregion
 
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using System.Text;
 using System.IO;
 using PdfSharp.Internal;
@@ -57,23 +57,22 @@ namespace PdfSharp.Pdf.Advanced
       Elements[Keys.ProcSet] = new PdfLiteral("[/PDF/Text/ImageB/ImageC/ImageI]");
     }
 
-    PdfResources(PdfDictionary dict)
+    internal PdfResources(PdfDictionary dict)
       : base(dict)
-    {
-    }
+    { }
 
     /// <summary>
     /// Adds the specified font to this resource dictionary and returns its local resource name.
     /// </summary>
     public string AddFont(PdfFont font)
     {
-      string name = (string)this.resources[font];
-      if (name == null)
+      string name;
+      if (!this.resources.TryGetValue(font, out name))
       {
         name = NextFontName;
         this.resources[font] = name;
         if (font.Reference == null)
-          this.Owner.irefTable.Add(font);
+          Owner.irefTable.Add(font);
         Fonts.Elements[name] = font.Reference;
       }
       return name;
@@ -85,13 +84,13 @@ namespace PdfSharp.Pdf.Advanced
     /// </summary>
     public string AddImage(PdfImage image)
     {
-      string name = (string)this.resources[image];
-      if (name == null)
+      string name;
+      if (!this.resources.TryGetValue(image, out name))
       {
         name = NextImageName;
         this.resources[image] = name;
         if (image.Reference == null)
-          this.Owner.irefTable.Add(image);
+          Owner.irefTable.Add(image);
         XObjects.Elements[name] = image.Reference;
       }
       return name;
@@ -103,13 +102,13 @@ namespace PdfSharp.Pdf.Advanced
     /// </summary>
     public string AddForm(PdfFormXObject form)
     {
-      string name = (string)this.resources[form];
-      if (name == null)
+      string name;
+      if (!this.resources.TryGetValue(form, out name))
       {
         name = NextFormName;
         this.resources[form] = name;
         if (form.Reference == null)
-          this.Owner.irefTable.Add(form);
+          Owner.irefTable.Add(form);
         XObjects.Elements[name] = form.Reference;
       }
       return name;
@@ -121,13 +120,13 @@ namespace PdfSharp.Pdf.Advanced
     /// </summary>
     public string AddExtGState(PdfExtGState extGState)
     {
-      string name = (string)this.resources[extGState];
-      if (name == null)
+      string name;
+      if (!this.resources.TryGetValue(extGState, out name))
       {
         name = NextExtGStateName;
         this.resources[extGState] = name;
         if (extGState.Reference == null)
-          this.Owner.irefTable.Add(extGState);
+          Owner.irefTable.Add(extGState);
         ExtGStates.Elements[name] = extGState.Reference;
       }
       return name;
@@ -139,13 +138,13 @@ namespace PdfSharp.Pdf.Advanced
     /// </summary>
     public string AddPattern(PdfShadingPattern pattern)
     {
-      string name = (string)this.resources[pattern];
-      if (name == null)
+      string name;
+      if (!this.resources.TryGetValue(pattern, out name))
       {
         name = NextPatternName;
         this.resources[pattern] = name;
         if (pattern.Reference == null)
-          this.Owner.irefTable.Add(pattern);
+          Owner.irefTable.Add(pattern);
         Patterns.Elements[name] = pattern.Reference;
       }
       return name;
@@ -157,13 +156,13 @@ namespace PdfSharp.Pdf.Advanced
     /// </summary>
     public string AddPattern(PdfTilingPattern pattern)
     {
-      string name = (string)this.resources[pattern];
-      if (name == null)
+      string name;
+      if (!this.resources.TryGetValue(pattern, out name))
       {
         name = NextPatternName;
         this.resources[pattern] = name;
         if (pattern.Reference == null)
-          this.Owner.irefTable.Add(pattern);
+          Owner.irefTable.Add(pattern);
         Patterns.Elements[name] = pattern.Reference;
       }
       return name;
@@ -175,13 +174,13 @@ namespace PdfSharp.Pdf.Advanced
     /// </summary>
     public string AddShading(PdfShading shading)
     {
-      string name = (string)this.resources[shading];
-      if (name == null)
+      string name;
+      if (!this.resources.TryGetValue(shading, out name))
       {
         name = NextShadingName;
         this.resources[shading] = name;
         if (shading.Reference == null)
-          this.Owner.irefTable.Add(shading);
+          Owner.irefTable.Add(shading);
         Shadings.Elements[name] = shading.Reference;
       }
       return name;
@@ -373,7 +372,7 @@ namespace PdfSharp.Pdf.Advanced
       // Collect all resouce names of all imported resources.
       if (this.importedResourceNames == null)
       {
-        this.importedResourceNames = new Hashtable();
+        this.importedResourceNames = new Dictionary<string, object>();
 
         if (Elements[Keys.Font] != null)
           Fonts.CollectResourceNames(this.importedResourceNames);
@@ -396,7 +395,7 @@ namespace PdfSharp.Pdf.Advanced
         if (Elements[Keys.Properties] != null)
           Properties.CollectResourceNames(this.importedResourceNames);
       }
-      return this.importedResourceNames.Contains(name);
+      return this.importedResourceNames.ContainsKey(name);
       // This is superfluous because PDFsharp resource names cannot be double.
       // this.importedResourceNames.Add(name, null);
     }
@@ -404,12 +403,12 @@ namespace PdfSharp.Pdf.Advanced
     /// <summary>
     /// All the names of imported resources.
     /// </summary>
-    Hashtable importedResourceNames;
+    Dictionary<string, object> importedResourceNames;
 
     /// <summary>
     /// Maps all PDFsharp resources to their local resource names.
     /// </summary>
-    readonly Hashtable resources = new Hashtable();
+    readonly Dictionary<PdfObject, string> resources = new Dictionary<PdfObject, string>();
 
     /// <summary>
     /// Predefined keys of this dictionary.
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfShading.cs b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfShading.cs
index 8ebc627..8574e2a 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfShading.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfShading.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -41,7 +41,7 @@ using System.Drawing.Imaging;
 using System.Windows.Media;
 #endif
 using PdfSharp.Drawing;
-using PdfSharp.Fonts.TrueType;
+using PdfSharp.Fonts.OpenType;
 using PdfSharp.Internal;
 using PdfSharp.Pdf.Internal;
 
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfShadingPattern.cs b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfShadingPattern.cs
index 655fdb8..b1f9270 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfShadingPattern.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfShadingPattern.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -40,7 +40,7 @@ using System.Drawing.Imaging;
 using System.Windows.Media;
 #endif
 using PdfSharp.Drawing;
-using PdfSharp.Fonts.TrueType;
+using PdfSharp.Fonts.OpenType;
 using PdfSharp.Internal;
 using PdfSharp.Pdf.Internal;
 
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfShadingTable.cs b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfShadingTable.cs
index caa9f17..7335f90 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfShadingTable.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfShadingTable.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfSoftMask.cs b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfSoftMask.cs
index 49b2360..d1a5bef 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfSoftMask.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfSoftMask.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -40,7 +40,7 @@ using System.Drawing.Imaging;
 using System.Windows.Media;
 #endif
 using PdfSharp.Drawing;
-using PdfSharp.Fonts.TrueType;
+using PdfSharp.Fonts.OpenType;
 using PdfSharp.Internal;
 
 namespace PdfSharp.Pdf.Advanced
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfTilingPattern.cs b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfTilingPattern.cs
index 7e3e5ce..88f8b48 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfTilingPattern.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfTilingPattern.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -40,7 +40,7 @@ using System.Drawing.Imaging;
 using System.Windows.Media;
 #endif
 using PdfSharp.Drawing;
-using PdfSharp.Fonts.TrueType;
+using PdfSharp.Fonts.OpenType;
 using PdfSharp.Internal;
 using PdfSharp.Pdf.Internal;
 
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfToUnicodeMap.cs b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfToUnicodeMap.cs
index 664d192..f6a7c21 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfToUnicodeMap.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfToUnicodeMap.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -36,7 +36,7 @@ using System.IO;
 using PdfSharp.Drawing;
 using PdfSharp.Internal;
 using PdfSharp.Fonts;
-using PdfSharp.Fonts.TrueType;
+using PdfSharp.Fonts.OpenType;
 using PdfSharp.Pdf.Advanced;
 using PdfSharp.Pdf.Filters;
 
@@ -84,7 +84,7 @@ namespace PdfSharp.Pdf.Advanced
         "/CMapName /Adobe-Identity-UCS def /CMapType 2 def\n";
       string suffix = "endcmap CMapName currentdict /CMap defineresource pop end end";
 
-      Hashtable glyphIndexToCharacter = new Hashtable();
+      Dictionary<int, char> glyphIndexToCharacter = new Dictionary<int, char>();
       int lowIndex = 65536, hiIndex = -1;
       foreach (KeyValuePair<char, int> entry in this.cmapInfo.CharacterToGlyphIndex)
       {
@@ -96,7 +96,11 @@ namespace PdfSharp.Pdf.Advanced
       }
 
       MemoryStream ms = new MemoryStream();
+#if !SILVERLIGHT
       StreamWriter wrt = new StreamWriter(ms, Encoding.ASCII);
+#else
+      StreamWriter wrt = new StreamWriter(ms, Encoding.UTF8);
+#endif
 
       wrt.Write(prefix);
 
@@ -106,8 +110,8 @@ namespace PdfSharp.Pdf.Advanced
 
       // Sorting seems not necessary. The limit is 100 entries, we will see.
       wrt.WriteLine(String.Format("{0} beginbfrange", glyphIndexToCharacter.Count));
-      foreach (DictionaryEntry entry in glyphIndexToCharacter)
-        wrt.WriteLine(String.Format("<{0:X4}><{0:X4}><{1:X4}>", (int)entry.Key, (int)(char)entry.Value));
+      foreach (KeyValuePair<int, char> entry in glyphIndexToCharacter)
+        wrt.WriteLine(String.Format("<{0:X4}><{0:X4}><{1:X4}>", entry.Key, (int)entry.Value));
       wrt.WriteLine("endbfrange");
 
       wrt.Write(suffix);
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfTrailer.cs b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfTrailer.cs
index 993744f..6d4c306 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfTrailer.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfTrailer.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -64,7 +64,7 @@ namespace PdfSharp.Pdf.Advanced
 
     public PdfDocumentInformation Info
     {
-      get {return (PdfDocumentInformation)Elements.GetValue(PdfTrailer.Keys.Info, VCF.CreateIndirect);}
+      get {return (PdfDocumentInformation)Elements.GetValue(Keys.Info, VCF.CreateIndirect);}
     }
 
     /// <summary>
@@ -77,7 +77,7 @@ namespace PdfSharp.Pdf.Advanced
     }
 
     /// <summary>
-    /// Gets the first or secound document identifier.
+    /// Gets the first or second document identifier.
     /// </summary>
     public string GetDocumentID(int index)
     {
@@ -94,7 +94,7 @@ namespace PdfSharp.Pdf.Advanced
     }
 
     /// <summary>
-    /// Sets the first or secound document identifier.
+    /// Sets the first or second document identifier.
     /// </summary>
     public void SetDocumentID(int index, string value)
     {
@@ -113,7 +113,8 @@ namespace PdfSharp.Pdf.Advanced
     internal PdfArray CreateNewDocumentIDs()
     {
       PdfArray array = new PdfArray(this.document);
-      string id = PdfEncoders.RawEncoding.GetString(Guid.NewGuid().ToByteArray());
+      byte[] docID = Guid.NewGuid().ToByteArray();
+      string id = PdfEncoders.RawEncoding.GetString(docID, 0, docID.Length);
       array.Elements.Add(new PdfString(id, PdfStringFlags.HexLiteral));
       array.Elements.Add(new PdfString(id, PdfStringFlags.HexLiteral));
       Elements[Keys.ID] = array;
@@ -128,7 +129,7 @@ namespace PdfSharp.Pdf.Advanced
       get 
       {
         if (this.securityHandler == null)
-          this.securityHandler = (PdfStandardSecurityHandler)Elements.GetValue(PdfTrailer.Keys.Encrypt, VCF.CreateIndirect);
+          this.securityHandler = (PdfStandardSecurityHandler)Elements.GetValue(Keys.Encrypt, VCF.CreateIndirect);
         return this.securityHandler;
       }
     }
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfTransparencyGroupAttributes.cs b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfTransparencyGroupAttributes.cs
index adfd381..d6b54fc 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfTransparencyGroupAttributes.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfTransparencyGroupAttributes.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -40,7 +40,7 @@ using System.Drawing.Imaging;
 using System.Windows.Media;
 #endif
 using PdfSharp.Drawing;
-using PdfSharp.Fonts.TrueType;
+using PdfSharp.Fonts.OpenType;
 using PdfSharp.Internal;
 using PdfSharp.Pdf.Internal;
 
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfTrueTypeFont.cs b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfTrueTypeFont.cs
index 467203d..1f3f875 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfTrueTypeFont.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfTrueTypeFont.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -35,7 +35,7 @@ using System.IO;
 using PdfSharp.Drawing;
 using PdfSharp.Internal;
 using PdfSharp.Fonts;
-using PdfSharp.Fonts.TrueType;
+using PdfSharp.Fonts.OpenType;
 using PdfSharp.Pdf.Advanced;
 using PdfSharp.Pdf.Filters;
 
@@ -61,7 +61,7 @@ namespace PdfSharp.Pdf.Advanced
       Elements.SetName(Keys.Subtype, "/TrueType");
 
       // TrueType with WinAnsiEncoding only
-      TrueTypeDescriptor ttDescriptor = (TrueTypeDescriptor)FontDescriptorStock.Global.CreateDescriptor(font);
+      OpenTypeDescriptor ttDescriptor = (OpenTypeDescriptor)FontDescriptorStock.Global.CreateDescriptor(font);
       this.fontDescriptor = new PdfFontDescriptor(document, ttDescriptor);
       this.fontOptions = font.PdfOptions;
       Debug.Assert(this.fontOptions != null);
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfType0Font.cs b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfType0Font.cs
index 89c49c1..0e8ffdd 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfType0Font.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfType0Font.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -35,7 +35,7 @@ using System.IO;
 using PdfSharp.Drawing;
 using PdfSharp.Internal;
 using PdfSharp.Fonts;
-using PdfSharp.Fonts.TrueType;
+using PdfSharp.Fonts.OpenType;
 using PdfSharp.Pdf.Advanced;
 using PdfSharp.Pdf.Filters;
 
@@ -51,14 +51,14 @@ namespace PdfSharp.Pdf.Advanced
     {
     }
 
-    public PdfType0Font(PdfDocument document, XFont font)
+    public PdfType0Font(PdfDocument document, XFont font, bool vertical)
       : base(document)
     {
       Elements.SetName(Keys.Type, "/Font");
       Elements.SetName(Keys.Subtype, "/Type0");
-      Elements.SetName(Keys.Encoding, "/Identity-H");
+      Elements.SetName(Keys.Encoding, vertical ? "/Identity-V" : "/Identity-H");
 
-      TrueTypeDescriptor ttDescriptor = (TrueTypeDescriptor)FontDescriptorStock.Global.CreateDescriptor(font);
+      OpenTypeDescriptor ttDescriptor = (OpenTypeDescriptor)FontDescriptorStock.Global.CreateDescriptor(font);
       this.fontDescriptor = new PdfFontDescriptor(document, ttDescriptor);
       this.fontOptions = font.PdfOptions;
       Debug.Assert(this.fontOptions != null);
@@ -106,14 +106,14 @@ namespace PdfSharp.Pdf.Advanced
       Elements[Keys.DescendantFonts] = descendantFonts;
     }
 
-    public PdfType0Font(PdfDocument document, string idName, byte[] fontData)
+    public PdfType0Font(PdfDocument document, string idName, byte[] fontData, bool vertical)
       : base(document)
     {
       Elements.SetName(Keys.Type, "/Font");
       Elements.SetName(Keys.Subtype, "/Type0");
-      Elements.SetName(Keys.Encoding, "/Identity-H");
+      Elements.SetName(Keys.Encoding, vertical ? "/Identity-V" : "/Identity-H");
 
-      TrueTypeDescriptor ttDescriptor = (TrueTypeDescriptor)FontDescriptorStock.Global.CreateDescriptor(idName, fontData);
+      OpenTypeDescriptor ttDescriptor = (OpenTypeDescriptor)FontDescriptorStock.Global.CreateDescriptor(idName, fontData);
       this.fontDescriptor = new PdfFontDescriptor(document, ttDescriptor);
       this.fontOptions = new XPdfFontOptions(PdfFontEncoding.Unicode, PdfFontEmbedding.Always);
       Debug.Assert(this.fontOptions != null);
@@ -144,7 +144,7 @@ namespace PdfSharp.Pdf.Advanced
         //}
 
       // CID fonts are always embedded
-      if (!BaseFont.Contains("+"))  // HACK
+      if (!BaseFont.Contains("+"))  // HACK in PdfType0Font
         BaseFont = PdfFont.CreateEmbeddedFontSubsetName(BaseFont);
 
       this.fontDescriptor.FontName = BaseFont;
@@ -178,6 +178,26 @@ namespace PdfSharp.Pdf.Advanced
     {
       base.PrepareForSave();
 
+#if true
+      // use GetGlyphIndices to create the widths array
+      OpenTypeDescriptor descriptor = (OpenTypeDescriptor)this.fontDescriptor.descriptor;
+      StringBuilder w = new StringBuilder("[");
+      if (this.cmapInfo != null)
+      {
+        int[] glyphIndices = this.cmapInfo.GetGlyphIndices();
+        int count = glyphIndices.Length;
+        int[] glyphWidths = new int[count];
+
+        for (int idx = 0; idx < count; idx++)
+          glyphWidths[idx] = descriptor.GlyphIndexToPdfWidth(glyphIndices[idx]);
+
+        //TODO: optimize order of indices
+
+        for (int idx = 0; idx < count; idx++)
+          w.AppendFormat("{0}[{1}]", glyphIndices[idx], glyphWidths[idx]);
+        w.Append("]");
+        this.descendantFont.Elements.SetValue(PdfCIDFont.Keys.W, new PdfLiteral(w.ToString()));
+#else
       TrueTypeDescriptor descriptor = (TrueTypeDescriptor)this.fontDescriptor.descriptor;
       bool symbol = descriptor.fontData.cmap.symbol;
       StringBuilder w = new StringBuilder("[");
@@ -212,6 +232,7 @@ namespace PdfSharp.Pdf.Advanced
           w.AppendFormat("{0}[{1}]", glyphIndices[idx], glyphWidths[idx]);
         w.Append("]");
         this.descendantFont.Elements.SetValue(PdfCIDFont.Keys.W, new PdfLiteral(w.ToString()));
+#endif
       }
 
       this.descendantFont.PrepareForSave();
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfType1Font.cs b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfType1Font.cs
index 1ba4e80..cb287ad 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfType1Font.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfType1Font.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfXObject.cs b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfXObject.cs
index 532bc89..c124556 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfXObject.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Advanced/PdfXObject.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -40,7 +40,7 @@ using System.Drawing.Imaging;
 using System.Windows.Media;
 #endif
 using PdfSharp.Drawing;
-using PdfSharp.Fonts.TrueType;
+using PdfSharp.Fonts.OpenType;
 using PdfSharp.Internal;
 
 namespace PdfSharp.Pdf.Advanced
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Annotations/PdfAnnotation.cs b/lib/PdfSharp/PdfSharp.Pdf.Annotations/PdfAnnotation.cs
index 53fa66c..bb8da13 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Annotations/PdfAnnotation.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Annotations/PdfAnnotation.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -98,7 +98,7 @@ namespace PdfSharp.Pdf.Annotations
     }
 
     /// <summary>
-    /// Gets or sets the PdfAnnotations object that this annoation belongs to.
+    /// Gets or sets the PdfAnnotations object that this annotation belongs to.
     /// </summary>
     public PdfAnnotations Parent
     {
@@ -209,7 +209,7 @@ namespace PdfSharp.Pdf.Annotations
     {
       get
       {
-        if (!Elements.Contains(Keys.CA))
+        if (!Elements.ContainsKey(Keys.CA))
           return 1;
         return Elements.GetReal(Keys.CA, true);
       }
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Annotations/PdfAnnotations.cs b/lib/PdfSharp/PdfSharp.Pdf.Annotations/PdfAnnotations.cs
index cb5dee3..b430af4 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Annotations/PdfAnnotations.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Annotations/PdfAnnotations.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -34,6 +34,7 @@ using System.Text;
 using System.IO;
 using PdfSharp.Pdf.Advanced;
 using PdfSharp.Pdf.IO;
+using System.Collections.Generic;
 
 namespace PdfSharp.Pdf.Annotations
 {
@@ -91,7 +92,7 @@ namespace PdfSharp.Pdf.Annotations
     //}
 
     /// <summary>
-    /// Gets the number of annoations in this collection.
+    /// Gets the number of annotations in this collection.
     /// </summary>
     public int Count
     {
@@ -164,10 +165,10 @@ namespace PdfSharp.Pdf.Annotations
       if (annots != null)
       {
         int count = annots.Elements.Count;
-        for (int idx=0;idx<count;idx++)
+        for (int idx = 0; idx < count; idx++)
         {
           PdfDictionary annot = annots.Elements.GetDictionary(idx);
-          if (annot != null && annot.Elements.Contains("/P"))
+          if (annot != null && annot.Elements.ContainsKey("/P"))
             annot.Elements["/P"] = page.Reference;
         }
       }
@@ -176,12 +177,12 @@ namespace PdfSharp.Pdf.Annotations
     /// <summary>
     /// Returns an enumerator that iterates through a collection.
     /// </summary>
-    public override IEnumerator GetEnumerator()
+    public override IEnumerator<PdfItem> GetEnumerator()
     {
-      return new AnnotationsIterator(this);
+      return (IEnumerator<PdfItem>)new AnnotationsIterator(this);
     }
 
-    class AnnotationsIterator : IEnumerator
+    class AnnotationsIterator : IEnumerator<PdfAnnotation>
     {
       PdfAnnotations annotations;
       int index;
@@ -192,11 +193,16 @@ namespace PdfSharp.Pdf.Annotations
         this.index = -1;
       }
 
-      public object Current
+      public PdfAnnotation Current
       {
         get { return this.annotations[this.index]; }
       }
 
+      object IEnumerator.Current
+      {
+        get { return Current; }
+      }
+
       public bool MoveNext()
       {
         return ++this.index < this.annotations.Count;
@@ -206,6 +212,11 @@ namespace PdfSharp.Pdf.Annotations
       {
         this.index = -1;
       }
+
+      public void Dispose()
+      {
+        //throw new NotImplementedException();
+      }
     }
   }
 }
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Annotations/PdfGenericAnnotation.cs b/lib/PdfSharp/PdfSharp.Pdf.Annotations/PdfGenericAnnotation.cs
index bae5bf0..603efee 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Annotations/PdfGenericAnnotation.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Annotations/PdfGenericAnnotation.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Annotations/PdfLinkAnnotation.cs b/lib/PdfSharp/PdfSharp.Pdf.Annotations/PdfLinkAnnotation.cs
index ef1afe0..40b90d4 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Annotations/PdfLinkAnnotation.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Annotations/PdfLinkAnnotation.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -70,19 +70,18 @@ namespace PdfSharp.Pdf.Annotations
     /// Creates a link within the current document.
     /// </summary>
     /// <param name="rect">The link area in default page coordinates.</param>
-    /// <param name="destinatinPage">The one-based destination page number.</param>
-    /// <returns></returns>
-    public static PdfLinkAnnotation CreateDocumentLink(PdfRectangle rect, int destinatinPage)
+    /// <param name="destinationPage">The one-based destination page number.</param>
+    public static PdfLinkAnnotation CreateDocumentLink(PdfRectangle rect, int destinationPage)
     {
       PdfLinkAnnotation link = new PdfLinkAnnotation();
       link.linkType = PdfLinkAnnotation.LinkType.Document;
       link.Rectangle = rect;
-      link.destPage = destinatinPage;
+      link.destPage = destinationPage;
       return link;
     }
     int destPage;
-    LinkType linkType; // HACK
-    string url; // HACK
+    LinkType linkType;
+    string url;
 
     /// <summary>
     /// Creates a link to the web.
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Annotations/PdfRubberStampAnnotation.cs b/lib/PdfSharp/PdfSharp.Pdf.Annotations/PdfRubberStampAnnotation.cs
index 4f9fe19..26f1070 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Annotations/PdfRubberStampAnnotation.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Annotations/PdfRubberStampAnnotation.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -81,7 +81,7 @@ namespace PdfSharp.Pdf.Annotations
         value = value.Substring(1);
         if (!Enum.IsDefined(typeof(PdfRubberStampAnnotationIcon), value))
           return PdfRubberStampAnnotationIcon.NoIcon;
-        return (PdfRubberStampAnnotationIcon)Enum.Parse(typeof(PdfRubberStampAnnotationIcon), value);
+        return (PdfRubberStampAnnotationIcon)Enum.Parse(typeof(PdfRubberStampAnnotationIcon), value, false);
       }
       set
       {
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Annotations/PdfTextAnnotation.cs b/lib/PdfSharp/PdfSharp.Pdf.Annotations/PdfTextAnnotation.cs
index 80453f5..f8e83ff 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Annotations/PdfTextAnnotation.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Annotations/PdfTextAnnotation.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -100,7 +100,7 @@ namespace PdfSharp.Pdf.Annotations
         value = value.Substring(1);
         if (!Enum.IsDefined(typeof(PdfTextAnnotationIcon), value))
           return PdfTextAnnotationIcon.NoIcon;
-        return (PdfTextAnnotationIcon)Enum.Parse(typeof(PdfTextAnnotationIcon), value);
+        return (PdfTextAnnotationIcon)Enum.Parse(typeof(PdfTextAnnotationIcon), value, false);
       }
       set
       {
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Annotations/PdfWidgetAnnotation.cs b/lib/PdfSharp/PdfSharp.Pdf.Annotations/PdfWidgetAnnotation.cs
index 054101c..373075a 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Annotations/PdfWidgetAnnotation.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Annotations/PdfWidgetAnnotation.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Annotations/enums/PdfAnnotationFlags.cs b/lib/PdfSharp/PdfSharp.Pdf.Annotations/enums/PdfAnnotationFlags.cs
index 15b27a1..384edf0 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Annotations/enums/PdfAnnotationFlags.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Annotations/enums/PdfAnnotationFlags.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Annotations/enums/PdfRubberStampAnnotationIcon.cs b/lib/PdfSharp/PdfSharp.Pdf.Annotations/enums/PdfRubberStampAnnotationIcon.cs
index 48967c6..dde8bd3 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Annotations/enums/PdfRubberStampAnnotationIcon.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Annotations/enums/PdfRubberStampAnnotationIcon.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Annotations/enums/PdfTextAnnotationIcon.cs b/lib/PdfSharp/PdfSharp.Pdf.Annotations/enums/PdfTextAnnotationIcon.cs
index cd5863d..3a4eaee 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Annotations/enums/PdfTextAnnotationIcon.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Annotations/enums/PdfTextAnnotationIcon.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Content.Objects/CObjects.cs b/lib/PdfSharp/PdfSharp.Pdf.Content.Objects/CObjects.cs
index 41da937..375f90a 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Content.Objects/CObjects.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Content.Objects/CObjects.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -28,6 +28,7 @@
 #endregion
 
 using System;
+using System.Collections.Generic;
 using System.Diagnostics;
 using System.Collections;
 using System.Globalization;
@@ -45,7 +46,7 @@ namespace PdfSharp.Pdf.Content.Objects  // TODO: split into single files
     /// <summary>
     /// Initializes a new instance of the <see cref="CObject"/> class.
     /// </summary>
-    public CObject()
+    protected CObject()
     {
     }
 
@@ -130,9 +131,9 @@ namespace PdfSharp.Pdf.Content.Objects  // TODO: split into single files
   /// Represents a sequence of objects in a PDF content stream.
   /// </summary>
   [DebuggerDisplay("(count={Count})")]
-  public class CSequence : CObject, IList, ICollection, IEnumerable
+  public class CSequence : CObject, IList<CObject>, ICollection<CObject>, IEnumerable<CObject>
   {
-    ArrayList items = new ArrayList();
+    List<CObject> items = new List<CObject>();
 
     /// <summary>
     /// Creates a new object that is a copy of the current instance.
@@ -148,11 +149,9 @@ namespace PdfSharp.Pdf.Content.Objects  // TODO: split into single files
     protected override CObject Copy()
     {
       CObject obj = base.Copy();
-      this.items = (ArrayList)this.items.Clone();
+      this.items = new List<CObject>(this.items);
       for (int idx = 0; idx < this.items.Count; idx++)
-      {
-        this.items[idx] = ((CObject)(this.items[idx])).Clone();
-      }
+        this.items[idx] = this.items[idx].Clone();
       return obj;
     }
 
@@ -170,24 +169,11 @@ namespace PdfSharp.Pdf.Content.Objects  // TODO: split into single files
     #region IList Members
 
     /// <summary>
-    /// Adds an item to the <see cref="T:System.Collections.IList"></see>.
-    /// </summary>
-    /// <param name="value">The <see cref="T:System.Object"></see> to add to the <see cref="T:System.Collections.IList"></see>.</param>
-    /// <returns>
-    /// The position into which the new element was inserted.
-    /// </returns>
-    /// <exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.IList"></see> is read-only.-or- The <see cref="T:System.Collections.IList"></see> has a fixed size. </exception>
-    int IList.Add(object value)
-    {
-      return this.items.Add(value);
-    }
-
-    /// <summary>
     /// Adds the specified value add the end of the sequence.
     /// </summary>
-    public int Add(CObject value)
+    public void Add(CObject value)
     {
-      return this.items.Add(value);
+      this.items.Add(value);
     }
 
     /// <summary>
@@ -198,10 +184,10 @@ namespace PdfSharp.Pdf.Content.Objects  // TODO: split into single files
       this.items.Clear();
     }
 
-    bool IList.Contains(object value)
-    {
-      return this.items.Contains(value);
-    }
+    //bool IList.Contains(object value)
+    //{
+    //  return this.items.Contains(value);
+    //}
 
     /// <summary>
     /// Determines whether the specified value is in the sequence.
@@ -211,11 +197,6 @@ namespace PdfSharp.Pdf.Content.Objects  // TODO: split into single files
       return this.items.Contains(value);
     }
 
-    int IList.IndexOf(object value)
-    {
-      return this.items.IndexOf(value);
-    }
-
     /// <summary>
     /// Returns the index of the specified value in the sequence or -1, if no such value is in the sequence.
     /// </summary>
@@ -224,11 +205,6 @@ namespace PdfSharp.Pdf.Content.Objects  // TODO: split into single files
       return this.items.IndexOf(value);
     }
 
-    void IList.Insert(int index, object value)
-    {
-      this.items.Insert(index, value);
-    }
-
     /// <summary>
     /// Inserts the specified value in the sequence.
     /// </summary>
@@ -237,33 +213,28 @@ namespace PdfSharp.Pdf.Content.Objects  // TODO: split into single files
       this.items.Insert(index, value);
     }
 
-    /// <summary>
-    /// Gets a value indicating whether the sequence has a fixed size.
-    /// </summary>
-    public bool IsFixedSize
-    {
-      get { return this.items.IsFixedSize; }
-    }
-
-    /// <summary>
-    /// Gets a value indicating whether the sequence is read-only.
-    /// </summary>
-    public bool IsReadOnly
-    {
-      get { return this.items.IsReadOnly; }
-    }
+    /////// <summary>
+    /////// Gets a value indicating whether the sequence has a fixed size.
+    /////// </summary>
+    ////public bool IsFixedSize
+    ////{
+    ////  get { return this.items.IsFixedSize; }
+    ////}
 
-    void IList.Remove(object value)
-    {
-      this.items.Remove(value);
-    }
+    /////// <summary>
+    /////// Gets a value indicating whether the sequence is read-only.
+    /////// </summary>
+    ////public bool IsReadOnly
+    ////{
+    ////  get { return this.items.IsReadOnly; }
+    ////}
 
     /// <summary>
     /// Removes the specified value from the sequence.
     /// </summary>
-    public void Remove(CObject value)
+    public bool Remove(CObject value)
     {
-      this.items.Remove(value);
+      return this.items.Remove(value);
     }
 
     /// <summary>
@@ -274,12 +245,6 @@ namespace PdfSharp.Pdf.Content.Objects  // TODO: split into single files
       this.items.RemoveAt(index);
     }
 
-    object IList.this[int index]
-    {
-      get { return this.items[index]; }
-      set { this.items[index] = value; }
-    }
-
     /// <summary>
     /// Gets or sets a CObject at the specified index.
     /// </summary>
@@ -296,11 +261,12 @@ namespace PdfSharp.Pdf.Content.Objects  // TODO: split into single files
     /// <summary>
     /// Copies the elements of the sequence to the specified array.
     /// </summary>
-    public void CopyTo(Array array, int index)
+    public void CopyTo(CObject[] array, int index)
     {
       this.items.CopyTo(array, index);
     }
 
+
     /// <summary>
     /// Gets the number of elements contained in the sequence.
     /// </summary>
@@ -309,21 +275,21 @@ namespace PdfSharp.Pdf.Content.Objects  // TODO: split into single files
       get { return this.items.Count; }
     }
 
-    /// <summary>
-    /// Gets a value indicating whether access to the sequence is synchronized (thread safe).
-    /// </summary>
-    public bool IsSynchronized
-    {
-      get { return this.items.IsSynchronized; }
-    }
+    ///// <summary>
+    ///// Gets a value indicating whether access to the sequence is synchronized (thread safe).
+    ///// </summary>
+    //public bool IsSynchronized
+    //{
+    //  get { return this.items.IsSynchronized; }
+    //}
 
-    /// <summary>
-    /// Gets an object that can be used to synchronize access to the sequence.
-    /// </summary>
-    public object SyncRoot
-    {
-      get { return this.items.SyncRoot; }
-    }
+    ///// <summary>
+    ///// Gets an object that can be used to synchronize access to the sequence.
+    ///// </summary>
+    //public object SyncRoot
+    //{
+    //  get { return this.items.SyncRoot; }
+    //}
 
     #endregion
 
@@ -332,7 +298,7 @@ namespace PdfSharp.Pdf.Content.Objects  // TODO: split into single files
     /// <summary>
     /// Returns an enumerator that iterates through the sequence.
     /// </summary>
-    public IEnumerator GetEnumerator()
+    public IEnumerator<CObject> GetEnumerator()
     {
       return this.items.GetEnumerator();
     }
@@ -340,7 +306,7 @@ namespace PdfSharp.Pdf.Content.Objects  // TODO: split into single files
     #endregion
 
     /// <summary>
-    /// Converts the sequence to a PDF conent stream.
+    /// Converts the sequence to a PDF content stream.
     /// </summary>
     public byte[] ToContent()
     {
@@ -370,11 +336,95 @@ namespace PdfSharp.Pdf.Content.Objects  // TODO: split into single files
       return s.ToString();
     }
 
+    IEnumerator IEnumerable.GetEnumerator()
+    {
+      return GetEnumerator();
+    }
+
     internal override void WriteObject(ContentWriter writer)
     {
       for (int idx = 0; idx < this.items.Count; idx++)
         (this.items[idx] as CObject).WriteObject(writer);
     }
+
+    #region IList<CObject> Members
+
+    int IList<CObject>.IndexOf(CObject item)
+    {
+      throw new NotImplementedException();
+    }
+
+    void IList<CObject>.Insert(int index, CObject item)
+    {
+      throw new NotImplementedException();
+    }
+
+    void IList<CObject>.RemoveAt(int index)
+    {
+      throw new NotImplementedException();
+    }
+
+    CObject IList<CObject>.this[int index]
+    {
+      get
+      {
+        throw new NotImplementedException();
+      }
+      set
+      {
+        throw new NotImplementedException();
+      }
+    }
+
+    #endregion
+
+    #region ICollection<CObject> Members
+
+    void ICollection<CObject>.Add(CObject item)
+    {
+      throw new NotImplementedException();
+    }
+
+    void ICollection<CObject>.Clear()
+    {
+      throw new NotImplementedException();
+    }
+
+    bool ICollection<CObject>.Contains(CObject item)
+    {
+      throw new NotImplementedException();
+    }
+
+    void ICollection<CObject>.CopyTo(CObject[] array, int arrayIndex)
+    {
+      throw new NotImplementedException();
+    }
+
+    int ICollection<CObject>.Count
+    {
+      get { throw new NotImplementedException(); }
+    }
+
+    bool ICollection<CObject>.IsReadOnly
+    {
+      get { throw new NotImplementedException(); }
+    }
+
+    bool ICollection<CObject>.Remove(CObject item)
+    {
+      throw new NotImplementedException();
+    }
+
+    #endregion
+
+    #region IEnumerable<CObject> Members
+
+    IEnumerator<CObject> IEnumerable<CObject>.GetEnumerator()
+    {
+      throw new NotImplementedException();
+    }
+
+    #endregion
   }
 
   /// <summary>
@@ -537,7 +587,63 @@ namespace PdfSharp.Pdf.Content.Objects  // TODO: split into single files
     /// </summary>
     public override string ToString()
     {
-      return "(" + this.value + ")";
+      StringBuilder s = new StringBuilder("(");
+      int length = this.value.Length;
+      for (int ich = 0; ich < length; ich++)
+      {
+        char ch = this.value[ich];
+        switch (ch)
+        {
+          case Chars.LF:
+            s.Append("\\n");
+            break;
+
+          case Chars.CR:
+            s.Append("\\r");
+            break;
+
+          case Chars.HT:
+            s.Append("\\t");
+            break;
+
+          case Chars.BS:
+            s.Append("\\b");
+            break;
+
+          case Chars.FF:
+            s.Append("\\f");
+            break;
+
+          case Chars.ParenLeft:
+            s.Append("\\(");
+            break;
+
+          case Chars.ParenRight:
+            s.Append("\\)");
+            break;
+
+          case Chars.BackSlash:
+            s.Append("\\\\");
+            break;
+
+          default:
+#if true_
+            // not absolut necessary to use octal encoding for characters less than blank
+            if (ch < ' ')
+            {
+              s.Append("\\");
+              s.Append((char)(((ch >> 6) & 7) + '0'));
+              s.Append((char)(((ch >> 3) & 7) + '0'));
+              s.Append((char)((ch & 7) + '0'));
+            }
+            else
+#endif
+            s.Append(ch);
+            break;
+        }
+      }
+      s.Append(')');
+      return s.ToString();
     }
 
     internal override void WriteObject(ContentWriter writer)
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Content.Objects/Operators.cs b/lib/PdfSharp/PdfSharp.Pdf.Content.Objects/Operators.cs
index dc43e0a..98746a6 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Content.Objects/Operators.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Content.Objects/Operators.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -28,9 +28,9 @@
 #endregion
 
 using System;
-using System.Diagnostics;
 using System.Collections;
-using System.Text;
+using System.Diagnostics;
+using System.Collections.Generic;
 
 namespace PdfSharp.Pdf.Content.Objects
 {
@@ -47,7 +47,7 @@ namespace PdfSharp.Pdf.Content.Objects
     /// <param name="name">The name.</param>
     /// <param name="opcodeName">The enum value of the operator.</param>
     /// <param name="operands">The number of operands.</param>
-    /// <param name="postscript">The postscript equvalent, or null, if no such operation exists.</param>
+    /// <param name="postscript">The postscript equivalent, or null, if no such operation exists.</param>
     /// <param name="flags">The flags.</param>
     /// <param name="description">The description from Adobe PDF Reference.</param>
     internal OpCode(string name, OpCodeName opcodeName, int operands, string postscript, OpCodeFlags flags, string description)
@@ -81,7 +81,7 @@ namespace PdfSharp.Pdf.Content.Objects
     public readonly OpCodeFlags Flags;
 
     /// <summary>
-    /// The postscript equvalent, or null, if no such operation exists.
+    /// The postscript equivalent, or null, if no such operation exists.
     /// </summary>
     public readonly string Postscript;
 
@@ -102,7 +102,6 @@ namespace PdfSharp.Pdf.Content.Objects
     /// Operators from name.
     /// </summary>
     /// <param name="name">The name.</param>
-    /// <returns></returns>
     static public COperator OperatorFromName(string name)
     {
       COperator op = null;
@@ -123,15 +122,15 @@ namespace PdfSharp.Pdf.Content.Objects
     /// </summary>
     static OpCodes()
     {
-      OpCodes.stringToOpCode = new Hashtable();
+      stringToOpCode = new Dictionary<string, OpCode>();
 
-      for (int idx = 0; idx < OpCodes.ops.Length; idx++)
+      for (int idx = 0; idx < ops.Length; idx++)
       {
-        OpCode op = OpCodes.ops[idx];
-        OpCodes.stringToOpCode.Add(op.Name, op);
+        OpCode op = ops[idx];
+        stringToOpCode.Add(op.Name, op);
       }
     }
-    static Hashtable stringToOpCode;
+    static readonly Dictionary<string, OpCode> stringToOpCode;
 
     static OpCode b = new OpCode("b", OpCodeName.b, 0, "closepath, fill, stroke", OpCodeFlags.None,
       "Close, fill, and stroke path using nonzero winding number");
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Content.Objects/enum/OpCodeFlags.cs b/lib/PdfSharp/PdfSharp.Pdf.Content.Objects/enum/OpCodeFlags.cs
index 0835d58..99dd733 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Content.Objects/enum/OpCodeFlags.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Content.Objects/enum/OpCodeFlags.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Content.Objects/enum/OpCodeName.cs b/lib/PdfSharp/PdfSharp.Pdf.Content.Objects/enum/OpCodeName.cs
index 23f3152..cad74ba 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Content.Objects/enum/OpCodeName.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Content.Objects/enum/OpCodeName.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -27,7 +27,6 @@
 // DEALINGS IN THE SOFTWARE.
 #endregion
 
-// Comment out next line in Visual Studio 7.1
 #pragma warning disable 1591
 
 namespace PdfSharp.Pdf.Content.Objects
@@ -42,6 +41,6 @@ namespace PdfSharp.Pdf.Content.Objects
     DP, EI, EMC, ET, EX, f, F, fx, G, g, gs, h, i, ID, j, J, K, k, l, m, M, MP,
     n, q, Q, re, RG, rg, ri, s, S, SC, sc, SCN, scn, sh,
     Tx, Tc, Td, TD, Tf, Tj, TJ, TL, Tm, Tr, Ts, Tw, Tz, v, w, W, Wx, y,
-    QuoteSingle, QuoteDbl
+    QuoteSingle, QuoteDbl,
   }
 }
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Content/CLexer.cs b/lib/PdfSharp/PdfSharp.Pdf.Content/CLexer.cs
index 4970203..c54c0b5 100644
Binary files a/lib/PdfSharp/PdfSharp.Pdf.Content/CLexer.cs and b/lib/PdfSharp/PdfSharp.Pdf.Content/CLexer.cs differ
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Content/CParser.cs b/lib/PdfSharp/PdfSharp.Pdf.Content/CParser.cs
index 5ac236f..ec778b7 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Content/CParser.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Content/CParser.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -142,9 +142,20 @@ namespace PdfSharp.Pdf.Content
     {
       string name = this.lexer.Token;
       COperator op = OpCodes.OperatorFromName(name);
+      if (op.OpCode.OpCodeName== OpCodeName.ID)
+      {
+        this.lexer.ScanInlineImage();
+      }
+
 #if DEBUG
       if (op.OpCode.Operands != -1 && op.OpCode.Operands != this.operands.Count)
-        Debug.Assert(false, "Invalid number of operands.");
+      {
+        if (op.OpCode.OpCodeName != OpCodeName.ID)
+        {
+          GetType();
+          Debug.Assert(false, "Invalid number of operands.");
+        }
+      }
 #endif
       op.Operands.Add(this.operands);
       return op;
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Content/Chars.cs b/lib/PdfSharp/PdfSharp.Pdf.Content/Chars.cs
index a1eb2c6..5d87a99 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Content/Chars.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Content/Chars.cs
@@ -1,9 +1,9 @@
-#region PDFsharp - A .NET library for processing PDF
+#region PDFsharp - A .NET library for processing PDF
 //
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -72,7 +72,7 @@ namespace PdfSharp.Pdf.Content
     public const char Asterisk = '*';
     public const char Question = '?';
     public const char Hyphen = '-';  // char(45)
-    public const char SoftHyphen = '­';  // char(173)
-    public const char Currency = '¤';
+    public const char SoftHyphen = '­';  // char(173)
+    public const char Currency = '¤';
   }
 }
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Content/ContentReader.cs b/lib/PdfSharp/PdfSharp.Pdf.Content/ContentReader.cs
index 9674d85..6ee5079 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Content/ContentReader.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Content/ContentReader.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -44,7 +44,6 @@ namespace PdfSharp.Pdf.Content
     /// Reads the content stream(s) of the specified page.
     /// </summary>
     /// <param name="page">The page.</param>
-    /// <returns></returns>
     static public CSequence ReadContent(PdfPage page)
     {
       CParser parser = new CParser(page);
@@ -56,7 +55,6 @@ namespace PdfSharp.Pdf.Content
     /// Reads the specified content.
     /// </summary>
     /// <param name="content">The content.</param>
-    /// <returns></returns>
     static public CSequence ReadContent(byte[] content)
     {
       CParser parser = new CParser(content);
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Content/ContentReaderException.cs b/lib/PdfSharp/PdfSharp.Pdf.Content/ContentReaderException.cs
index 0793497..75aa100 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Content/ContentReaderException.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Content/ContentReaderException.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Content/ContentWriter.cs b/lib/PdfSharp/PdfSharp.Pdf.Content/ContentWriter.cs
index c43565e..9848f2f 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Content/ContentWriter.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Content/ContentWriter.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -28,6 +28,7 @@
 #endregion
 
 using System;
+using System.Collections.Generic;
 using System.Diagnostics;
 using System.Collections;
 using System.Globalization;
@@ -618,6 +619,6 @@ namespace PdfSharp.Pdf.Content
       //public bool HasStream;
     }
 
-    ArrayList stack = new ArrayList();
+    List<CObject> stack = new List<CObject>();
   }
 }
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Content/enums/Symbol.cs b/lib/PdfSharp/PdfSharp.Pdf.Content/enums/Symbol.cs
index 6108541..dfa02a3 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Content/enums/Symbol.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Content/enums/Symbol.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Filters/ASCII85Decode.cs b/lib/PdfSharp/PdfSharp.Pdf.Filters/ASCII85Decode.cs
index 59b2a86..ad759bf 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Filters/ASCII85Decode.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Filters/ASCII85Decode.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -84,7 +84,7 @@ namespace PdfSharp.Pdf.Filters
       }
       if (rest == 1)
       {
-        uint val = (uint)data[idxIn++] << 24;
+        uint val = (uint)data[idxIn] << 24;
         val /= 85 * 85 * 85;
         byte c2 = (byte)(val % 85 + '!');
         val /= 85;
@@ -95,7 +95,7 @@ namespace PdfSharp.Pdf.Filters
       }
       else if (rest == 2)
       {
-        uint val = ((uint)data[idxIn++] << 24) + ((uint)data[idxIn++] << 16);
+        uint val = ((uint)data[idxIn++] << 24) + ((uint)data[idxIn] << 16);
         val /= 85 * 85;
         byte c3 = (byte)(val % 85 + '!');
         val /= 85;
@@ -109,7 +109,7 @@ namespace PdfSharp.Pdf.Filters
       }
       else if (rest == 3)
       {
-        uint val = ((uint)data[idxIn++] << 24) + ((uint)data[idxIn++] << 16) + ((uint)data[idxIn++] << 8);
+        uint val = ((uint)data[idxIn++] << 24) + ((uint)data[idxIn++] << 16) + ((uint)data[idxIn] << 8);
         val /= 85;
         byte c4 = (byte)(val % 85 + '!');
         val /= 85;
@@ -128,7 +128,7 @@ namespace PdfSharp.Pdf.Filters
       result[idxOut++] = (byte)'>';
 
       if (idxOut < result.Length)
-        Array.Resize<byte>(ref result, idxOut);
+        Array.Resize(ref result, idxOut);
 
       return result;
     }
@@ -161,14 +161,11 @@ namespace PdfSharp.Pdf.Filters
             throw new ArgumentException("Illegal character.", "data");
           break;
         }
-        else
-        {
-          // ingnore unknown character
-        }
+        // ingnore unknown character
       }
       // Loop not ended with break?
       if (idx == length)
-        throw new ArgumentException("Illegal character.", "date");
+        throw new ArgumentException("Illegal character.", "data");
 
       length = idxOut;
       int nonZero = length - zCount;
@@ -214,30 +211,28 @@ namespace PdfSharp.Pdf.Filters
       // All possible cases are tested programmatically.
       if (remainder == 2) // one byte
       {
-        int idxIn = idx;
         uint value =
           (uint)(data[idx++] - '!') * (85 * 85 * 85 * 85) +
-          (uint)(data[idx++] - '!') * (85 * 85 * 85);
+          (uint)(data[idx] - '!') * (85 * 85 * 85);
 
         // Always increase if not zero (tried out)
         if (value != 0)
           value += 0x01000000;
 
-        output[idxOut++] = (byte)(value >> 24);
+        output[idxOut] = (byte)(value >> 24);
       }
       else if (remainder == 3) // two bytes
       {
         int idxIn = idx;
-        uint val;
         uint value =
           (uint)(data[idx++] - '!') * (85 * 85 * 85 * 85) +
           (uint)(data[idx++] - '!') * (85 * 85 * 85) +
-          (uint)(data[idx++] - '!') * (85 * 85);
+          (uint)(data[idx] - '!') * (85 * 85);
 
         if (value != 0)
         {
           value &= 0xFFFF0000;
-          val = value / (85 * 85);
+          uint val = value / (85 * 85);
           byte c3 = (byte)(val % 85 + '!');
           val /= 85;
           byte c2 = (byte)(val % 85 + '!');
@@ -250,22 +245,21 @@ namespace PdfSharp.Pdf.Filters
           }
         }
         output[idxOut++] = (byte)(value >> 24);
-        output[idxOut++] = (byte)(value >> 16);
+        output[idxOut] = (byte)(value >> 16);
       }
       else if (remainder == 4) // three bytes
       {
         int idxIn = idx;
-        uint val;
         uint value =
           (uint)(data[idx++] - '!') * (85 * 85 * 85 * 85) +
           (uint)(data[idx++] - '!') * (85 * 85 * 85) +
           (uint)(data[idx++] - '!') * (85 * 85) +
-          (uint)(data[idx++] - '!') * 85;
+          (uint)(data[idx] - '!') * 85;
 
         if (value != 0)
         {
           value &= 0xFFFFFF00;
-          val = value / 85;
+          uint val = value / 85;
           byte c4 = (byte)(val % 85 + '!');
           val /= 85;
           byte c3 = (byte)(val % 85 + '!');
@@ -281,7 +275,7 @@ namespace PdfSharp.Pdf.Filters
         }
         output[idxOut++] = (byte)(value >> 24);
         output[idxOut++] = (byte)(value >> 16);
-        output[idxOut++] = (byte)(value >> 8);
+        output[idxOut] = (byte)(value >> 8);
       }
       return output;
     }
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Filters/ASCIIHexDecode.cs b/lib/PdfSharp/PdfSharp.Pdf.Filters/ASCIIHexDecode.cs
index 80b64e8..be00a95 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Filters/ASCIIHexDecode.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Filters/ASCIIHexDecode.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Filters/Filter.cs b/lib/PdfSharp/PdfSharp.Pdf.Filters/Filter.cs
index 72beb28..b76afcc 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Filters/Filter.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Filters/Filter.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -82,7 +82,7 @@ namespace PdfSharp.Pdf.Filters
     public virtual string DecodeToString(byte[] data, FilterParms parms)
     {
       byte[] bytes = Decode(data, parms);
-      string text = PdfEncoders.RawEncoding.GetString(bytes);
+      string text = PdfEncoders.RawEncoding.GetString(bytes, 0, bytes.Length);
       return text;
     }
 
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Filters/Filtering.cs b/lib/PdfSharp/PdfSharp.Pdf.Filters/Filtering.cs
index c324b3a..3d35765 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Filters/Filtering.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Filters/Filtering.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Filters/FlateDecode.cs b/lib/PdfSharp/PdfSharp.Pdf.Filters/FlateDecode.cs
index 0ad852f..ca5d831 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Filters/FlateDecode.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Filters/FlateDecode.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Filters/LzwDecode.cs b/lib/PdfSharp/PdfSharp.Pdf.Filters/LzwDecode.cs
index 652234d..4cb2ae7 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Filters/LzwDecode.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Filters/LzwDecode.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   David Stephensen (mailto:David Stephensen pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -52,7 +52,7 @@ namespace PdfSharp.Pdf.Filters
     /// </summary>
     public override byte[] Decode(byte[] data, FilterParms parms)
     {
-      if (data[0] == (byte)0x00 && data[1] == (byte)0x01)
+      if (data[0] == 0x00 && data[1] == 0x01)
         throw new Exception("LZW flavour not supported.");
 
       MemoryStream outputStream = new MemoryStream();
@@ -60,16 +60,13 @@ namespace PdfSharp.Pdf.Filters
       InitializeDictionary();
 
       this.data = data;
-
       bytePointer = 0;
-
       nextData = 0;
       nextBits = 0;
-
       int code, oldCode = 0;
       byte[] str;
 
-      while ((code = this.NextCode) != 257)
+      while ((code = NextCode) != 257)
       {
         if (code == 256)
         {
@@ -177,9 +174,9 @@ namespace PdfSharp.Pdf.Filters
       }
     }
 
-    int[] andTable = { 511, 1023, 2047, 4095 };
+    readonly int[] andTable = { 511, 1023, 2047, 4095 };
     byte[][] stringTable;
-    byte[] data = null;
+    byte[] data;
     int tableIndex, bitsToGet = 9;
     int bytePointer;
     int nextData = 0;
diff --git a/lib/PdfSharp/PdfSharp.Pdf.IO/Chars.cs b/lib/PdfSharp/PdfSharp.Pdf.IO/Chars.cs
index 94de386..e386095 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.IO/Chars.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.IO/Chars.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -36,7 +36,8 @@ namespace PdfSharp.Pdf.IO
   /// </summary>
   internal sealed class Chars
   {
-    public const char EOF          = (char)65535; //unchecked((char)(-1));
+    // ReSharper disable InconsistentNaming
+    public const char EOF = (char)65535; //unchecked((char)(-1));
     public const char NUL          = '\0';   // EOF
     public const char CR           = '\x0D'; // ignored by lexer
     public const char LF           = '\x0A'; // Line feed
@@ -75,5 +76,6 @@ namespace PdfSharp.Pdf.IO
     public const char Hyphen       = '-';  // char(45)
     public const char SoftHyphen   = '­';  // char(173)
     public const char Currency     = '¤';
+    // ReSharper restore InconsistentNaming
   }
 }
diff --git a/lib/PdfSharp/PdfSharp.Pdf.IO/Lexer.cs b/lib/PdfSharp/PdfSharp.Pdf.IO/Lexer.cs
index 37494be..d573965 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.IO/Lexer.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.IO/Lexer.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -39,8 +39,8 @@ using PdfSharp.Pdf.Internal;
 namespace PdfSharp.Pdf.IO
 {
   /// <summary>
-  /// Lexical analyser for PDF files. Technically a PDF file is a stream of bytes. Some chunks
-  /// of bytes represent strings in serveral encodings. The actual encoding depends on the
+  /// Lexical analyzer for PDF files. Technically a PDF file is a stream of bytes. Some chunks
+  /// of bytes represent strings in several encodings. The actual encoding depends on the
   /// context where the string is used. Therefore the bytes are 'raw encoded' into characters,
   /// i.e. a character or token read by the lexer has always character values in the range from
   /// 0 to 255.
@@ -85,10 +85,10 @@ namespace PdfSharp.Pdf.IO
 
     /// <summary>
     /// Reads the next token and returns its type. If the token starts with a digit, the parameter
-    /// testReference specifies how to treat it. If it is flase, the lexer scans for a single integer.
+    /// testReference specifies how to treat it. If it is false, the lexer scans for a single integer.
     /// If it is true, the lexer checks if the digit is the prefix of a reference. If it is a reference,
     /// the token is set to the object ID followed by the generation number separated by a blank
-    /// (the 'R' is omited from the token).
+    /// (the 'R' is omitted from the token).
     /// </summary>
     // /// <param name="testReference">Indicates whether to test the next token if it is a reference.</param>
     public Symbol ScanNextToken()
@@ -203,7 +203,7 @@ namespace PdfSharp.Pdf.IO
       this.pdf.Position = position;
       byte[] bytes = new byte[length];
       this.pdf.Read(bytes, 0, length);
-      return PdfEncoders.RawEncoding.GetString(bytes);
+      return PdfEncoders.RawEncoding.GetString(bytes, 0, bytes.Length);
     }
 
     /// <summary>
@@ -233,10 +233,9 @@ namespace PdfSharp.Pdf.IO
       {
         char ch = AppendAndScanNextChar();
         if (IsWhiteSpace(ch) || IsDelimiter(ch))
-        {
           return this.symbol = Symbol.Name;
-        }
-        else if (ch == '#')
+
+        if (ch == '#')
         {
           ScanNextChar();
           char[] hex = new char[2];
@@ -707,7 +706,7 @@ namespace PdfSharp.Pdf.IO
           ch = ScanNextChar();
         }
       }
-//      Debug.Assert(false, "Must never come here:");
+      //      Debug.Assert(false, "Must never come here:");
     }
 
     public Symbol ScanHexadecimalString()
@@ -727,14 +726,11 @@ namespace PdfSharp.Pdf.IO
         }
         if (char.IsLetterOrDigit(this.currChar))
         {
-          if (char.IsLetterOrDigit(this.nextChar))
-          {
-            hex[0] = char.ToUpper(this.currChar);
-            hex[1] = char.ToUpper(this.nextChar);
-            int ch = int.Parse(new string(hex), NumberStyles.AllowHexSpecifier);
-            this.token.Append(Convert.ToChar(ch));
-            ScanNextChar();
-          }
+          hex[0] = char.ToUpper(this.currChar);
+          hex[1] = char.ToUpper(this.nextChar);
+          int ch = int.Parse(new string(hex), NumberStyles.AllowHexSpecifier);
+          this.token.Append(Convert.ToChar(ch));
+          ScanNextChar();
           ScanNextChar();
         }
       }
@@ -882,7 +878,7 @@ namespace PdfSharp.Pdf.IO
     }
 
     /// <summary>
-    /// Interpret current token as real or interger literal.
+    /// Interpret current token as real or integer literal.
     /// </summary>
     internal double TokenToReal
     {
diff --git a/lib/PdfSharp/PdfSharp.Pdf.IO/Parser.cs b/lib/PdfSharp/PdfSharp.Pdf.IO/Parser.cs
index 9e66a1f..b1973ed 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.IO/Parser.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.IO/Parser.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -78,7 +78,7 @@ namespace PdfSharp.Pdf.IO
     }
 
     /// <summary>
-    /// Sets PDF input stream position the the specified object.
+    /// Sets PDF input stream position to the specified object.
     /// </summary>
     public int MoveToObject(PdfObjectID objectID)
     {
@@ -181,7 +181,7 @@ namespace PdfSharp.Pdf.IO
           return pdfObject;
 
         case Symbol.Boolean:
-          pdfObject = new PdfBooleanObject(this.document, this.lexer.Token == Boolean.TrueString);
+          pdfObject = new PdfBooleanObject(this.document, string.Compare(this.lexer.Token, Boolean.TrueString, true) == 0); //!!!mod THHO 19.11.09
           pdfObject.SetObjectID(objectNumber, generationNumber);
           ReadSymbol(Symbol.EndObj);
           return pdfObject;
@@ -222,7 +222,7 @@ namespace PdfSharp.Pdf.IO
 
         default:
           // Should not come here anymore
-          throw new NotImplementedException("unknown token");
+          throw new NotImplementedException("unknown token \"" + symbol + "\"");
       }
       symbol = ScanNextToken();
       if (symbol == Symbol.BeginStream)
@@ -705,9 +705,15 @@ namespace PdfSharp.Pdf.IO
       //string token;
       //int xrefOffset = 0;
       int length = lexer.PdfLength;
+#if true
+      string trail = this.lexer.ReadRawString(length - 131, 130); //lexer.Pdf.Substring(length - 30);
+      int idx = trail.IndexOf("startxref");
+      this.lexer.Position = length - 131 + idx;
+#else
       string trail = this.lexer.ReadRawString(length - 31, 30); //lexer.Pdf.Substring(length - 30);
       int idx = trail.IndexOf("startxref");
       this.lexer.Position = length - 31 + idx;
+#endif
       ReadSymbol(Symbol.StartXRef);
       this.lexer.Position = ReadInteger();
 
@@ -741,7 +747,7 @@ namespace PdfSharp.Pdf.IO
       // Is it an xref stream?
       if (symbol == Symbol.Integer)
         throw new PdfReaderException(PSSR.CannotHandleXRefStreams);
-      // TODO: We have all code to handle them -> just do it
+      // TODO: It is very high on the todo list, but still undone
       Debug.Assert(symbol == Symbol.XRef);
       while (true)
       {
@@ -831,7 +837,7 @@ namespace PdfSharp.Pdf.IO
         }
         else
         {
-          // Some libraries use plain english format.
+          // Some libraries use plain English format.
           datetime = DateTime.Parse(date);
         }
       }
diff --git a/lib/PdfSharp/PdfSharp.Pdf.IO/PdfReader.cs b/lib/PdfSharp/PdfSharp.Pdf.IO/PdfReader.cs
index 9c1853b..3535cb8 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.IO/PdfReader.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.IO/PdfReader.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -65,11 +65,8 @@ namespace PdfSharp.Pdf.IO
   /// <summary>
   /// Represents the functionality for reading PDF documents.
   /// </summary>
-  public sealed class PdfReader
+  public static class PdfReader
   {
-    // Makes this class static
-    PdfReader() { }
-
     /// <summary>
     /// Determines whether the file specified by its path is a PDF file by inspecting the first eight
     /// bytes of the data. If the file header has the form «%PDF-x.y» the function returns the version
@@ -149,6 +146,7 @@ namespace PdfSharp.Pdf.IO
     /// </summary>
     internal static int GetPdfFileVersion(byte[] bytes)
     {
+#if !SILVERLIGHT
       try
       {
         // Acrobat accepts headers like «%!PS-Adobe-N.n PDF-M.m»...
@@ -161,12 +159,15 @@ namespace PdfSharp.Pdf.IO
             char major = header[ich + 4];
             char minor = header[ich + 6];
             if (major >= '1' && major < '2' && minor >= '0' && minor <= '9')
-              return ((int)(major - '0')) * 10 + (int)(minor - '0');
+              return (major - '0') * 10 + (minor - '0');
           }
         }
       }
       catch {}
       return 0;
+#else
+      return 50; // AGHACK
+#endif
     }
 
     /// <summary>
@@ -198,12 +199,15 @@ namespace PdfSharp.Pdf.IO
     /// </summary>
     public static PdfDocument Open(string path, string password, PdfDocumentOpenMode openmode, PdfPasswordProvider provider)
     {
-      PdfDocument document = null;
+      PdfDocument document;
       Stream stream = new FileStream(path, FileMode.Open, FileAccess.Read);
       try
       {
         document = PdfReader.Open(stream, password, openmode, provider);
-        document.fullPath = Path.GetFullPath(path);
+        if (document != null)
+        {
+          document.fullPath = Path.GetFullPath(path);
+        }
       }
       finally
       {
@@ -292,8 +296,8 @@ namespace PdfSharp.Pdf.IO
           xrefEncrypt.Value = encrypt;
           PdfStandardSecurityHandler securityHandler = document.SecurityHandler;
         TryAgain:
-          int v = securityHandler.ValidatePassword(password);
-          if (v == 0)
+          PasswordValidity validity = securityHandler.ValidatePassword(password);
+          if (validity == PasswordValidity.Invalid)
           {
             if (passwordProvider != null)
             {
@@ -312,9 +316,19 @@ namespace PdfSharp.Pdf.IO
                 throw new PdfReaderException(PSSR.InvalidPassword);
             }
           }
-          else if (v == 1 && openmode == PdfDocumentOpenMode.Modify)
+          else if (validity == PasswordValidity.UserPassword && openmode == PdfDocumentOpenMode.Modify)
           {
-            throw new PdfReaderException(PSSR.OwnerPasswordRequired);
+            if (passwordProvider != null)
+            {
+              PdfPasswordProviderArgs args = new PdfPasswordProviderArgs();
+              passwordProvider(args);
+              if (args.Abort)
+                return null;
+              password = args.Password;
+              goto TryAgain;
+            }
+            else
+              throw new PdfReaderException(PSSR.OwnerPasswordRequired);
           }
         }
         else
@@ -379,7 +393,10 @@ namespace PdfSharp.Pdf.IO
           if (document.Internals.SecondDocumentID == "")
             document.trailer.CreateNewDocumentIDs();
           else
-            document.Internals.SecondDocumentID = PdfEncoders.RawEncoding.GetString(Guid.NewGuid().ToByteArray());
+          {
+            byte[] agTemp = Guid.NewGuid().ToByteArray();
+            document.Internals.SecondDocumentID = PdfEncoders.RawEncoding.GetString(agTemp, 0, agTemp.Length);
+          }
 
           // Change modification date
           document.Info.ModificationDate = DateTime.Now;
diff --git a/lib/PdfSharp/PdfSharp.Pdf.IO/PdfReaderException.cs b/lib/PdfSharp/PdfSharp.Pdf.IO/PdfReaderException.cs
index adbb5ac..76be1f9 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.IO/PdfReaderException.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.IO/PdfReaderException.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Pdf.IO/PdfWriter.cs b/lib/PdfSharp/PdfSharp.Pdf.IO/PdfWriter.cs
index 1889701..194b8c2 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.IO/PdfWriter.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.IO/PdfWriter.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -28,6 +28,7 @@
 #endregion
 
 using System;
+using System.Collections.Generic;
 using System.Diagnostics;
 using System.Collections;
 using System.Globalization;
@@ -227,11 +228,12 @@ namespace PdfSharp.Pdf.IO
       for (int idx = 1; idx < name.Length; idx++)
       {
         char ch = name[idx];
-        Debug.Assert((int)ch < 256);
+        Debug.Assert(ch < 256);
         if (ch > ' ')
           switch (ch)
           {
             // TODO: is this all?
+            case '%':
             case '/':
             case '<':
             case '>':
@@ -648,7 +650,7 @@ namespace PdfSharp.Pdf.IO
       public bool HasStream;
     }
 
-    ArrayList stack = new ArrayList();
+    List<StackItem> stack = new List<StackItem>();
     int commentPosition;
   }
 }
diff --git a/lib/PdfSharp/PdfSharp.Pdf.IO/ShiftStack.cs b/lib/PdfSharp/PdfSharp.Pdf.IO/ShiftStack.cs
index b488a13..547c65d 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.IO/ShiftStack.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.IO/ShiftStack.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -28,6 +28,7 @@
 #endregion
 
 using System;
+using System.Collections.Generic;
 using System.Diagnostics;
 using System.Collections;
 using System.Text;
@@ -37,7 +38,7 @@ using PdfSharp.Pdf;
 namespace PdfSharp.Pdf.IO
 {
   /// <summary>
-  /// Represents the stack for the shift-reduce parser. It seems that it is only neede for
+  /// Represents the stack for the shift-reduce parser. It seems that it is only needed for
   /// reduction of indirect references.
   /// </summary>
   internal class ShiftStack
@@ -46,7 +47,7 @@ namespace PdfSharp.Pdf.IO
 
     public ShiftStack()
     {
-      this.items = new ArrayList();
+      this.items = new List<PdfItem>();
     }
 
     public PdfItem[] ToArray(int start, int length)
@@ -66,7 +67,7 @@ namespace PdfSharp.Pdf.IO
     }
 
     /// <summary>
-    /// Gets the value at the specifed index. Valid index is in range 0 up to sp-1.
+    /// Gets the value at the specified index. Valid index is in range 0 up to sp-1.
     /// </summary>
     public PdfItem this[int index]
     {
@@ -99,7 +100,7 @@ namespace PdfSharp.Pdf.IO
     }
 
     /// <summary>
-    /// Pushs the specified item onto the stack.
+    /// Pushes the specified item onto the stack.
     /// </summary>
     public void Shift(PdfItem item)
     {
@@ -138,6 +139,6 @@ namespace PdfSharp.Pdf.IO
     /// <summary>
     /// An array representing the stack.
     /// </summary>
-    ArrayList items;
+    List<PdfItem> items;
   }
 }
diff --git a/lib/PdfSharp/PdfSharp.Pdf.IO/enums/PasswordValidity.cs b/lib/PdfSharp/PdfSharp.Pdf.IO/enums/PasswordValidity.cs
new file mode 100644
index 0000000..9ba5174
--- /dev/null
+++ b/lib/PdfSharp/PdfSharp.Pdf.IO/enums/PasswordValidity.cs
@@ -0,0 +1,54 @@
+#region PDFsharp - A .NET library for processing PDF
+//
+// Authors:
+//   Stefan Lange (mailto:Stefan Lange pdfsharp com)
+//
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
+//
+// http://www.pdfsharp.com
+// http://sourceforge.net/projects/pdfsharp
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+// DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+
+namespace PdfSharp.Pdf.IO
+{
+  /// <summary>
+  /// Determines the type of the password.
+  /// </summary>
+  public enum PasswordValidity
+  {
+    /// <summary>
+    /// Password is neither user nor owner password.
+    /// </summary>
+    Invalid,
+
+    /// <summary>
+    /// Password is user password.
+    /// </summary>
+    UserPassword,
+
+    /// <summary>
+    /// Password is owner password.
+    /// </summary>
+    OwnerPassword,
+  }
+}
\ No newline at end of file
diff --git a/lib/PdfSharp/PdfSharp.Pdf.IO/enums/PdfDocumentOpenMode.cs b/lib/PdfSharp/PdfSharp.Pdf.IO/enums/PdfDocumentOpenMode.cs
index 17a35f4..8ee67c5 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.IO/enums/PdfDocumentOpenMode.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.IO/enums/PdfDocumentOpenMode.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -49,7 +49,7 @@ namespace PdfSharp.Pdf.IO
 
     /// <summary>
     /// The PDF stream is completely read into memory, but cannot be modified. This mode preserves the
-    /// original internal structure of the document and is useful for analysing existing PDF files.
+    /// original internal structure of the document and is useful for analyzing existing PDF files.
     /// </summary>
     ReadOnly,
 
diff --git a/lib/PdfSharp/PdfSharp.Pdf.IO/enums/PdfWriterLayout.cs b/lib/PdfSharp/PdfSharp.Pdf.IO/enums/PdfWriterLayout.cs
index 4d81a2e..fb5a08d 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.IO/enums/PdfWriterLayout.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.IO/enums/PdfWriterLayout.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -46,15 +46,15 @@ namespace PdfSharp.Pdf.IO
     Standard, 
 
     /// <summary>
-    /// The PDF stream is indented to reflect the nesting levels of the objects. This is usedful
-    /// for analysing PDF files, but increases the size of the file significantly.
+    /// The PDF stream is indented to reflect the nesting levels of the objects. This is useful
+    /// for analyzing PDF files, but increases the size of the file significantly.
     /// </summary>
     Indented,
 
     /// <summary>
     /// The PDF stream is indented to reflect the nesting levels of the objects and contains additional
     /// information about the PDFsharp objects. Furthermore content streams are not deflated. This 
-    /// is usedful for debugging purposes only and increases the size of the file significantly.
+    /// is useful for debugging purposes only and increases the size of the file significantly.
     /// </summary>
     Verbose,
   }
diff --git a/lib/PdfSharp/PdfSharp.Pdf.IO/enums/PdfWriterOptions.cs b/lib/PdfSharp/PdfSharp.Pdf.IO/enums/PdfWriterOptions.cs
index c613811..4cfd80b 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.IO/enums/PdfWriterOptions.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.IO/enums/PdfWriterOptions.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Pdf.IO/enums/Symbol.cs b/lib/PdfSharp/PdfSharp.Pdf.IO/enums/Symbol.cs
index 6cbe634..c321507 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.IO/enums/Symbol.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.IO/enums/Symbol.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Internal/AnsiEncoding.cs b/lib/PdfSharp/PdfSharp.Pdf.Internal/AnsiEncoding.cs
index 503e2e1..5b2d69a 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Internal/AnsiEncoding.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Internal/AnsiEncoding.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Internal/ColorSpaceHelper.cs b/lib/PdfSharp/PdfSharp.Pdf.Internal/ColorSpaceHelper.cs
index f78d0ae..3173b75 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Internal/ColorSpaceHelper.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Internal/ColorSpaceHelper.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -73,7 +73,7 @@ namespace PdfSharp.Pdf.Internal
     }
 
     /// <summary>
-    /// Determines wheter two colors are equal refering to their CMYK color values.
+    /// Determines whether two colors are equal referring to their CMYK color values.
     /// </summary>
     public static bool IsEqualCmyk(XColor x, XColor y)
     {
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Internal/DocEncoding.cs b/lib/PdfSharp/PdfSharp.Pdf.Internal/DocEncoding.cs
index 1a803f7..87f60dc 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Internal/DocEncoding.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Internal/DocEncoding.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -103,5 +103,28 @@ namespace PdfSharp.Pdf.Internal
       0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
       0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF,
     };
+
+    // TODO: use this table
+    static char[] PdfDocToUnicode = new char[]
+    {
+      '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07', '\x08', '\x09', '\x0A', '\x0B', '\x0C', '\x0D', '\x0E', '\x0F',
+      '\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17', '\x18', '\x19', '\x1A', '\x1B', '\x1C', '\x1D', '\x1E', '\x1F',
+      '\x20', '\x21', '\x22', '\x23', '\x24', '\x25', '\x26', '\x27', '\x28', '\x29', '\x2A', '\x2B', '\x2C', '\x2D', '\x2E', '\x2F',
+      '\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', '\x38', '\x39', '\x3A', '\x3B', '\x3C', '\x3D', '\x3E', '\x3F',
+      '\x40', '\x41', '\x42', '\x43', '\x44', '\x45', '\x46', '\x47', '\x48', '\x49', '\x4A', '\x4B', '\x4C', '\x4D', '\x4E', '\x4F',
+      '\x50', '\x51', '\x52', '\x53', '\x54', '\x55', '\x56', '\x57', '\x58', '\x59', '\x5A', '\x5B', '\x5C', '\x5D', '\x5E', '\x5F',
+      '\x60', '\x61', '\x62', '\x63', '\x64', '\x65', '\x66', '\x67', '\x68', '\x69', '\x6A', '\x6B', '\x6C', '\x6D', '\x6E', '\x6F',
+      '\x70', '\x71', '\x72', '\x73', '\x74', '\x75', '\x76', '\x77', '\x78', '\x79', '\x7A', '\x7B', '\x7C', '\x7D', '\x7E', '\x7F',
+      '\x2022', '\x2020', '\x2021', '\x2026', '\x2014', '\x2013', '\x0192', '\x2044', '\x2039', '\x203A', '\x2212', '\x2030', '\x201E', '\x201C', '\x201D', '\x2018',
+      '\x2019', '\x201A', '\x2122', '\xFB01', '\xFB02', '\x0141', '\x0152', '\x0160', '\x0178', '\x017D', '\x0131', '\x0142', '\x0153', '\x0161', '\x017E', '\xFFFD',
+      '\x20AC', '\xA1', '\xA2', '\xA3', '\xA4', '\xA5', '\xA6', '\xA7', '\xA8', '\xA9', '\xAA', '\xAB', '\xAC', '\xAD', '\xAE', '\xAF',
+      '\xB0', '\xB1', '\xB2', '\xB3', '\xB4', '\xB5', '\xB6', '\xB7', '\xB8', '\xB9', '\xBA', '\xBB', '\xBC', '\xBD', '\xBE', '\xBF',
+      '\xC0', '\xC1', '\xC2', '\xC3', '\xC4', '\xC5', '\xC6', '\xC7', '\xC8', '\xC9', '\xCA', '\xCB', '\xCC', '\xCD', '\xCE', '\xCF',
+      '\xD0', '\xD1', '\xD2', '\xD3', '\xD4', '\xD5', '\xD6', '\xD7', '\xD8', '\xD9', '\xDA', '\xDB', '\xDC', '\xDD', '\xDE', '\xDF',
+      '\xE0', '\xE1', '\xE2', '\xE3', '\xE4', '\xE5', '\xE6', '\xE7', '\xE8', '\xE9', '\xEA', '\xEB', '\xEC', '\xED', '\xEE', '\xEF',
+      '\xF0', '\xF1', '\xF2', '\xF3', '\xF4', '\xF5', '\xF6', '\xF7', '\xF8', '\xF9', '\xFA', '\xFB', '\xFC', '\xFD', '\xFE', '\xFF',
+    };
+
+
   }
 }
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Internal/GlobalObjectTable.cs b/lib/PdfSharp/PdfSharp.Pdf.Internal/GlobalObjectTable.cs
index 9d1b441..3870cc1 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Internal/GlobalObjectTable.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Internal/GlobalObjectTable.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -28,6 +28,7 @@
 #endregion
 
 using System;
+using System.Collections.Generic;
 using System.Diagnostics;
 using System.Collections;
 using System.Globalization;
@@ -134,6 +135,6 @@ namespace PdfSharp.Pdf.Internal
     /// <summary>
     /// Array of handles to all documents.
     /// </summary>
-    ArrayList documentHandles = new ArrayList();
+    List<object> documentHandles = new List<object>();
   }
 }
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Internal/PdfEncoders.cs b/lib/PdfSharp/PdfSharp.Pdf.Internal/PdfEncoders.cs
index e997a61..c5e2c4e 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Internal/PdfEncoders.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Internal/PdfEncoders.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -42,12 +42,9 @@ namespace PdfSharp.Pdf.Internal
   /// <summary>
   /// Groups a set of static encoding helper functions.
   /// </summary>
-  internal class PdfEncoders
+  internal static class PdfEncoders
   {
-    PdfEncoders()
-    { }
-
-    const char InvalidChar = '?';
+    // static char InvalidChar = '?';
 
     //[Obsolete]
     //public static void WriteAnsi(Stream stream, string text)
@@ -63,7 +60,7 @@ namespace PdfSharp.Pdf.Internal
       get
       {
         if (PdfEncoders.rawEncoding == null)
-          PdfEncoders.rawEncoding = new PdfSharp.Pdf.Internal.RawEncoding();
+          PdfEncoders.rawEncoding = new RawEncoding();
         return PdfEncoders.rawEncoding;
       }
     }
@@ -77,7 +74,7 @@ namespace PdfSharp.Pdf.Internal
       get
       {
         if (PdfEncoders.rawUnicodeEncoding == null)
-          PdfEncoders.rawUnicodeEncoding = new PdfSharp.Pdf.Internal.RawUnicodeEncoding();
+          PdfEncoders.rawUnicodeEncoding = new RawUnicodeEncoding();
         return PdfEncoders.rawUnicodeEncoding;
       }
     }
@@ -91,7 +88,12 @@ namespace PdfSharp.Pdf.Internal
       get
       {
         if (PdfEncoders.winAnsiEncoding == null)
-          PdfEncoders.winAnsiEncoding = Encoding.GetEncoding(1252);
+          PdfEncoders.winAnsiEncoding =
+#if !SILVERLIGHT
+            Encoding.GetEncoding(1252);
+#else
+ Encoding.GetEncoding("utf-8"); // AGHACK
+#endif
         return PdfEncoders.winAnsiEncoding;
       }
     }
@@ -105,7 +107,7 @@ namespace PdfSharp.Pdf.Internal
       get
       {
         if (PdfEncoders.docEncoding == null)
-          PdfEncoders.docEncoding = new PdfSharp.Pdf.Internal.DocEncoding();
+          PdfEncoders.docEncoding = new DocEncoding();
         return PdfEncoders.docEncoding;
       }
     }
@@ -232,33 +234,33 @@ namespace PdfSharp.Pdf.Internal
     /// </summary>
     public static string ToStringLiteral(string text, PdfStringEncoding encoding, PdfStandardSecurityHandler securityHandler)
     {
-      if (text == null || text == "")
+      if (String.IsNullOrEmpty(text))
         return "()";
 
       byte[] bytes;
       switch (encoding)
       {
         case PdfStringEncoding.RawEncoding:
-          bytes = PdfEncoders.RawEncoding.GetBytes(text);
+          bytes = RawEncoding.GetBytes(text);
           break;
 
         case PdfStringEncoding.WinAnsiEncoding:
-          bytes = PdfEncoders.WinAnsiEncoding.GetBytes(text);
+          bytes = WinAnsiEncoding.GetBytes(text);
           break;
 
         case PdfStringEncoding.PDFDocEncoding:
-          bytes = PdfEncoders.DocEncoding.GetBytes(text);
+          bytes = DocEncoding.GetBytes(text);
           break;
 
         case PdfStringEncoding.Unicode:
-          bytes = PdfEncoders.UnicodeEncoding.GetBytes(text);
+          bytes = UnicodeEncoding.GetBytes(text);
           break;
 
         default:
           throw new NotImplementedException(encoding.ToString());
       }
-      return PdfEncoders.RawEncoding.GetString(FormatStringLiteral(bytes, encoding == PdfStringEncoding.Unicode, true,
-        false, securityHandler));
+      byte[] temp = FormatStringLiteral(bytes, encoding == PdfStringEncoding.Unicode, true, false, securityHandler);
+      return RawEncoding.GetString(temp, 0, temp.Length);
     }
 
     /// <summary>
@@ -269,7 +271,8 @@ namespace PdfSharp.Pdf.Internal
       if (bytes == null || bytes.Length == 0)
         return "()";
 
-      return PdfEncoders.RawEncoding.GetString(FormatStringLiteral(bytes, unicode, true, false, securityHandler));
+      byte[] temp = FormatStringLiteral(bytes, unicode, true, false, securityHandler);
+      return RawEncoding.GetString(temp, 0, temp.Length);
     }
 
     /// <summary>
@@ -277,33 +280,34 @@ namespace PdfSharp.Pdf.Internal
     /// </summary>
     public static string ToHexStringLiteral(string text, PdfStringEncoding encoding, PdfStandardSecurityHandler securityHandler)
     {
-      if (text == null || text == "")
+      if (String.IsNullOrEmpty(text))
         return "<>";
 
       byte[] bytes;
       switch (encoding)
       {
         case PdfStringEncoding.RawEncoding:
-          bytes = PdfEncoders.RawEncoding.GetBytes(text);
+          bytes = RawEncoding.GetBytes(text);
           break;
 
         case PdfStringEncoding.WinAnsiEncoding:
-          bytes = PdfEncoders.WinAnsiEncoding.GetBytes(text);
+          bytes = WinAnsiEncoding.GetBytes(text);
           break;
 
         case PdfStringEncoding.PDFDocEncoding:
-          bytes = PdfEncoders.DocEncoding.GetBytes(text);
+          bytes = DocEncoding.GetBytes(text);
           break;
 
         case PdfStringEncoding.Unicode:
-          bytes = PdfEncoders.UnicodeEncoding.GetBytes(text);
+          bytes = UnicodeEncoding.GetBytes(text);
           break;
 
         default:
           throw new NotImplementedException(encoding.ToString());
       }
-      return PdfEncoders.RawEncoding.GetString(FormatStringLiteral(bytes, encoding == PdfStringEncoding.Unicode, true,
-        true, securityHandler));
+
+      byte[] agTemp = FormatStringLiteral(bytes, encoding == PdfStringEncoding.Unicode, true, true, securityHandler);
+      return RawEncoding.GetString(agTemp, 0, agTemp.Length);
     }
 
     /// <summary>
@@ -314,7 +318,8 @@ namespace PdfSharp.Pdf.Internal
       if (bytes == null || bytes.Length == 0)
         return "<>";
 
-      return PdfEncoders.RawEncoding.GetString(FormatStringLiteral(bytes, unicode, true, true, securityHandler));
+      byte[] agTemp = FormatStringLiteral(bytes, unicode, true, true, securityHandler);
+      return RawEncoding.GetString(agTemp, 0, agTemp.Length);
     }
 
     /// <summary>
@@ -447,7 +452,7 @@ namespace PdfSharp.Pdf.Internal
           goto Hex;
         }
       }
-      return PdfEncoders.RawEncoding.GetBytes(pdf.ToString());
+      return RawEncoding.GetBytes(pdf.ToString());
     }
 
     /// <summary>
@@ -596,7 +601,7 @@ namespace PdfSharp.Pdf.Internal
     //}
 
     /// <summary>
-    /// ...because I always forget CultureInfo.InvariantCulture and wonder why Arcobat
+    /// ...because I always forget CultureInfo.InvariantCulture and wonder why Acrobat
     /// cannot understand my German decimal separator...
     /// </summary>
     public static string Format(string format, params object[] args)
@@ -619,12 +624,8 @@ namespace PdfSharp.Pdf.Internal
     {
       // If not defined let color decide
       if (colorMode == PdfColorMode.Undefined)
-      {
-        if (color.ColorSpace == XColorSpace.Cmyk)
-          colorMode = PdfColorMode.Cmyk;
-        else
-          colorMode = PdfColorMode.Rgb;
-      }
+        colorMode = color.ColorSpace == XColorSpace.Cmyk ? PdfColorMode.Cmyk : PdfColorMode.Rgb;
+
       switch (colorMode)
       {
         case PdfColorMode.Cmyk:
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Internal/RawEncoding.cs b/lib/PdfSharp/PdfSharp.Pdf.Internal/RawEncoding.cs
index abadebe..c51aaeb 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Internal/RawEncoding.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Internal/RawEncoding.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -28,6 +28,7 @@
 #endregion
 
 using System;
+using System.Diagnostics;
 using System.Text;
 
 namespace PdfSharp.Pdf.Internal
@@ -51,7 +52,10 @@ namespace PdfSharp.Pdf.Internal
     public override int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex)
     {
       for (int count = charCount; count > 0; charIndex++, byteIndex++, count--)
+      {
+        Debug.Assert((uint)chars[charIndex] < 256, "Raw string contains invalid character with a value > 255.");
         bytes[byteIndex] = (byte)chars[charIndex];
+      }
       return charCount;
     }
 
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Internal/RawUnicodeEncoding.cs b/lib/PdfSharp/PdfSharp.Pdf.Internal/RawUnicodeEncoding.cs
index 1a3cb01..e610ba8 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Internal/RawUnicodeEncoding.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Internal/RawUnicodeEncoding.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Internal/ThreadLocalStorage.cs b/lib/PdfSharp/PdfSharp.Pdf.Internal/ThreadLocalStorage.cs
index 707cba5..593cdfc 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Internal/ThreadLocalStorage.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Internal/ThreadLocalStorage.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -28,6 +28,7 @@
 #endregion
 
 using System;
+using System.Collections.Generic;
 using System.Diagnostics;
 using System.Collections;
 using System.Globalization;
@@ -47,7 +48,7 @@ namespace PdfSharp.Pdf.Internal
   {
     public ThreadLocalStorage()
     {
-      this.importedDocuments = new Hashtable(StringComparer.InvariantCultureIgnoreCase);
+      this.importedDocuments = new Dictionary<string, PdfDocument.DocumentHandle>(StringComparer.InvariantCultureIgnoreCase);
     }
 
     public void AddDocument(string path, PdfDocument document)
@@ -65,8 +66,8 @@ namespace PdfSharp.Pdf.Internal
       Debug.Assert(path.StartsWith("*") || Path.IsPathRooted(path), "Path must be full qualified.");
 
       PdfDocument document = null;
-      PdfDocument.DocumentHandle handle = this.importedDocuments[path] as PdfDocument.DocumentHandle;
-      if (handle != null)
+      PdfDocument.DocumentHandle handle;
+      if (this.importedDocuments.TryGetValue(path, out handle))
       {
         document = handle.Target;
         if (document == null)
@@ -84,13 +85,13 @@ namespace PdfSharp.Pdf.Internal
     {
       get
       {
-        ArrayList list = new ArrayList();
+        List<PdfDocument> list = new List<PdfDocument>();
         foreach (PdfDocument.DocumentHandle handle in this.importedDocuments.Values)
         {
           if (handle.IsAlive)
             list.Add(handle.Target);
         }
-        return (PdfDocument[])list.ToArray(typeof(PdfDocument));
+        return list.ToArray();
       }
     }
 
@@ -100,7 +101,7 @@ namespace PdfSharp.Pdf.Internal
       {
         foreach (String path in this.importedDocuments.Keys)
         {
-          if ((PdfDocument.DocumentHandle)this.importedDocuments[path] == handle)
+          if (this.importedDocuments[path] == handle)
           {
             this.importedDocuments.Remove(path);
             break;
@@ -115,7 +116,7 @@ namespace PdfSharp.Pdf.Internal
         itemRemoved = false;
         foreach (String path in this.importedDocuments.Keys)
         {
-          if (!((PdfDocument.DocumentHandle)this.importedDocuments[path]).IsAlive)
+          if (!this.importedDocuments[path].IsAlive)
           {
             this.importedDocuments.Remove(path);
             itemRemoved = true;
@@ -128,6 +129,6 @@ namespace PdfSharp.Pdf.Internal
     /// <summary>
     /// Maps path to document handle.
     /// </summary>
-    Hashtable importedDocuments;
+    readonly Dictionary<string, PdfDocument.DocumentHandle> importedDocuments;
   }
 }
\ No newline at end of file
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Printing/PdfFilePrinter.cs b/lib/PdfSharp/PdfSharp.Pdf.Printing/PdfFilePrinter.cs
index 8bb5c6e..d564cae 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Printing/PdfFilePrinter.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Printing/PdfFilePrinter.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -57,8 +57,8 @@ namespace PdfSharp.Pdf.Printing
   /// <summary>
   /// A wrapper around Adobe Reader or Adobe Acrobat that helps to print PDF files.
   /// The property AdobeReaderPath must be set before the class can be used for printing.
-  /// The class was testet with Adobe Reader 7.0.7.
-  /// If this stuff does not work, _please_ don't write me mails!
+  /// The class was tested with Adobe Reader 7.0.7.
+  /// If this stuff does not work, <c>please</c> don't write me mails!
   /// If you enhance this class, please let me know.
   /// </summary>
   public class PdfFilePrinter
@@ -151,7 +151,7 @@ namespace PdfSharp.Pdf.Printing
       else
         fqName = Path.Combine(Directory.GetCurrentDirectory(), this.pdfFileName);
       if (!File.Exists(fqName))
-        throw new InvalidOperationException(String.Format("The file {0} does not exists.", fqName));
+        throw new InvalidOperationException(String.Format("The file {0} does not exist.", fqName));
 
       // TODO: Check whether printer exists.
 
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Security/PdfSecurityHandler.cs b/lib/PdfSharp/PdfSharp.Pdf.Security/PdfSecurityHandler.cs
index 8b2e390..60fb4a5 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Security/PdfSecurityHandler.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Security/PdfSecurityHandler.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Security/PdfSecuritySettings.cs b/lib/PdfSharp/PdfSharp.Pdf.Security/PdfSecuritySettings.cs
index 681a1a7..423cde5 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Security/PdfSecuritySettings.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Security/PdfSecuritySettings.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -39,7 +39,7 @@ using PdfSharp.Drawing;
 namespace PdfSharp.Pdf.Security
 {
   /// <summary>
-  /// Encapsultes access to the security settings of a PDF document.
+  /// Encapsulates access to the security settings of a PDF document.
   /// </summary>
   public sealed class PdfSecuritySettings
   {
@@ -50,7 +50,7 @@ namespace PdfSharp.Pdf.Security
     PdfDocument document;
 
     /// <summary>
-    /// Indicates whether the granted access to the document is 'owner permission'. Retruns true if the document 
+    /// Indicates whether the granted access to the document is 'owner permission'. Returns true if the document 
     /// is unprotected or was opened with the owner password. Returns false if the document was opened with the
     /// user password.
     /// </summary>
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Security/PdfStandardSecurityHandler.cs b/lib/PdfSharp/PdfSharp.Pdf.Security/PdfStandardSecurityHandler.cs
index a6267b2..fa05f0f 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Security/PdfStandardSecurityHandler.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Security/PdfStandardSecurityHandler.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -28,6 +28,7 @@
 #endregion
 
 using System;
+using System.Collections.Generic;
 using System.Diagnostics;
 using System.Collections;
 using PdfSharp.Drawing;
@@ -47,13 +48,11 @@ namespace PdfSharp.Pdf.Security
   {
     internal PdfStandardSecurityHandler(PdfDocument document)
       : base(document)
-    {
-    }
+    { }
 
     internal PdfStandardSecurityHandler(PdfDictionary dict)
       : base(dict)
-    {
-    }
+    { }
 
     /// <summary>
     /// Sets the user password of the document. Setting a password automatically sets the
@@ -109,7 +108,7 @@ namespace PdfSharp.Pdf.Security
     {
       foreach (PdfReference iref in this.document.irefTable.AllReferences)
       {
-        if (!Object.ReferenceEquals(iref.Value, this))
+        if (!ReferenceEquals(iref.Value, this))
           EncryptObject(iref.Value);
       }
     }
@@ -152,7 +151,7 @@ namespace PdfSharp.Pdf.Security
     void EncryptDictionary(PdfDictionary dict)
     {
       PdfName[] names = dict.Elements.KeyNames;
-      foreach (DictionaryEntry item in dict.Elements)
+      foreach (KeyValuePair<string, PdfItem> item in dict.Elements)
       {
         PdfString value1;
         PdfDictionary value2;
@@ -230,16 +229,11 @@ namespace PdfSharp.Pdf.Security
     /// Checks the password.
     /// </summary>
     /// <param name="inputPassword">Password or null if no password is provided.</param>
-    /// <returns>
-    /// 0: inputPassword is neither user nor owner password.
-    /// 1: inputPassword is user password.
-    /// 2: inputPassword is owner password.
-    /// </returns>
-    public int ValidatePassword(string inputPassword)
+    public PasswordValidity ValidatePassword(string inputPassword)
     {
       // We can handle 40 and 128 bit standard encryption
       string filter = Elements.GetName(PdfSecurityHandler.Keys.Filter);
-      int v = Elements.GetInteger(Keys.V);
+      int v = Elements.GetInteger(PdfSecurityHandler.Keys.V);
       if (filter != "/Standard" || !(v >= 1 && v <= 3))
         throw new PdfReaderException(PSSR.UnknownEncryption);
 
@@ -249,13 +243,30 @@ namespace PdfSharp.Pdf.Security
       int pValue = Elements.GetInteger(Keys.P);
       int rValue = Elements.GetInteger(Keys.R);
 
-      byte[] password;
       if (inputPassword == null)
         inputPassword = "";
 
       bool strongEncryption = rValue == 3;
       int keyLength = strongEncryption ? 16 : 32;
 
+#if true
+      // Try owner password first
+      byte[] password = PdfEncoders.RawEncoding.GetBytes(inputPassword);
+      InitWidhOwnerPassword(documentID, inputPassword, oValue, pValue, strongEncryption);
+      if (EqualsKey(uValue, keyLength))
+      {
+        this.document.SecuritySettings.hasOwnerPermissions = true;
+        return PasswordValidity.OwnerPassword;
+      }
+      this.document.SecuritySettings.hasOwnerPermissions = false;
+
+      // Now try user password
+      password = PdfEncoders.RawEncoding.GetBytes(inputPassword);
+      InitWidhUserPassword(documentID, inputPassword, oValue, pValue, strongEncryption);
+      if (!EqualsKey(uValue, keyLength))
+        return PasswordValidity.Invalid;
+      return PasswordValidity.UserPassword;
+#else
       password = PdfEncoders.RawEncoding.GetBytes(inputPassword);
       InitWidhUserPassword(documentID, inputPassword, oValue, pValue, strongEncryption);
 
@@ -265,7 +276,7 @@ namespace PdfSharp.Pdf.Security
       {
         password = PdfEncoders.RawEncoding.GetBytes(inputPassword);
 
-        //Compare owner password
+        // Compare owner password
         InitWidhOwnerPassword(documentID, inputPassword, oValue, pValue, strongEncryption);
 
         if (!EqualsKey(uValue, keyLength))
@@ -280,10 +291,11 @@ namespace PdfSharp.Pdf.Security
         return 2;
       }
       return 1;
+#endif
     }
 
     [Conditional("DEBUG")]
-    void DumpBytes(string tag, byte[] bytes)
+    static void DumpBytes(string tag, byte[] bytes)
     {
       string dump = tag + ": ";
       for (int idx = 0; idx < bytes.Length; idx++)
@@ -294,7 +306,7 @@ namespace PdfSharp.Pdf.Security
     /// <summary>
     /// Pads a password to a 32 byte array.
     /// </summary>
-    byte[] PadPassword(string password)
+    static byte[] PadPassword(string password)
     {
       byte[] padded = new byte[32];
       if (password == null)
@@ -339,7 +351,7 @@ namespace PdfSharp.Pdf.Security
     byte[] ComputeOwnerKey(byte[] userPad, byte[] ownerPad, bool strongEncryption)
     {
       byte[] ownerKey = new byte[32];
-
+#if !SILVERLIGHT
       byte[] digest = this.md5.ComputeHash(ownerPad);
       if (strongEncryption)
       {
@@ -362,6 +374,7 @@ namespace PdfSharp.Pdf.Security
         PrepareRC4Key(digest, 0, 5);
         EncryptRC4(userPad, ownerKey);
       }
+#endif
       return ownerKey;
     }
 
@@ -370,6 +383,7 @@ namespace PdfSharp.Pdf.Security
     /// </summary>
     void InitEncryptionKey(byte[] documentID, byte[] userPad, byte[] ownerKey, int permissions, bool strongEncryption)
     {
+#if !SILVERLIGHT
       this.ownerKey = ownerKey;
       this.encryptionKey = new byte[strongEncryption ? 16 : 5];
 
@@ -398,6 +412,7 @@ namespace PdfSharp.Pdf.Security
         }
       }
       Array.Copy(digest, 0, this.encryptionKey, 0, this.encryptionKey.Length);
+#endif
     }
 
     /// <summary>
@@ -405,6 +420,7 @@ namespace PdfSharp.Pdf.Security
     /// </summary>
     void SetupUserKey(byte[] documentID)
     {
+#if !SILVERLIGHT
       if (this.encryptionKey.Length == 16)
       {
         this.md5.TransformBlock(passwordPadding, 0, passwordPadding.Length, passwordPadding, 0);
@@ -428,6 +444,7 @@ namespace PdfSharp.Pdf.Security
         PrepareRC4Key(this.encryptionKey);
         EncryptRC4(passwordPadding, this.userKey);
       }
+#endif
     }
 
     /// <summary>
@@ -527,6 +544,7 @@ namespace PdfSharp.Pdf.Security
     /// </summary>
     internal void SetHashKey(PdfObjectID id)
     {
+#if !SILVERLIGHT
       byte[] objectId = new byte[5];
       this.md5.Initialize();
       // Split the object number and generation
@@ -542,6 +560,7 @@ namespace PdfSharp.Pdf.Security
       this.keySize = this.encryptionKey.Length + 5;
       if (this.keySize > 16)
         this.keySize = 16;
+#endif
     }
 
     /// <summary>
@@ -549,6 +568,7 @@ namespace PdfSharp.Pdf.Security
     /// </summary>
     public void PrepareEncryption()
     {
+#if !SILVERLIGHT
       Debug.Assert(this.document.securitySettings.DocumentSecurityLevel != PdfDocumentSecurityLevel.None);
       int permissions = (int)this.Permission;
       bool strongEncryption = this.document.securitySettings.DocumentSecurityLevel == PdfDocumentSecurityLevel.Encrypted128Bit;
@@ -570,10 +590,10 @@ namespace PdfSharp.Pdf.Security
         rValue = new PdfInteger(2);
       }
 
-      if (this.userPassword == null || this.userPassword.Length == 0)
+      if (String.IsNullOrEmpty(this.userPassword))
         this.userPassword = "";
       // Use user password twice if no owner password provided.
-      if (this.ownerPassword == null || this.ownerPassword.Length == 0)
+      if (String.IsNullOrEmpty(this.ownerPassword))
         this.ownerPassword = this.userPassword;
 
       // Correct permission bits
@@ -601,6 +621,7 @@ namespace PdfSharp.Pdf.Security
       Elements[Keys.O] = oValue;
       Elements[Keys.U] = uValue;
       Elements[Keys.P] = pValue;
+#endif
     }
 
     /// <summary>
@@ -608,10 +629,12 @@ namespace PdfSharp.Pdf.Security
     /// </summary>
     byte[] encryptionKey;
 
+#if !SILVERLIGHT
     /// <summary>
     /// The message digest algorithm MD5.
     /// </summary>
     MD5 md5 = new MD5CryptoServiceProvider();
+#endif
 
     /// <summary>
     /// Bytes used for RC4 encryption.
@@ -706,9 +729,9 @@ namespace PdfSharp.Pdf.Security
       {
         get
         {
-          if (Keys.meta == null)
-            Keys.meta = CreateMeta(typeof(Keys));
-          return Keys.meta;
+          if (meta == null)
+            meta = CreateMeta(typeof(Keys));
+          return meta;
         }
       }
       static DictionaryMeta meta;
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Security/enums/PdfDocumentSecurity.cs b/lib/PdfSharp/PdfSharp.Pdf.Security/enums/PdfDocumentSecurity.cs
index aa1d015..40f70f0 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Security/enums/PdfDocumentSecurity.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Security/enums/PdfDocumentSecurity.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Pdf.Security/enums/PdfUserAccessPermission.cs b/lib/PdfSharp/PdfSharp.Pdf.Security/enums/PdfUserAccessPermission.cs
index 5858cf2..c4806c3 100644
--- a/lib/PdfSharp/PdfSharp.Pdf.Security/enums/PdfUserAccessPermission.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf.Security/enums/PdfUserAccessPermission.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Pdf/EntryInfoAttribute.cs b/lib/PdfSharp/PdfSharp.Pdf/EntryInfoAttribute.cs
index 89e2d1f..9e7b9c3 100644
--- a/lib/PdfSharp/PdfSharp.Pdf/EntryInfoAttribute.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf/EntryInfoAttribute.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -34,7 +34,7 @@ using System.Collections;
 namespace PdfSharp.Pdf
 {
   /// <summary>
-  /// Specifes the type of a key's value in a dictionary.
+  /// Specifies the type of a key's value in a dictionary.
   /// </summary>
   [Flags]
   internal enum KeyType
diff --git a/lib/PdfSharp/PdfSharp.Pdf/KeysBase.cs b/lib/PdfSharp/PdfSharp.Pdf/KeysBase.cs
index b2bfb0c..f96ddfe 100644
--- a/lib/PdfSharp/PdfSharp.Pdf/KeysBase.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf/KeysBase.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Pdf/KeysMeta.cs b/lib/PdfSharp/PdfSharp.Pdf/KeysMeta.cs
index 4fd61e3..51df990 100644
--- a/lib/PdfSharp/PdfSharp.Pdf/KeysMeta.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf/KeysMeta.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -29,7 +29,7 @@
 
 using System;
 using System.Diagnostics;
-using System.Collections;
+using System.Collections.Generic;
 using System.Reflection;
 using PdfSharp.Pdf.IO;
 
@@ -37,7 +37,7 @@ namespace PdfSharp.Pdf
 {
   /// <summary>
   /// Hold information about the value of a key in a dictionary. This information is used to create
-  /// interpred this value.
+  /// and interpret this value.
   /// </summary>
   internal sealed class KeyDescriptor
   {
@@ -167,7 +167,7 @@ namespace PdfSharp.Pdf
             throw new NotImplementedException("KeyType.ArrayOrNameOrString");
 
           default:
-            Debug.Assert(false, "Invalid KeyType: " + this.keyType.ToString());
+            Debug.Assert(false, "Invalid KeyType: " + this.keyType);
             break;
         }
       }
@@ -198,9 +198,9 @@ namespace PdfSharp.Pdf
 
     public KeyDescriptor this[string key]
     {
-      get { return (KeyDescriptor)this.keyDescriptors[key]; }
+      get { return this.keyDescriptors[key]; }
     }
 
-    Hashtable keyDescriptors = new Hashtable();
+    readonly Dictionary<string, KeyDescriptor> keyDescriptors = new Dictionary<string, KeyDescriptor>();
   }
 }
diff --git a/lib/PdfSharp/PdfSharp.Pdf/PdfArray.cs b/lib/PdfSharp/PdfSharp.Pdf/PdfArray.cs
index 8d16fbe..c420123 100644
--- a/lib/PdfSharp/PdfSharp.Pdf/PdfArray.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf/PdfArray.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -28,6 +28,7 @@
 #endregion
 
 using System;
+using System.Collections.Generic;
 using System.Diagnostics;
 using System.Collections;
 using System.Text;
@@ -42,7 +43,7 @@ namespace PdfSharp.Pdf
   /// Represents a PDF array object.
   /// </summary>
   [DebuggerDisplay("(elements={Elements.Count})")]
-  public class PdfArray : PdfObject, IEnumerable
+  public class PdfArray : PdfObject, IEnumerable<PdfItem>
   {
     ArrayElements elements;
 
@@ -130,11 +131,16 @@ namespace PdfSharp.Pdf
     /// <summary>
     /// Returns an enumerator that iterates through a collection.
     /// </summary>
-    public virtual IEnumerator GetEnumerator()
+    public virtual IEnumerator<PdfItem> GetEnumerator()
     {
       return Elements.GetEnumerator();
     }
 
+    IEnumerator IEnumerable.GetEnumerator()
+    {
+      return GetEnumerator();
+    }
+
     /// <summary>
     /// Returns a string with the content of this object in a readable form. Useful for debugging purposes only.
     /// </summary>
@@ -164,21 +170,21 @@ namespace PdfSharp.Pdf
     /// <summary>
     /// Represents the elements of an PdfArray.
     /// </summary>
-    public sealed class ArrayElements : IList, ICloneable
+    public sealed class ArrayElements : IList<PdfItem>, ICloneable
     {
-      ArrayList elements;
+      List<PdfItem> elements;
       PdfArray owner;
 
       internal ArrayElements(PdfArray array)
       {
-        this.elements = new ArrayList();
+        this.elements = new List<PdfItem>();
         this.owner = array;
       }
 
       object ICloneable.Clone()
       {
         ArrayElements elements = (ArrayElements)MemberwiseClone();
-        elements.elements = (ArrayList)elements.elements.Clone();
+        elements.elements = new List<PdfItem>(elements.elements);
         elements.owner = null;
         return elements;
       }
@@ -204,7 +210,7 @@ namespace PdfSharp.Pdf
       /// Converts the specified value to boolean.
       /// If the value not exists, the function returns false.
       /// If the value is not convertible, the function throws an InvalidCastException.
-      /// If the index is out ouf range, the function throws an ArgumentOutOfRangeException.
+      /// If the index is out of range, the function throws an ArgumentOutOfRangeException.
       /// </summary>
       public bool GetBoolean(int index)
       {
@@ -225,7 +231,7 @@ namespace PdfSharp.Pdf
       /// Converts the specified value to integer.
       /// If the value not exists, the function returns 0.
       /// If the value is not convertible, the function throws an InvalidCastException.
-      /// If the index is out ouf range, the function throws an ArgumentOutOfRangeException.
+      /// If the index is out of range, the function throws an ArgumentOutOfRangeException.
       /// </summary>
       public int GetInteger(int index)
       {
@@ -246,7 +252,7 @@ namespace PdfSharp.Pdf
       /// Converts the specified value to double.
       /// If the value not exists, the function returns 0.
       /// If the value is not convertible, the function throws an InvalidCastException.
-      /// If the index is out ouf range, the function throws an ArgumentOutOfRangeException.
+      /// If the index is out of range, the function throws an ArgumentOutOfRangeException.
       /// </summary>
       public double GetReal(int index)
       {
@@ -271,7 +277,7 @@ namespace PdfSharp.Pdf
       /// Converts the specified value to string.
       /// If the value not exists, the function returns the empty string.
       /// If the value is not convertible, the function throws an InvalidCastException.
-      /// If the index is out ouf range, the function throws an ArgumentOutOfRangeException.
+      /// If the index is out of range, the function throws an ArgumentOutOfRangeException.
       /// </summary>
       public string GetString(int index)
       {
@@ -292,7 +298,7 @@ namespace PdfSharp.Pdf
       /// Converts the specified value to a name.
       /// If the value not exists, the function returns the empty string.
       /// If the value is not convertible, the function throws an InvalidCastException.
-      /// If the index is out ouf range, the function throws an ArgumentOutOfRangeException.
+      /// If the index is out of range, the function throws an ArgumentOutOfRangeException.
       /// </summary>
       public string GetName(int index)
       {
@@ -371,18 +377,18 @@ namespace PdfSharp.Pdf
       /// </summary>
       public PdfItem[] Items
       {
-        get { return (PdfItem[])this.elements.ToArray(typeof(PdfItem)); }
+        get { return this.elements.ToArray(); }
       }
 
-      /// <summary>
-      /// INTERNAL USE ONLY.
-      /// </summary>
-      public ArrayList GetArrayList()
-      {
-        // I use this hack to order the pages by ZIP code (MigraDoc ControlCode-Generator)
-        // TODO: implement a clean solution
-        return this.elements;
-      }
+      ///// <summary>
+      ///// INTERNAL USE ONLY.
+      ///// </summary>
+      //public List<PdfItem> GetArrayList_()
+      //{
+      //  // I use this hack to order the pages by ZIP code (MigraDoc ControlCode-Generator)
+      //  // TODO: implement a clean solution
+      //  return this.elements;
+      //}
 
       #region IList Members
 
@@ -394,11 +400,11 @@ namespace PdfSharp.Pdf
         get { return false; }
       }
 
-      object IList.this[int index]
-      {
-        get { return this.elements[index]; }
-        set { this.elements[index] = value; }
-      }
+      //object IList.this[int index]
+      //{
+      //  get { return this.elements[index]; }
+      //  set { this.elements[index] = value as PdfItem; }
+      //}
 
       /// <summary>
       /// Gets or sets an item at the specified index.
@@ -406,7 +412,7 @@ namespace PdfSharp.Pdf
       /// <value></value>
       public PdfItem this[int index]
       {
-        get { return (PdfItem)this.elements[index]; }
+        get { return this.elements[index]; }
         set
         {
           if (value == null)
@@ -423,9 +429,12 @@ namespace PdfSharp.Pdf
         this.elements.RemoveAt(index);
       }
 
-      void IList.Insert(int index, object value)
+      /// <summary>
+      /// Removes the first occurrence of a specific object from the array/>.
+      /// </summary>
+      public bool Remove(PdfItem item)
       {
-        this.elements.Insert(index, value);
+        return this.elements.Remove(item);
       }
 
       /// <summary>
@@ -436,24 +445,6 @@ namespace PdfSharp.Pdf
         this.elements.Insert(index, value);
       }
 
-      void IList.Remove(object value)
-      {
-        this.elements.Remove(value);
-      }
-
-      /// <summary>
-      /// Removes the specified value.
-      /// </summary>
-      public void Remove(PdfItem value)
-      {
-        this.elements.Remove(value);
-      }
-
-      bool IList.Contains(object value)
-      {
-        return this.elements.Contains(value);
-      }
-
       /// <summary>
       /// Determines whether the specified value is in the array.
       /// </summary>
@@ -470,11 +461,6 @@ namespace PdfSharp.Pdf
         this.elements.Clear();
       }
 
-      int IList.IndexOf(object value)
-      {
-        return this.elements.IndexOf(value);
-      }
-
       /// <summary>
       /// Gets the index of the specified item.
       /// </summary>
@@ -483,15 +469,10 @@ namespace PdfSharp.Pdf
         return this.elements.IndexOf(value);
       }
 
-      int IList.Add(object value)
-      {
-        return this.elements.Add(value);
-      }
-
       /// <summary>
       /// Appends the specified object to the array.
       /// </summary>
-      public int Add(PdfItem value)
+      public void Add(PdfItem value)
       {
         // TODO: ??? 
         //Debug.Assert((value is PdfObject && ((PdfObject)value).Reference == null) | !(value is PdfObject),
@@ -499,8 +480,9 @@ namespace PdfSharp.Pdf
 
         PdfObject obj = value as PdfObject;
         if (obj != null && obj.IsIndirect)
-          return this.elements.Add(obj.Reference);
-        return this.elements.Add(value);
+          this.elements.Add(obj.Reference);
+        else
+          this.elements.Add(value);
       }
 
       /// <summary>
@@ -534,7 +516,7 @@ namespace PdfSharp.Pdf
       /// <summary>
       /// Copies the elements of the array to the specified array.
       /// </summary>
-      public void CopyTo(Array array, int index)
+      public void CopyTo(PdfItem[] array, int index)
       {
         this.elements.CopyTo(array, index);
       }
@@ -549,17 +531,18 @@ namespace PdfSharp.Pdf
 
       #endregion
 
-      #region IEnumerable Members
-
       /// <summary>
       /// Returns an enumerator that iterates through the array.
       /// </summary>
-      public IEnumerator GetEnumerator()
+      public IEnumerator<PdfItem> GetEnumerator()
       {
         return this.elements.GetEnumerator();
       }
 
-      #endregion
+      IEnumerator IEnumerable.GetEnumerator()
+      {
+        return this.elements.GetEnumerator();
+      }
     }
   }
 }
diff --git a/lib/PdfSharp/PdfSharp.Pdf/PdfBoolean.cs b/lib/PdfSharp/PdfSharp.Pdf/PdfBoolean.cs
index 16296e0..a221e02 100644
--- a/lib/PdfSharp/PdfSharp.Pdf/PdfBoolean.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf/PdfBoolean.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Pdf/PdfBooleanObject.cs b/lib/PdfSharp/PdfSharp.Pdf/PdfBooleanObject.cs
index 9f34d04..f6527ee 100644
--- a/lib/PdfSharp/PdfSharp.Pdf/PdfBooleanObject.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf/PdfBooleanObject.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Pdf/PdfCustomValue.cs b/lib/PdfSharp/PdfSharp.Pdf/PdfCustomValue.cs
index 564325c..1c85f3e 100644
--- a/lib/PdfSharp/PdfSharp.Pdf/PdfCustomValue.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf/PdfCustomValue.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -34,12 +34,12 @@ using System.Collections;
 namespace PdfSharp.Pdf
 {
   /// <summary>
-  /// This class is intended for empira interanl use only and may change or drop in future releases.
+  /// This class is intended for empira internal use only and may change or drop in future releases.
   /// </summary>
   public class PdfCustomValue : PdfDictionary
   {
     /// <summary>
-    /// This function is intended for empira interanl use only.
+    /// This function is intended for empira internal use only.
     /// </summary>
     public PdfCustomValue()
     {
@@ -47,7 +47,7 @@ namespace PdfSharp.Pdf
     }
 
     /// <summary>
-    /// This function is intended for empira interanl use only.
+    /// This function is intended for empira internal use only.
     /// </summary>
     public PdfCustomValue(byte[] bytes)
     {
@@ -67,12 +67,12 @@ namespace PdfSharp.Pdf
     }
 
     /// <summary>
-    /// This property is intended for empira interanl use only.
+    /// This property is intended for empira internal use only.
     /// </summary>
     public PdfCustomValueCompressionMode CompressionMode;
 
     /// <summary>
-    /// This property is intended for empira interanl use only.
+    /// This property is intended for empira internal use only.
     /// </summary>
     public byte[] Value
     {
diff --git a/lib/PdfSharp/PdfSharp.Pdf/PdfCustomValues.cs b/lib/PdfSharp/PdfSharp.Pdf/PdfCustomValues.cs
index dd796c1..19864b2 100644
--- a/lib/PdfSharp/PdfSharp.Pdf/PdfCustomValues.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf/PdfCustomValues.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -68,7 +68,7 @@ namespace PdfSharp.Pdf
     /// </summary>
     public bool Contains(string key)
     {
-      return Elements.Contains(key);
+      return Elements.ContainsKey(key);
     }
 
     /// <summary>
diff --git a/lib/PdfSharp/PdfSharp.Pdf/PdfDate.cs b/lib/PdfSharp/PdfSharp.Pdf/PdfDate.cs
index d2ae02b..fd7fa2b 100644
--- a/lib/PdfSharp/PdfSharp.Pdf/PdfDate.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf/PdfDate.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Pdf/PdfDictionary.cs b/lib/PdfSharp/PdfSharp.Pdf/PdfDictionary.cs
index 0d3224e..77256dd 100644
--- a/lib/PdfSharp/PdfSharp.Pdf/PdfDictionary.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf/PdfDictionary.cs
@@ -1,9 +1,9 @@
-#region PDFsharp - A .NET library for processing PDF
+#region PDFsharp - A .NET library for processing PDF
 //
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -30,6 +30,7 @@
 using System;
 using System.Diagnostics;
 using System.Collections;
+using System.Collections.Generic;
 using System.Reflection;
 using System.Text;
 using System.IO;
@@ -70,7 +71,7 @@ namespace PdfSharp.Pdf
   public class PdfDictionary : PdfObject, IEnumerable
   {
     /// <summary>
-    /// The elemets of the dictionary.
+    /// The elements of the dictionary.
     /// </summary>
     protected DictionaryElements elements;
 
@@ -113,7 +114,7 @@ namespace PdfSharp.Pdf
 
     /// <summary>
     /// This function is useful for importing objects from external documents. The returned object is not
-    /// yet complete. irefs refer to external objects and directed objects are coloned but their document
+    /// yet complete. irefs refer to external objects and directed objects are cloned but their document
     /// property is null. A cloned dictionary or array needs a 'fix-up' to be a valid object.
     /// </summary>
     protected override object Copy()
@@ -171,14 +172,14 @@ namespace PdfSharp.Pdf
     {
       // Get keys and sort
       PdfName[] keys = Elements.KeyNames;
-      ArrayList list = new ArrayList(keys);
-      list.Sort(PdfName.Comparer);
+      List<PdfName> list = new List<PdfName>(keys);
+      list.Sort((IComparer<PdfName>)PdfName.Comparer);
       list.CopyTo(keys, 0);
 
       StringBuilder pdf = new StringBuilder();
       pdf.Append("<< ");
       foreach (PdfName key in keys)
-        pdf.Append(key.ToString() + " " + Elements[key].ToString() + " ");
+        pdf.Append(key + " " + this.Elements[key] + " ");
       pdf.Append(">>");
 
       return pdf.ToString();
@@ -193,7 +194,7 @@ namespace PdfSharp.Pdf
 #if DEBUG
       // TODO: automatically set length
       if (this.stream != null)
-        Debug.Assert(Elements.Contains(PdfDictionary.PdfStream.Keys.Length), "Dictionary has a stream but no length is set.");
+        Debug.Assert(Elements.ContainsKey(PdfStream.Keys.Length), "Dictionary has a stream but no length is set.");
 #endif
 
 #if DEBUG
@@ -201,7 +202,7 @@ namespace PdfSharp.Pdf
       // Araxis Merge is easier with sorted keys.
       if (writer.Layout == PdfWriterLayout.Verbose)
       {
-        ArrayList list = new ArrayList(keys);
+        List<PdfName> list = new List<PdfName>(keys);
         list.Sort(PdfName.Comparer);
         list.CopyTo(keys, 0);
       }
@@ -259,7 +260,7 @@ namespace PdfSharp.Pdf
 
     /// <summary>
     /// Creates the stream of this dictionary and initializes it with the specified byte array.
-    /// The function must not be called if the dictionary already has a strem.
+    /// The function must not be called if the dictionary already has a stream.
     /// </summary>
     public PdfStream CreateStream(byte[] value)
     {
@@ -283,23 +284,23 @@ namespace PdfSharp.Pdf
     /// <summary>
     /// Represents the interface to the elements of a PDF dictionary.
     /// </summary>
-    public sealed class DictionaryElements : IDictionary, ICloneable
+    public sealed class DictionaryElements : IDictionary<string, PdfItem>, ICloneable
     {
-      Hashtable elements;
+      Dictionary<string, PdfItem> elements;
       PdfDictionary owner;
 
       internal DictionaryElements(PdfDictionary dict)
       {
-        this.elements = new Hashtable();
+        this.elements = new Dictionary<string, PdfItem>();
         this.owner = dict;
       }
 
       object ICloneable.Clone()
       {
-        DictionaryElements elements = (DictionaryElements)MemberwiseClone();
-        elements.elements = (Hashtable)elements.elements.Clone();
-        elements.owner = null;
-        return elements;
+        DictionaryElements dictionaryElements = (DictionaryElements)MemberwiseClone();
+        dictionaryElements.elements = new Dictionary<string, PdfItem>(dictionaryElements.elements);
+        dictionaryElements.owner = null;
+        return dictionaryElements;
       }
 
       /// <summary>
@@ -439,12 +440,16 @@ namespace PdfSharp.Pdf
 
         if (obj is PdfReal)
           return ((PdfReal)obj).Value;
-        else if (obj is PdfRealObject)
+        
+        if (obj is PdfRealObject)
           return ((PdfRealObject)obj).Value;
-        else if (obj is PdfInteger)
+        
+        if (obj is PdfInteger)
           return ((PdfInteger)obj).Value;
-        else if (obj is PdfIntegerObject)
+        
+        if (obj is PdfIntegerObject)
           return ((PdfIntegerObject)obj).Value;
+        
         throw new InvalidCastException("GetReal: Object is not a number.");
       }
 
@@ -484,12 +489,16 @@ namespace PdfSharp.Pdf
 
         if (obj is PdfString)
           return ((PdfString)obj).Value;
-        else if (obj is PdfStringObject)
+        
+        if (obj is PdfStringObject)
           return ((PdfStringObject)obj).Value;
-        else if (obj is PdfName)
+        
+        if (obj is PdfName)
           return ((PdfName)obj).Value;
-        else if (obj is PdfNameObject)
+        
+        if (obj is PdfNameObject)
           return ((PdfNameObject)obj).Value;
+        
         throw new InvalidCastException("GetString: Object is not a string.");
       }
 
@@ -528,7 +537,8 @@ namespace PdfSharp.Pdf
 
         if (obj is PdfName)
           return ((PdfName)obj).Value;
-        else if (obj is PdfNameObject)
+        
+        if (obj is PdfNameObject)
           return ((PdfNameObject)obj).Value;
 
         throw new InvalidCastException("GetName: Object is not a name.");
@@ -664,11 +674,11 @@ namespace PdfSharp.Pdf
         if (obj is PdfDate)
           return ((PdfDate)obj).Value;
 
-        string date = "";
+        string date;
         if (obj is PdfString)
           date = ((PdfString)obj).Value;
         else if (obj is PdfStringObject)
-          date = ((PdfStringObject)obj).Value;
+          date = ((PdfNameObject)obj).Value;
         else
           throw new InvalidCastException("GetName: Object is not a name.");
 
@@ -704,7 +714,7 @@ namespace PdfSharp.Pdf
           return (int)defaultValue;
         }
         Debug.Assert(obj is Enum);
-        return (int)Enum.Parse(defaultValue.GetType(), obj.ToString().Substring(1));
+        return (int)Enum.Parse(defaultValue.GetType(), obj.ToString().Substring(1), false);
       }
 
       internal int GetEnumFromName(string key, object defaultValue)
@@ -716,11 +726,11 @@ namespace PdfSharp.Pdf
       {
         if (!(value is Enum))
           throw new ArgumentException("value");
-        this.elements[key] = new PdfName("/" + value.ToString());
+        this.elements[key] = new PdfName("/" + value);
       }
 
       /// <summary>
-      /// Gets the value for the specified key. If the value does not exists, it is optionally created.
+      /// Gets the value for the specified key. If the value does not exist, it is optionally created.
       /// </summary>
       public PdfItem GetValue(string key, VCF options)
       {
@@ -762,7 +772,7 @@ namespace PdfSharp.Pdf
         }
         else
         {
-          // The value exists and can returned. But for imported documents check for neccessary
+          // The value exists and can returned. But for imported documents check for necessary
           // object type transformation.
           if ((iref = value as PdfReference) != null)
           {
@@ -811,7 +821,8 @@ namespace PdfSharp.Pdf
                 dict = CreateDictionary(type, dict);
               return dict;
             }
-            else if ((array = value as PdfArray) != null)
+            
+            if ((array = value as PdfArray) != null)
             {
               Type type = GetValueType(key);
               Debug.Assert(type != null, "No value type specified in meta information. Please send this file to PDFsharp support.");
@@ -910,7 +921,7 @@ namespace PdfSharp.Pdf
           if (obj is PdfDictionary)
           {
             PdfDictionary dict = (PdfDictionary)obj;
-            dict.elements = ((PdfDictionary)oldValue).elements;
+            dict.elements = oldValue.elements;
           }
         }
         return obj;
@@ -1014,29 +1025,34 @@ namespace PdfSharp.Pdf
       /// <summary>
       /// Returns an <see cref="T:System.Collections.IDictionaryEnumerator"></see> object for the <see cref="T:System.Collections.IDictionary"></see> object.
       /// </summary>
-      public IDictionaryEnumerator GetEnumerator()
+      public IEnumerator<KeyValuePair<string, PdfItem>> GetEnumerator()
       {
         return this.elements.GetEnumerator();
       }
 
-      object IDictionary.this[object key]
+      IEnumerator IEnumerable.GetEnumerator()
       {
-        get { return this.elements[key]; }
-        set
-        {
-          if (key == null)
-            throw new ArgumentNullException("key");
-          if (!(key is string))
-            throw new ArgumentException("Key must be of type System.String.");
-          if (((string)key) == "")
-            throw new ArgumentException(PSSR.NameMustStartWithSlash, "key");
-          if (((string)key)[0] != '/')
-            throw new ArgumentException(PSSR.NameMustStartWithSlash, "key");
-
-          this.elements[key] = value;
-        }
+        return ((ICollection)this.elements).GetEnumerator();
       }
 
+      //object IDictionary.this[object key]
+      //{
+      //  get { return this.elements[key]; }
+      //  set
+      //  {
+      //    if (key == null)
+      //      throw new ArgumentNullException("key");
+      //    if (!(key is string))
+      //      throw new ArgumentException("Key must be of type System.String.");
+      //    if (((string)key) == "")
+      //      throw new ArgumentException(PSSR.NameMustStartWithSlash, "key");
+      //    if (((string)key)[0] != '/')
+      //      throw new ArgumentException(PSSR.NameMustStartWithSlash, "key");
+
+      //    this.elements[key] = value;
+      //  }
+      //}
+
       /// <summary>
       /// Gets or sets an entry in the dictionary. The specified key must be a valid PDF name
       /// starting with a slash '/'. This property provides full access to the elements of the
@@ -1044,7 +1060,12 @@ namespace PdfSharp.Pdf
       /// </summary>
       public PdfItem this[string key]
       {
-        get { return (PdfItem)((IDictionary)this)[key]; }
+        get
+        {
+          PdfItem item;
+          this.elements.TryGetValue(key, out item);
+          return item;
+        }
         set
         {
           if (value == null)
@@ -1068,11 +1089,8 @@ namespace PdfSharp.Pdf
 #endif
           PdfObject obj = value as PdfObject;
           if (obj != null && obj.IsIndirect)
-          {
-            ((IDictionary)this)[key] = obj.Reference;
-            return;
-          }
-          ((IDictionary)this)[key] = value;
+            value = obj.Reference;
+          this.elements[key] = value;
         }
       }
 
@@ -1081,8 +1099,8 @@ namespace PdfSharp.Pdf
       /// </summary>
       public PdfItem this[PdfName key]
       {
-        get { return (PdfItem)((IDictionary)this)[key.Value]; }
-        set 
+        get { return this[key.Value]; }
+        set
         {
           if (value == null)
             throw new ArgumentNullException("value");
@@ -1098,38 +1116,50 @@ namespace PdfSharp.Pdf
 
           PdfObject obj = value as PdfObject;
           if (obj != null && obj.IsIndirect)
-          {
-            ((IDictionary)this)[key] = obj.Reference;
-            return;
-          }
-          ((IDictionary)this)[key.Value] = value; 
+            value = obj.Reference;
+          this.elements[key.Value] = value;
         }
       }
 
-      void IDictionary.Remove(object key)
+      /// <summary>
+      /// Removes the value with the specified key.
+      /// </summary>
+      public bool Remove(string key)
       {
-        this.elements.Remove(key);
+        return this.elements.Remove(key);
       }
 
       /// <summary>
       /// Removes the value with the specified key.
       /// </summary>
-      public void Remove(string key)
+      public bool Remove(KeyValuePair<string, PdfItem> item)
       {
-        this.elements.Remove(key);
+        throw new NotImplementedException();
       }
 
-      bool IDictionary.Contains(object key)
+      /// <summary>
+      /// Determines whether the dictionary contains the specified name.
+      /// </summary>
+      [Obsolete("Use ContainsKey.")]
+      public bool Contains(string key)
       {
-        return this.elements.Contains(key);
+        return this.elements.ContainsKey(key);
       }
 
       /// <summary>
       /// Determines whether the dictionary contains the specified name.
       /// </summary>
-      public bool Contains(string key)
+      public bool ContainsKey(string key)
       {
-        return this.elements.Contains(key);
+        return this.elements.ContainsKey(key);
+      }
+
+      /// <summary>
+      /// Determines whether the dictionary contains a specific value.
+      /// </summary>
+      public bool Contains(KeyValuePair<string, PdfItem> item)
+      {
+        throw new NotImplementedException();
       }
 
       /// <summary>
@@ -1140,17 +1170,36 @@ namespace PdfSharp.Pdf
         this.elements.Clear();
       }
 
-      void IDictionary.Add(object key, object value)
+      //void IDictionary.Add(object key, object value)
+      //{
+      //  if (key == null)
+      //    throw new ArgumentNullException("key");
+      //  if (key is PdfName)
+      //    key = (key as PdfName).Value;
+      //  if (!(key is string))
+      //    throw new ArgumentException("key must be of type System.String.");
+      //  if (((string)key) == "")
+      //    throw new ArgumentException("key");
+      //  if (((string)key)[0] != '/')
+      //    throw new ArgumentException("The key must start with a slash '/'.");
+
+      //  // If object is indirect automatically convert value to reference.
+      //  PdfObject obj = value as PdfObject;
+      //  if (obj != null && obj.IsIndirect)
+      //    value = obj.Reference;
+
+      //  this.elements.Add(key, value);
+      //}
+
+      /// <summary>
+      /// Adds the specified value to the dictionary.
+      /// </summary>
+      public void Add(string key, PdfItem value)
       {
-        if (key == null)
+        if (String.IsNullOrEmpty(key))
           throw new ArgumentNullException("key");
-        if (key is PdfName)
-          key = (key as PdfName).Value;
-        if (!(key is string))
-          throw new ArgumentException("key must be of type System.String.");
-        if (((string)key) == "")
-          throw new ArgumentException("key");
-        if (((string)key)[0] != '/')
+
+        if (key[0] != '/')
           throw new ArgumentException("The key must start with a slash '/'.");
 
         // If object is indirect automatically convert value to reference.
@@ -1162,16 +1211,11 @@ namespace PdfSharp.Pdf
       }
 
       /// <summary>
-      /// Adds the specified value to the dictionary.
+      /// Adds an item to the dictionary.
       /// </summary>
-      public void Add(object key, PdfItem value)
-      {
-        ((IDictionary)this).Add(key, value);
-      }
-
-      ICollection IDictionary.Keys
+      public void Add(KeyValuePair<string, PdfItem> item)
       {
-        get { return this.elements.Keys; }
+        Add(item.Key, item.Value);
       }
 
       /// <summary>
@@ -1195,7 +1239,7 @@ namespace PdfSharp.Pdf
       /// <summary>
       /// Get all keys currently in use in this dictionary as an array of string objects.
       /// </summary>
-      public string[] Keys
+      public ICollection<string> Keys
       {
         get
         {
@@ -1207,15 +1251,18 @@ namespace PdfSharp.Pdf
         }
       }
 
-      ICollection IDictionary.Values
+      /// <summary>
+      /// Gets the value associated with the specified key.
+      /// </summary>
+      public bool TryGetValue(string key, out PdfItem value)
       {
-        get { return this.elements.Values; }
+        return this.elements.TryGetValue(key, out value);
       }
 
       /// <summary>
       /// Gets all values currently in use in this dictionary as an array of PdfItem objects.
       /// </summary>
-      public PdfItem[] Values
+      public ICollection<PdfItem> Values
       {
         get
         {
@@ -1254,14 +1301,20 @@ namespace PdfSharp.Pdf
         get { return this.elements.Count; }
       }
 
+      ///// <param name="array">The one-dimensional array that is the destination of the elements copied from.</param>
+      ///// <param name="index">The zero-based index in array at which copying begins.</param>
+      //public void CopyTo(Array array, int index)
+      //{
+      //  //this.elements.CopyTo(array, index);
+      //  throw new NotImplementedException();
+      //}
+
       /// <summary>
-      /// Copies the elements of the elementes of the dictionary to an array, starting at a particular index.
+      /// Copies the elements of the dictionary to an array, starting at a particular index.
       /// </summary>
-      /// <param name="array">The one-dimensional array that is the destination of the elements copied from.</param>
-      /// <param name="index">The zero-based index in array at which copying begins.</param>
-      public void CopyTo(Array array, int index)
+      public void CopyTo(KeyValuePair<string, PdfItem>[] array, int arrayIndex)
       {
-        this.elements.CopyTo(array, index);
+        throw new NotImplementedException();
       }
 
       /// <summary>
@@ -1273,15 +1326,6 @@ namespace PdfSharp.Pdf
       }
 
       #endregion
-
-      #region IEnumerable Members
-
-      IEnumerator System.Collections.IEnumerable.GetEnumerator()
-      {
-        return ((ICollection)this.elements).GetEnumerator();
-      }
-
-      #endregion
     }
 
     /// <summary>
@@ -1384,7 +1428,7 @@ namespace PdfSharp.Pdf
               bytes = Filtering.Decode(this.value, filter);
               if (bytes == null)
               {
-                string message = String.Format("«Cannot decode filter '{0}'»", filter.ToString());
+                string message = String.Format("«Cannot decode filter '{0}'»", filter);
                 bytes = PdfEncoders.RawEncoding.GetBytes(message);
               }
             }
@@ -1394,19 +1438,18 @@ namespace PdfSharp.Pdf
               this.value.CopyTo(bytes, 0);
             }
           }
-          return bytes == null ? new byte[0] : bytes;
+          return bytes ?? new byte[0];
         }
       }
 
       /// <summary>
-      /// Tries the unfilter the bytes of the stream. If the stream is filtered and PDFsharp knows the filter
-      /// algorithm, the stream content is replaced by its unfiltered value and the function return true.
-      /// Otherwise the content keeps untouched and the function returns flase.
-      /// The funktion is useful for analysing existing PDF files.
+      /// Tries to unfilter the bytes of the stream. If the stream is filtered and PDFsharp knows the filter
+      /// algorithm, the stream content is replaced by its unfiltered value and the function returns true.
+      /// Otherwise the content remains untouched and the function returns false.
+      /// The function is useful for analyzing existing PDF files.
       /// </summary>
       public bool TryUnfilter()
       {
-        byte[] bytes = null;
         if (this.value != null)
         {
           PdfItem filter = this.owner.Elements["/Filter"];
@@ -1414,7 +1457,7 @@ namespace PdfSharp.Pdf
           {
             // PDFsharp can only uncompress streams that are compressed with
             // the ZIP or LHZ algorithm.
-            bytes = Filtering.Decode(this.value, filter);
+            byte[] bytes = Filtering.Decode(this.value, filter);
             if (bytes != null)
             {
               this.owner.Elements.Remove(Keys.Filter);
@@ -1436,7 +1479,7 @@ namespace PdfSharp.Pdf
         if (this.value == null)
           return;
 
-        if (!this.owner.Elements.Contains("/Filter"))
+        if (!this.owner.Elements.ContainsKey("/Filter"))
         {
           this.value = Filtering.FlateDecode.Encode(this.value);
           this.owner.Elements["/Filter"] = new PdfName("/FlateDecode");
@@ -1445,21 +1488,21 @@ namespace PdfSharp.Pdf
       }
 
       /// <summary>
-      /// Returns the strem content a raw string.
+      /// Returns the stream content as a raw string.
       /// </summary>
       public override string ToString()
       {
         if (this.value == null)
-          return "«null»";
+          return "«null»";
 
-        string stream = "";
+        string stream;
         PdfItem filter = this.owner.Elements["/Filter"];
         if (filter != null)
         {
 #if true
           byte[] bytes = Filtering.Decode(this.value, filter);
           if (bytes != null)
-            stream = PdfEncoders.RawEncoding.GetString(bytes);
+            stream = PdfEncoders.RawEncoding.GetString(bytes, 0, bytes.Length);
 #else
 
           if (this.owner.Elements.GetString("/Filter") == "/FlateDecode")
@@ -1471,7 +1514,7 @@ namespace PdfSharp.Pdf
             throw new NotImplementedException("Unknown filter");
         }
         else
-          stream = PdfEncoders.RawEncoding.GetString(this.value);
+          stream = PdfEncoders.RawEncoding.GetString(this.value, 0, this.value.Length);
 
         return stream;
       }
@@ -1483,13 +1526,21 @@ namespace PdfSharp.Pdf
       //}
 
       /// <summary>
+      /// Converts a raw encoded string into a byte array.
+      /// </summary>
+      public static byte[] RawEncode(string content)
+      {
+        return PdfEncoders.RawEncoding.GetBytes(content);
+      }
+
+      /// <summary>
       /// Common keys for all streams.
       /// </summary>
       public class Keys : KeysBase
       {
         /// <summary>
         /// (Required) The number of bytes from the beginning of the line following the keyword
-        /// stream to the last byte just before the keywordendstream. (There may be an additional
+        /// stream to the last byte just before the keyword endstream. (There may be an additional
         /// EOL marker, preceding endstream, that is not included in the count and is not logically
         /// part of the stream data.)
         /// </summary>
@@ -1507,7 +1558,7 @@ namespace PdfSharp.Pdf
         /// <summary>
         /// (Optional) A parameter dictionary or an array of such dictionaries, used by the filters
         /// specified by Filter. If there is only one filter and that filter has parameters, DecodeParms
-        /// must be set to the filter?s parameter dictionary unless all the filter?s parameters have
+        /// must be set to the filterâ??s parameter dictionary unless all the filterâ??s parameters have
         /// their default values, in which case the DecodeParms entry may be omitted. If there are 
         /// multiple filters and any of the filters has parameters set to nondefault values, DecodeParms
         /// must be an array with one entry for each filter: either the parameter dictionary for that
@@ -1530,7 +1581,7 @@ namespace PdfSharp.Pdf
 
         /// <summary>
         /// (Optional; PDF 1.2) The name of a filter to be applied in processing the data found in the
-        /// stream?s external file, or an array of such names. The same rules apply as for Filter.
+        /// streamâ??s external file, or an array of such names. The same rules apply as for Filter.
         /// </summary>
         [KeyInfo("1.2", KeyType.NameOrArray | KeyType.Optional)]
         public const string FFilter = "/FFilter";
@@ -1554,4 +1605,4 @@ namespace PdfSharp.Pdf
       }
     }
   }
-}
+}
\ No newline at end of file
diff --git a/lib/PdfSharp/PdfSharp.Pdf/PdfDocument.cs b/lib/PdfSharp/PdfSharp.Pdf/PdfDocument.cs
index fda76ca..819605a 100644
--- a/lib/PdfSharp/PdfSharp.Pdf/PdfDocument.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf/PdfDocument.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -198,14 +198,15 @@ namespace PdfSharp.Pdf
       if (PdfDocument.nameCount == 57)
         PdfDocument.nameCount.GetType();
 #endif
-      return "Document " + (nameCount++).ToString();
+      return "Document " + nameCount++;
     }
     static int nameCount;
 
     internal bool CanModify
     {
       //get {return this.state == DocumentState.Created || this.state == DocumentState.Modifyable;}
-      get { return true; }
+      // THHO4STLA: TODO: correct implementation
+      get { return openMode == PdfDocumentOpenMode.Modify; } // TODO: correct implementation
     }
 
     /// <summary>
@@ -230,8 +231,7 @@ namespace PdfSharp.Pdf
         }
         finally
         {
-          if (writer != null)
-            writer.Close();
+          writer.Close();
         }
       }
     }
@@ -273,8 +273,13 @@ namespace PdfSharp.Pdf
       }
       finally
       {
-        if (stream != null && closeStream)
-          stream.Close();
+        if (stream != null)
+        {
+          if (closeStream)
+            stream.Close();
+          else
+            stream.Position = 0; // Reset the stream position if the stream is left open.
+        }
         if (writer != null)
           writer.Close(closeStream);
       }
@@ -358,7 +363,7 @@ namespace PdfSharp.Pdf
     /// </summary>
     internal override void PrepareForSave()
     {
-      PdfDocumentInformation info = this.Info;
+      PdfDocumentInformation info = Info;
 
       // Set Creator if value is undefined
       if (info.Elements[PdfDocumentInformation.Keys.Creator] == null)
@@ -387,7 +392,7 @@ namespace PdfSharp.Pdf
       // Remove all unreachable objects (e.g. from deleted pages)
       int removed = this.irefTable.Compact();
       if (removed != 0)
-        Debug.WriteLine("PrepareForSave: Number of deleted unreachable objects: " + removed.ToString());
+        Debug.WriteLine("PrepareForSave: Number of deleted unreachable objects: " + removed);
       this.irefTable.Renumber();
 #endif
     }
@@ -516,7 +521,7 @@ namespace PdfSharp.Pdf
     DocumentHandle handle;
 
     /// <summary>
-    /// Returns a value indicating whether the document was new created or opend from an exsisting document.
+    /// Returns a value indicating whether the document was newly created or opened from an existing document.
     /// Returns true if the document was opened with the PdfReader.Open function, false otherwise.
     /// </summary>
     public bool IsImported
@@ -615,7 +620,7 @@ namespace PdfSharp.Pdf
     }
 
     /// <summary>
-    /// Gets the viewer preverences of this document.
+    /// Gets the viewer preferences of this document.
     /// </summary>
     public PdfViewerPreferences ViewerPreferences
     {
@@ -631,7 +636,7 @@ namespace PdfSharp.Pdf
     }
 
     /// <summary>
-    /// Get the AcroFrom dictionary.
+    /// Get the AcroForm dictionary.
     /// </summary>
     public PdfAcroForm AcroForm
     {
@@ -735,7 +740,7 @@ namespace PdfSharp.Pdf
     /// Gets the PdfInternals object of this document, that grants access to some internal structures
     /// which are not part of the public interface of PdfDocument.
     /// </summary>
-    public PdfInternals Internals
+    public new PdfInternals Internals
     {
       get
       {
@@ -812,7 +817,7 @@ namespace PdfSharp.Pdf
     /// </summary>
     internal void OnExternalDocumentFinalized(PdfDocument.DocumentHandle handle)
     {
-      if (PdfDocument.tls != null)
+      if (tls != null)
       {
         //PdfDocument[] documents = tls.Documents;
         tls.DetachDocument(handle);
@@ -832,9 +837,9 @@ namespace PdfSharp.Pdf
     {
       get
       {
-        if (PdfDocument.tls == null)
-          PdfDocument.tls = new ThreadLocalStorage();
-        return PdfDocument.tls;
+        if (tls == null)
+          tls = new ThreadLocalStorage();
+        return tls;
       }
     }
     [ThreadStatic]
diff --git a/lib/PdfSharp/PdfSharp.Pdf/PdfDocumentInformation.cs b/lib/PdfSharp/PdfSharp.Pdf/PdfDocumentInformation.cs
index 9ac5b49..fd85f68 100644
--- a/lib/PdfSharp/PdfSharp.Pdf/PdfDocumentInformation.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf/PdfDocumentInformation.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -160,7 +160,7 @@ namespace PdfSharp.Pdf
 
       /// <summary>
       /// (Optional) If the document was converted to PDF from another format,
-      /// the name of the application (for example, empira MigraDoc®) that created the
+      /// the name of the application (for example, empira MigraDoc) that created the
       /// original document from which it was converted.
       /// </summary>
       [KeyInfo(KeyType.String | KeyType.Optional)]
diff --git a/lib/PdfSharp/PdfSharp.Pdf/PdfDocumentOptions.cs b/lib/PdfSharp/PdfSharp.Pdf/PdfDocumentOptions.cs
index 3e916b4..7895dda 100644
--- a/lib/PdfSharp/PdfSharp.Pdf/PdfDocumentOptions.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf/PdfDocumentOptions.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Pdf/PdfDocumentSettings.cs b/lib/PdfSharp/PdfSharp.Pdf/PdfDocumentSettings.cs
index 34e3529..22c6ac8 100644
--- a/lib/PdfSharp/PdfSharp.Pdf/PdfDocumentSettings.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf/PdfDocumentSettings.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -30,6 +30,7 @@
 using System;
 using System.Diagnostics;
 using System.Collections;
+using PdfSharp.Drawing;
 using PdfSharp.Internal;
 
 namespace PdfSharp.Pdf
@@ -44,6 +45,23 @@ namespace PdfSharp.Pdf
     }
 
     /// <summary>
+    /// Sets the private font collection.
+    /// </summary>
+    public XPrivateFontCollection PrivateFontCollection
+    {
+      internal get { return this.privateFontCollection; }
+      set
+      {
+        if (this.privateFontCollection != null)
+          throw new InvalidOperationException("PrivateFontCollection can only be set once.");
+
+        this.privateFontCollection = value;
+      }
+    }
+    private XPrivateFontCollection privateFontCollection;
+
+
+    /// <summary>
     /// Gets or sets the default trim margins.
     /// </summary>
     public TrimMargins TrimMargins
diff --git a/lib/PdfSharp/PdfSharp.Pdf/PdfInteger.cs b/lib/PdfSharp/PdfSharp.Pdf/PdfInteger.cs
index a5dd4f2..4a1e7eb 100644
--- a/lib/PdfSharp/PdfSharp.Pdf/PdfInteger.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf/PdfInteger.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -67,7 +67,7 @@ namespace PdfSharp.Pdf
       // This class must behave like a value type. Therefore it cannot be changed (like System.String).
       get { return this.value; }
     }
-    int value;
+    readonly int value;
 
     /// <summary>
     /// Returns the integer as string.
diff --git a/lib/PdfSharp/PdfSharp.Pdf/PdfIntegerObject.cs b/lib/PdfSharp/PdfSharp.Pdf/PdfIntegerObject.cs
index c097b6b..0e39882 100644
--- a/lib/PdfSharp/PdfSharp.Pdf/PdfIntegerObject.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf/PdfIntegerObject.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Pdf/PdfItem.cs b/lib/PdfSharp/PdfSharp.Pdf/PdfItem.cs
index cd4b2d0..b72e7fd 100644
--- a/lib/PdfSharp/PdfSharp.Pdf/PdfItem.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf/PdfItem.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -40,15 +40,9 @@ namespace PdfSharp.Pdf
   /// <summary>
   /// The base class of all PDF objects and simple types.
   /// </summary>
-  public abstract class PdfItem  : ICloneable
+  public abstract class PdfItem : ICloneable
   {
     // All simple types (i.e. derived from PdfItem but not from PdfObject) must be immutable.
-    //
-
-    /// <summary>
-    /// Initializes a new instance of the <see cref="PdfItem"/> class.
-    /// </summary>
-    public PdfItem() { }
 
     object ICloneable.Clone()
     {
diff --git a/lib/PdfSharp/PdfSharp.Pdf/PdfLiteral.cs b/lib/PdfSharp/PdfSharp.Pdf/PdfLiteral.cs
index 97b5f0c..e31ed83 100644
--- a/lib/PdfSharp/PdfSharp.Pdf/PdfLiteral.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf/PdfLiteral.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -77,14 +77,14 @@ namespace PdfSharp.Pdf
     }
 
     /// <summary>
-    /// Gets the value as litarl string.
+    /// Gets the value as litaral string.
     /// </summary>
     public string Value
     {
       // This class must behave like a value type. Therefore it cannot be changed (like System.String).
       get { return this.value; }
     }
-    string value = "";
+    readonly string value = String.Empty;
 
     /// <summary>
     /// Returns a string that represents the current value.
diff --git a/lib/PdfSharp/PdfSharp.Pdf/PdfName.cs b/lib/PdfSharp/PdfSharp.Pdf/PdfName.cs
index d5cc54a..e292955 100644
--- a/lib/PdfSharp/PdfSharp.Pdf/PdfName.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf/PdfName.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -28,6 +28,7 @@
 #endregion
 
 using System;
+using System.Collections.Generic;
 using System.Diagnostics;
 using System.Collections;
 using System.Text;
@@ -161,17 +162,17 @@ namespace PdfSharp.Pdf
     /// <summary>
     /// Implements a comparer that compares PdfName objects.
     /// </summary>
-    public class PdfXNameComparer : IComparer
+    public class PdfXNameComparer : IComparer<PdfName>
     {
       /// <summary>
       /// Compares two objects and returns a value indicating whether one is less than, equal to, or greater than the other.
       /// </summary>
       /// <param name="x">The first object to compare.</param>
       /// <param name="y">The second object to compare.</param>
-      public int Compare(object x, object y)
+      public int Compare(PdfName x, PdfName y)
       {
-        PdfName l = x as PdfName;
-        PdfName r = y as PdfName;
+        PdfName l = x; // as PdfName;
+        PdfName r = y; // as PdfName;
         if (l != null)
         {
           if (r != null)
diff --git a/lib/PdfSharp/PdfSharp.Pdf/PdfNameObject.cs b/lib/PdfSharp/PdfSharp.Pdf/PdfNameObject.cs
index 2bfb0ab..0c68119 100644
--- a/lib/PdfSharp/PdfSharp.Pdf/PdfNameObject.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf/PdfNameObject.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Pdf/PdfNull.cs b/lib/PdfSharp/PdfSharp.Pdf/PdfNull.cs
index 77ec533..bf10e25 100644
--- a/lib/PdfSharp/PdfSharp.Pdf/PdfNull.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf/PdfNull.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Pdf/PdfNullObject.cs b/lib/PdfSharp/PdfSharp.Pdf/PdfNullObject.cs
index 2f16bb1..f402e04 100644
--- a/lib/PdfSharp/PdfSharp.Pdf/PdfNullObject.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf/PdfNullObject.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Pdf/PdfNumber.cs b/lib/PdfSharp/PdfSharp.Pdf/PdfNumber.cs
index 8bece07..7163655 100644
--- a/lib/PdfSharp/PdfSharp.Pdf/PdfNumber.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf/PdfNumber.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Pdf/PdfNumberObject.cs b/lib/PdfSharp/PdfSharp.Pdf/PdfNumberObject.cs
index 65aaa04..dcb9e28 100644
--- a/lib/PdfSharp/PdfSharp.Pdf/PdfNumberObject.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf/PdfNumberObject.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -44,7 +44,7 @@ namespace PdfSharp.Pdf
     /// <summary>
     /// Initializes a new instance of the <see cref="PdfNumberObject"/> class.
     /// </summary>
-    public PdfNumberObject()
+    protected PdfNumberObject()
     {
     }
 
@@ -52,7 +52,7 @@ namespace PdfSharp.Pdf
     /// Initializes a new instance of the <see cref="PdfNumberObject"/> class.
     /// </summary>
     /// <param name="document">The document.</param>
-    public PdfNumberObject(PdfDocument document) : base(document)
+    protected PdfNumberObject(PdfDocument document) : base(document)
     {
     }
   }
diff --git a/lib/PdfSharp/PdfSharp.Pdf/PdfObject.cs b/lib/PdfSharp/PdfSharp.Pdf/PdfObject.cs
index 2c90775..0971bba 100644
--- a/lib/PdfSharp/PdfSharp.Pdf/PdfObject.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf/PdfObject.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -56,7 +56,7 @@ namespace PdfSharp.Pdf
     /// </summary>
     protected PdfObject(PdfDocument document)
     {
-      this.Document = document;
+      Document = document;
     }
 
     /// <summary>
@@ -64,11 +64,18 @@ namespace PdfSharp.Pdf
     /// </summary>
     protected PdfObject(PdfObject obj)
     {
-      this.Document = obj.Owner;
+      Document = obj.Owner;
       // If the object that was transformed to an instance of a derived class was an indirect object
       // set the value of the reference to this.
       if (obj.iref != null)
         obj.iref.Value = this;
+#if DEBUG
+      else
+      {
+        // If this occurs it is an internal error
+        Debug.Assert(false, "Object type transformation must not be done with direct objects");
+      }
+#endif
     }
 
     /// <summary>
@@ -90,6 +97,37 @@ namespace PdfSharp.Pdf
       return obj;
     }
 
+#if true_  // works, but may lead to other problems that I cannot assess
+    /// <summary>
+    /// Determines whether the specified object is equal to the current PdfObject.
+    /// </summary>
+    public override bool Equals(object obj)
+    {
+      if (obj is PdfObject)
+      {
+        PdfObject other = (PdfObject)obj;
+        // Take object type transformation into account
+        if (this.iref != null && other.iref != null)
+        {
+          Debug.Assert(this.iref.Value != null, "iref without value.");
+          Debug.Assert(other.iref.Value != null, "iref without value.");
+          return Object.ReferenceEquals(this.iref.Value, other.iref.Value);
+        }
+      }
+      return base.Equals(obj);
+    }
+
+    public override int GetHashCode()
+    {
+      if (this.iref != null)
+      {
+        Debug.Assert(this.iref.Value != null, "iref without value.");
+        return this.iref.GetHashCode();
+      }
+      return base.GetHashCode();
+    }
+#endif
+
     /// <summary>
     /// Sets the object and generation number
     /// Setting the object identifier makes this object an indirect object, i.e. the object gets
@@ -135,7 +173,7 @@ namespace PdfSharp.Pdf
     {
       set
       {
-        if (!Object.ReferenceEquals(this.document, value))
+        if (!ReferenceEquals(this.document, value))
         {
           if (this.document != null)
             throw new InvalidOperationException("Cannot change document.");
@@ -150,13 +188,28 @@ namespace PdfSharp.Pdf
     /// <summary>
     /// Indicates whether the object is an indirect object.
     /// </summary>
-    internal bool IsIndirect
+    public bool IsIndirect
     {
-      // An object is an indirect object if and only if is has an indirect refernece value.
+      // An object is an indirect object if and only if is has an indirect reference value.
       get { return this.iref != null; }
     }
 
     /// <summary>
+    /// Gets the PdfInternals object of this document, that grants access to some internal structures
+    /// which are not part of the public interface of PdfDocument.
+    /// </summary>
+    public PdfObjectInternals Internals
+    {
+      get
+      {
+        if (this.internals == null)
+          this.internals = new PdfObjectInternals(this);
+        return this.internals;
+      }
+    }
+    PdfObjectInternals internals;
+
+    /// <summary>
     /// When overridden in a derived class, prepares the object to get saved.
     /// </summary>
     internal virtual void PrepareForSave()
@@ -197,7 +250,7 @@ namespace PdfSharp.Pdf
     /// </summary>
     internal int ObjectNumber
     {
-      get { return this.ObjectID.ObjectNumber; }
+      get { return ObjectID.ObjectNumber; }
     }
 
     /// <summary>
@@ -205,14 +258,14 @@ namespace PdfSharp.Pdf
     /// </summary>
     internal int GenerationNumber
     {
-      get { return this.ObjectID.GenerationNumber; }
+      get { return ObjectID.GenerationNumber; }
     }
 
     ///// <summary>
     ///// Creates a deep copy of the specified value and its transitive closure and adds the
     ///// new objects to the specified owner document.
     ///// </summary>
-    /// <param name="owner">The document that ownes the cloned objects.</param>
+    /// <param name="owner">The document that owns the cloned objects.</param>
     /// <param name="externalObject">The root object to be cloned.</param>
     /// <returns>The clone of the root object</returns>
     internal static PdfObject DeepCopyClosure(PdfDocument owner, PdfObject externalObject)
@@ -284,13 +337,13 @@ namespace PdfSharp.Pdf
     ///// Imports an object and its transitive closure to the specified document.
     ///// </summary>
     /// <param name="importedObjectTable">The imported object table of the owner for the external document.</param>
-    /// <param name="owner">The document that ownes the cloned objects.</param>
+    /// <param name="owner">The document that owns the cloned objects.</param>
     /// <param name="externalObject">The root object to be cloned.</param>
     /// <returns>The clone of the root object</returns>
     internal static PdfObject ImportClosure(PdfImportedObjectTable importedObjectTable, PdfDocument owner, PdfObject externalObject)
     {
-      Debug.Assert(Object.ReferenceEquals(importedObjectTable.Owner, owner), "importedObjectTable does not belong to the owner.");
-      Debug.Assert(Object.ReferenceEquals(importedObjectTable.ExternalDocument, externalObject.Owner),
+      Debug.Assert(ReferenceEquals(importedObjectTable.Owner, owner), "importedObjectTable does not belong to the owner.");
+      Debug.Assert(ReferenceEquals(importedObjectTable.ExternalDocument, externalObject.Owner),
         "The ExternalDocument of the importedObjectTable does not belong to the owner of object to be imported.");
 
       // Get transitive closure of external object
@@ -310,7 +363,7 @@ namespace PdfSharp.Pdf
       for (int idx = 0; idx < count; idx++)
       {
         PdfObject obj = elements[idx];
-        Debug.Assert(!Object.ReferenceEquals(obj.Owner, owner));
+        Debug.Assert(!ReferenceEquals(obj.Owner, owner));
 
         if (importedObjectTable.Contains(obj.ObjectID))
         {
@@ -379,7 +432,7 @@ namespace PdfSharp.Pdf
     /// </summary>
     internal static void FixUpObject(PdfImportedObjectTable iot, PdfDocument owner, PdfObject value)
     {
-      Debug.Assert(Object.ReferenceEquals(iot.Owner, owner));
+      Debug.Assert(ReferenceEquals(iot.Owner, owner));
 
       PdfDictionary dict;
       PdfArray array;
diff --git a/lib/PdfSharp/PdfSharp.Pdf/PdfObjectID.cs b/lib/PdfSharp/PdfSharp.Pdf/PdfObjectID.cs
index 7b0df54..a1d40d6 100644
--- a/lib/PdfSharp/PdfSharp.Pdf/PdfObjectID.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf/PdfObjectID.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Pdf/PdfOutline.cs b/lib/PdfSharp/PdfSharp.Pdf/PdfOutline.cs
index 5210b5e..b1107ca 100644
--- a/lib/PdfSharp/PdfSharp.Pdf/PdfOutline.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf/PdfOutline.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -28,6 +28,7 @@
 #endregion
 
 using System;
+using System.Collections.Generic;
 using System.Diagnostics;
 using System.Collections;
 using System.Text;
@@ -176,7 +177,7 @@ namespace PdfSharp.Pdf
     PdfPage destinationPage;
 
     /// <summary>
-    /// Gets or sets whether the the outline item is opened (or expanded).
+    /// Gets or sets whether the outline item is opened (or expanded).
     /// </summary>
     public bool Opened
     {
@@ -475,7 +476,7 @@ namespace PdfSharp.Pdf
       }
 
       private PdfOutline parent;
-      private ArrayList outlines = new ArrayList();
+      private List<PdfOutline> outlines = new List<PdfOutline>();
     }
 
     /// <summary>
diff --git a/lib/PdfSharp/PdfSharp.Pdf/PdfPage.cs b/lib/PdfSharp/PdfSharp.Pdf/PdfPage.cs
index e78fa1d..8a114ba 100644
--- a/lib/PdfSharp/PdfSharp.Pdf/PdfPage.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf/PdfPage.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -53,13 +53,7 @@ namespace PdfSharp.Pdf
     public PdfPage()
     {
       Elements.SetName(Keys.Type, "/Page");
-
-      // TODO: Can I get default paper size from something like CultureInfo??
-      if (RegionInfo.CurrentRegion != null && RegionInfo.CurrentRegion.IsMetric)
-        Size = PageSize.A4;
-      else
-        Size = PageSize.Letter;
-      PdfRectangle rect = MediaBox;
+      Initialize();
     }
 
     /// <summary>
@@ -70,12 +64,8 @@ namespace PdfSharp.Pdf
       : base(document)
     {
       Elements.SetName(Keys.Type, "/Page");
-      Elements[PdfPage.Keys.Parent] = document.Pages.Reference;
-
-      if (RegionInfo.CurrentRegion != null && RegionInfo.CurrentRegion.IsMetric)
-        Size = PageSize.A4;
-      else
-        Size = PageSize.Letter;
+      Elements[Keys.Parent] = document.Pages.Reference;
+      Initialize();
     }
 
     internal PdfPage(PdfDictionary dict)
@@ -87,6 +77,16 @@ namespace PdfSharp.Pdf
         this.orientation = PageOrientation.Landscape;
     }
 
+    void Initialize()
+    {
+      Size = RegionInfo.CurrentRegion.IsMetric ? PageSize.A4 : PageSize.Letter;
+
+#pragma warning disable 168
+      // Force creation of MediaBox object by invoking property
+      PdfRectangle rect = MediaBox;
+#pragma warning restore 168
+    }
+
     /// <summary>
     /// Gets or sets a user defined object that contains arbitrary information associated with this PDF page.
     /// The tag is not used by PDFsharp.
@@ -127,7 +127,7 @@ namespace PdfSharp.Pdf
     {
       set
       {
-        if (!Object.ReferenceEquals(this.document, value))
+        if (!ReferenceEquals(this.document, value))
         {
           if (this.document != null)
             throw new InvalidOperationException("Cannot change document.");
@@ -141,13 +141,13 @@ namespace PdfSharp.Pdf
 
     /// <summary>
     /// Gets or sets the orientation of the page. The default value PageOrientation.Portrait.
-    /// If an imported page has a /Rotate value that satisfys the formula 90 + n * 180 the 
+    /// If an imported page has a /Rotate value that matches the formula 90 + n * 180 the 
     /// orientation is set to PageOrientation.Landscape.
     /// </summary>
     public PageOrientation Orientation
     {
-      get { return this.orientation; }
-      set { this.orientation = value; }
+      get { return orientation; }
+      set { orientation = value; }
     }
     PageOrientation orientation;
 
@@ -163,11 +163,12 @@ namespace PdfSharp.Pdf
           throw new InvalidEnumArgumentException("value", (int)value, typeof(PageSize));
 
         XSize size = PageSizeConverter.ToSize(value);
-        if (this.orientation == PageOrientation.Portrait)
+        // THHO: MediaBox is always in Portrait mode (see Height, Width)
+        /*if (this.orientation == PageOrientation.Portrait)*/
           MediaBox = new PdfRectangle(0, 0, size.Width, size.Height);
-        else
-          MediaBox = new PdfRectangle(0, 0, size.Height, size.Width);
-        this.pageSize = value;
+        /*else
+          MediaBox = new PdfRectangle(0, 0, size.Height, size.Width);*/
+        pageSize = value;
       }
     }
     PageSize pageSize;
@@ -346,8 +347,10 @@ namespace PdfSharp.Pdf
                 {
                   // Make it a direct array
                   array = array.Clone();
-                  array.Document = this.Owner;
+                  array.Document = Owner;
                 }
+//#warning THHO4STLA: verursacht Exception "Object type transformation must not be done with direct objects" in "protected PdfObject(PdfObject obj)"
+                // TODO THHO4STLA: verursacht Exception "Object type transformation must not be done with direct objects" in "protected PdfObject(PdfObject obj)"
                 this.contents = new PdfContents(array);
               }
               else
@@ -393,24 +396,22 @@ namespace PdfSharp.Pdf
     PdfAnnotations annotations;
 
     /// <summary>
-    /// Adds the intra document link.
+    /// Adds an intra document link.
     /// </summary>
     /// <param name="rect">The rect.</param>
-    /// <param name="destinatinPage">The destinatin page.</param>
-    /// <returns></returns>
-    public PdfLinkAnnotation AddDocumentLink(PdfRectangle rect, int destinatinPage)
+    /// <param name="destinationPage">The destination page.</param>
+    public PdfLinkAnnotation AddDocumentLink(PdfRectangle rect, int destinationPage)
     {
-      PdfLinkAnnotation annotation = PdfLinkAnnotation.CreateDocumentLink(rect, destinatinPage);
+      PdfLinkAnnotation annotation = PdfLinkAnnotation.CreateDocumentLink(rect, destinationPage);
       Annotations.Add(annotation);
       return annotation;
     }
 
     /// <summary>
-    /// Adds the link to the Web.
+    /// Adds a link to the Web.
     /// </summary>
     /// <param name="rect">The rect.</param>
     /// <param name="url">The URL.</param>
-    /// <returns></returns>
     public PdfLinkAnnotation AddWebLink(PdfRectangle rect, string url)
     {
       PdfLinkAnnotation annotation = PdfLinkAnnotation.CreateWebLink(rect, url);
@@ -419,11 +420,10 @@ namespace PdfSharp.Pdf
     }
 
     /// <summary>
-    /// Adds the link to a file.
+    /// Adds a link to a file.
     /// </summary>
     /// <param name="rect">The rect.</param>
     /// <param name="fileName">Name of the file.</param>
-    /// <returns></returns>
     public PdfLinkAnnotation AddFileLink(PdfRectangle rect, string fileName)
     {
       PdfLinkAnnotation annotation = PdfLinkAnnotation.CreateFileLink(rect, fileName);
@@ -563,13 +563,15 @@ namespace PdfSharp.Pdf
       // HACK: temporarily flip media box if Landscape
       PdfRectangle mediaBox = MediaBox;
       // TODO: Take /Rotate into account
-      if (this.orientation == PageOrientation.Landscape)
+      if (orientation == PageOrientation.Landscape)
         MediaBox = new PdfRectangle(mediaBox.X1, mediaBox.Y1, mediaBox.Y2, mediaBox.X2);
+//#warning THHO4STLA: warum nicht new PdfRectangle(mediaBox.Y1, mediaBox.X1, mediaBox.Y2, mediaBox.X2)? - siehe auch Orientation
+//#warning THHO4STLA: CropBox, BleedBox etc. auch drehen?
 
 #if true
       // Add transparency group to prevent rendering problems of Adobe viewer
       this.transparencyUsed = true; // TODO: check XObjects
-      if (this.transparencyUsed && !Elements.Contains(Keys.Group))
+      if (this.transparencyUsed && !Elements.ContainsKey(Keys.Group))
       {
         PdfDictionary group = new PdfDictionary();
         this.elements["/Group"] = group;
@@ -612,6 +614,7 @@ namespace PdfSharp.Pdf
         if (res is PdfReference)
         {
           resources = (PdfDictionary)((PdfReference)res).Value.Clone();
+          resources.Document = page.Owner;
         }
         else
           resources = (PdfDictionary)res;
@@ -619,18 +622,19 @@ namespace PdfSharp.Pdf
         if (resources == null)
         {
           resources = values.Resources.Clone();
+          resources.Document = page.Owner;
           page.Elements.Add(PdfPage.Keys.Resources, resources);
         }
         else
         {
           foreach (PdfName name in values.Resources.Elements.KeyNames)
           {
-            if (!resources.Elements.Contains(name.Value))
+            if (!resources.Elements.ContainsKey(name.Value))
             {
               PdfItem item = values.Resources.Elements[name];
               if (item is PdfObject)
                 item = item.Clone();
-              resources.Elements.Add(name, item);
+              resources.Elements.Add(name.ToString(), item);
             }
           }
         }
@@ -647,7 +651,7 @@ namespace PdfSharp.Pdf
     }
 
     /// <summary>
-    /// Add all inheritables values from the specified page to the specified values structure.
+    /// Add all inheritable values from the specified page to the specified values structure.
     /// </summary>
     internal static void InheritValues(PdfDictionary page, ref InheritedValues values)
     {
@@ -955,7 +959,7 @@ namespace PdfSharp.Pdf
       /// (Optional; inheritable) A rectangle, expressed in default user space units, defining the 
       /// visible region of default user space. When the page is displayed or printed, its contents 
       /// are to be clipped (cropped) to this rectangle and then imposed on the output medium in some
-      /// implementationdefined manner. Default value: the value of MediaBox.
+      /// implementation defined manner. Default value: the value of MediaBox.
       /// </summary>
       [KeyInfo(KeyType.Rectangle | KeyType.Optional | KeyType.Inheritable)]
       public const string CropBox = "/CropBox";
diff --git a/lib/PdfSharp/PdfSharp.Pdf/PdfPages.cs b/lib/PdfSharp/PdfSharp.Pdf/PdfPages.cs
index 5dca9c0..afa2982 100644
--- a/lib/PdfSharp/PdfSharp.Pdf/PdfPages.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf/PdfPages.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -28,6 +28,7 @@
 #endregion
 
 using System;
+using System.Collections.Generic;
 using System.Diagnostics;
 using System.Collections;
 using System.Text;
@@ -53,7 +54,7 @@ namespace PdfSharp.Pdf
       Elements[Keys.Count] = new PdfInteger(0);
     }
 
-    PdfPages(PdfDictionary dictionary)
+    internal PdfPages(PdfDictionary dictionary)
       : base(dictionary)
     {
     }
@@ -63,7 +64,7 @@ namespace PdfSharp.Pdf
     /// </summary>
     public int Count
     {
-      get { return this.PagesArray.Elements.Count; }
+      get { return PagesArray.Elements.Count; }
     }
 
     /// <summary>
@@ -90,7 +91,7 @@ namespace PdfSharp.Pdf
     }
 
     /// <summary>
-    /// Creates a new PdfPage, adds it to this document, and retruns it.
+    /// Creates a new PdfPage, adds it to this document, and returns it.
     /// </summary>
     public PdfPage Add()
     {
@@ -100,7 +101,7 @@ namespace PdfSharp.Pdf
     }
 
     /// <summary>
-    /// Adds the specified PdfPage to this document and retruns a may be new PdfPage object.
+    /// Adds the specified PdfPage to this document and maybe returns a new PdfPage object.
     /// The value returned is a new object if the added page comes from a foreign document.
     /// </summary>
     public PdfPage Add(PdfPage page)
@@ -109,7 +110,7 @@ namespace PdfSharp.Pdf
     }
 
     /// <summary>
-    /// Creates a new PdfPage, inserts it at the specified position to this document, and retruns it.
+    /// Creates a new PdfPage, inserts it at the specified position into this document, and returns it.
     /// </summary>
     public PdfPage Insert(int index)
     {
@@ -119,7 +120,7 @@ namespace PdfSharp.Pdf
     }
 
     /// <summary>
-    /// Inserts the specified PdfPage at the specified position to this document and retruns a may be new PdfPage object.
+    /// Inserts the specified PdfPage at the specified position to this document and maybe returns a new PdfPage object.
     /// The value returned is a new object if the inserted page comes from a foreign document.
     /// </summary>
     public PdfPage Insert(int index, PdfPage page)
@@ -128,13 +129,13 @@ namespace PdfSharp.Pdf
         throw new ArgumentNullException("page");
 
       // Is the page already owned by this document
-      if (page.Owner == this.Owner)
+      if (page.Owner == Owner)
       {
         // Case: Page is removed and than inserted a another position.
         int count = Count;
         for (int idx = 0; idx < count; idx++)
         {
-          if (Object.ReferenceEquals(this[idx], page))
+          if (ReferenceEquals(this[idx], page))
             throw new InvalidOperationException(PSSR.MultiplePageInsert);
         }
         // TODO: check this case
@@ -148,7 +149,7 @@ namespace PdfSharp.Pdf
       if (page.Owner == null)
       {
         // Case: New page was created and inserted now.
-        page.Document = this.Owner;
+        page.Document = Owner;
 
         Owner.irefTable.Add(page);
         PagesArray.Elements.Insert(index, page.Reference);
@@ -200,6 +201,7 @@ namespace PdfSharp.Pdf
       if (oldIndex == newIndex)
         return;
 
+      //PdfPage page = (PdfPage)pagesArray.Elements[oldIndex];
       PdfReference page = (PdfReference)pagesArray.Elements[oldIndex];
       pagesArray.Elements.RemoveAt(oldIndex);
       pagesArray.Elements.Insert(newIndex, page);
@@ -300,12 +302,12 @@ namespace PdfSharp.Pdf
     PdfArray pagesArray;
 
     /// <summary>
-    /// Replaces the page tree by a flat array of indirect references to the the pages objects.
+    /// Replaces the page tree by a flat array of indirect references to the pages objects.
     /// </summary>
     internal void FlattenPageTree()
     {
       // Acrobat creates a balanced tree if the number of pages is rougly more than ten. This is
-      // not difficult but obviously also not neccessary. I created a document with 50000 pages with
+      // not difficult but obviously also not necessary. I created a document with 50000 pages with
       // PDF4NET and Acrobat opened it in less than 2 seconds.
 
       //PdfReference xrefRoot = this.Document.Catalog.Elements[PdfCatalog.Keys.Pages] as PdfReference;
@@ -314,16 +316,16 @@ namespace PdfSharp.Pdf
       // Promote inheritable values down the page tree
       PdfPage.InheritedValues values = new PdfPage.InheritedValues();
       PdfPage.InheritValues(this, ref values);
-      PdfDictionary[] pages = GetKids(this.Reference, values, null);
+      PdfDictionary[] pages = GetKids(Reference, values, null);
 
       // Replace /Pages in catalog by this object
       // xrefRoot.Value = this;
 
-      PdfArray array = new PdfArray(this.Owner);
+      PdfArray array = new PdfArray(Owner);
       foreach (PdfDictionary page in pages)
       {
         // Fix the parent
-        page.Elements[PdfPage.Keys.Parent] = this.Reference;
+        page.Elements[PdfPage.Keys.Parent] = Reference;
         array.Elements.Add(page.Reference);
       }
 
@@ -356,7 +358,7 @@ namespace PdfSharp.Pdf
       {
         Debug.Assert(kid.Elements.GetName(Keys.Type) == "/Pages");
         PdfPage.InheritValues(kid, ref values);
-        ArrayList list = new ArrayList();
+        List<PdfDictionary> list = new List<PdfDictionary>();
         PdfArray kids = kid.Elements["/Kids"] as PdfArray;
         //newTHHO 15.10.2007 begin
         if (kids == null)
@@ -369,12 +371,13 @@ namespace PdfSharp.Pdf
           list.AddRange(GetKids(xref2, values, kid));
         int count = list.Count;
         Debug.Assert(count == kid.Elements.GetInteger("/Count"));
-        return (PdfDictionary[])list.ToArray(typeof(PdfDictionary));
+        //return (PdfDictionary[])list.ToArray(typeof(PdfDictionary));
+        return list.ToArray();
       }
     }
 
     /// <summary>
-    /// TODO: Create the page tree.
+    /// Prepares the document for saving.
     /// </summary>
     internal override void PrepareForSave()
     {
@@ -433,7 +436,7 @@ namespace PdfSharp.Pdf
 
       object IEnumerator.Current
       {
-        get { return this.Current; }
+        get { return Current; }
       }
 
       public PdfPage Current
diff --git a/lib/PdfSharp/PdfSharp.Pdf/PdfReal.cs b/lib/PdfSharp/PdfSharp.Pdf/PdfReal.cs
index 6d599e7..6fdd5fc 100644
--- a/lib/PdfSharp/PdfSharp.Pdf/PdfReal.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf/PdfReal.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Pdf/PdfRealObject.cs b/lib/PdfSharp/PdfSharp.Pdf/PdfRealObject.cs
index a7e5810..b155b5d 100644
--- a/lib/PdfSharp/PdfSharp.Pdf/PdfRealObject.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf/PdfRealObject.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Pdf/PdfRectangle.cs b/lib/PdfSharp/PdfSharp.Pdf/PdfRectangle.cs
index cd17ba2..3339b32 100644
--- a/lib/PdfSharp/PdfSharp.Pdf/PdfRectangle.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf/PdfRectangle.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -143,7 +143,7 @@ namespace PdfSharp.Pdf
     /// </summary>
     internal PdfRectangle(PdfItem item)
     {
-      if (item == null)
+      if (item == null || item is PdfNull)
         return;
 
       if (item is PdfReference)
@@ -226,7 +226,7 @@ namespace PdfSharp.Pdf
     }
 
     /// <summary>
-    /// Tests whether two structures differs in one or more coordinates.
+    /// Tests whether two structures differ in one or more coordinates.
     /// </summary>
     public static bool operator !=(PdfRectangle left, PdfRectangle right)
     {
diff --git a/lib/PdfSharp/PdfSharp.Pdf/PdfReferenceTable.cs b/lib/PdfSharp/PdfSharp.Pdf/PdfReferenceTable.cs
index 2a7ffe5..c5b0a37 100644
--- a/lib/PdfSharp/PdfSharp.Pdf/PdfReferenceTable.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf/PdfReferenceTable.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -30,6 +30,7 @@
 using System;
 using System.Diagnostics;
 using System.Collections;
+using System.Collections.Generic;
 using System.Text;
 using System.IO;
 using PdfSharp.Internal;
@@ -54,7 +55,7 @@ namespace PdfSharp.Pdf
     /// <summary>
     /// Represents the relation between PdfObjectID and PdfReference for a PdfDocument.
     /// </summary>
-    public Hashtable objectTable = new Hashtable();
+    public Dictionary<PdfObjectID, PdfReference> objectTable = new Dictionary<PdfObjectID, PdfReference>();
 
     internal bool IsUnderConstruction
     {
@@ -71,7 +72,7 @@ namespace PdfSharp.Pdf
       if (iref.ObjectID.IsEmpty)
         iref.ObjectID = new PdfObjectID(GetNewObjectNumber());
 
-      if (this.objectTable.Contains(iref.ObjectID))
+      if (this.objectTable.ContainsKey(iref.ObjectID))
         throw new InvalidOperationException("Object already in table.");
 
       this.objectTable.Add(iref.ObjectID, iref);
@@ -90,7 +91,7 @@ namespace PdfSharp.Pdf
       if (value.ObjectID.IsEmpty)
         value.SetObjectID(GetNewObjectNumber(), 0);
 
-      if (this.objectTable.Contains(value.ObjectID))
+      if (this.objectTable.ContainsKey(value.ObjectID))
         throw new InvalidOperationException("Object already in table.");
 
       this.objectTable.Add(value.ObjectID, value.Reference);
@@ -103,10 +104,16 @@ namespace PdfSharp.Pdf
 
     /// <summary>
     /// Gets a cross reference entry from an object identifier.
+    /// Returns null if no object with the specified ID exists in the object table.
     /// </summary>
     public PdfReference this[PdfObjectID objectID]
     {
-      get { return (PdfReference)this.objectTable[objectID]; }
+      get
+      {
+        PdfReference iref;
+        this.objectTable.TryGetValue(objectID, out iref);
+        return iref;
+      }
     }
 
     /// <summary>
@@ -114,7 +121,7 @@ namespace PdfSharp.Pdf
     /// </summary>
     public bool Contains(PdfObjectID objectID)
     {
-      return this.objectTable.Contains(objectID);
+      return this.objectTable.ContainsKey(objectID);
     }
 
     //public PdfObject GetObject(PdfObjectID objectID)
@@ -199,8 +206,8 @@ namespace PdfSharp.Pdf
     {
       get
       {
-        ICollection collection = this.objectTable.Values;
-        ArrayList list = new ArrayList(collection);
+        Dictionary<PdfObjectID, PdfReference>.ValueCollection collection = this.objectTable.Values;
+        List<PdfReference> list = new List<PdfReference>(collection);
         list.Sort(PdfReference.Comparer);
         PdfReference[] irefs = new PdfReference[collection.Count];
         list.CopyTo(irefs, 0);
@@ -281,24 +288,24 @@ namespace PdfSharp.Pdf
     }
 
     /// <summary>
-    /// Checks the locical consistence for debugging purposes (useful after reconstruction work).
+    /// Checks the logical consistence for debugging purposes (useful after reconstruction work).
     /// </summary>
     [Conditional("DEBUG_")]
     public void CheckConsistence()
     {
-      Hashtable ht = new Hashtable();
+      Dictionary<PdfReference, object> ht1 = new Dictionary<PdfReference, object>();
       foreach (PdfReference iref in this.objectTable.Values)
       {
-        Debug.Assert(!ht.Contains(iref), "Duplicate iref.");
+        Debug.Assert(!ht1.ContainsKey(iref), "Duplicate iref.");
         Debug.Assert(iref.Value != null);
-        ht.Add(iref, null);
+        ht1.Add(iref, null);
       }
 
-      ht.Clear();
+      Dictionary<PdfObjectID, object> ht2 = new Dictionary<PdfObjectID, object>();
       foreach (PdfReference iref in this.objectTable.Values)
       {
-        Debug.Assert(!ht.Contains(iref.ObjectID), "Duplicate iref.");
-        ht.Add(iref.ObjectID, null);
+        Debug.Assert(!ht2.ContainsKey(iref.ObjectID), "Duplicate iref.");
+        ht2.Add(iref.ObjectID, null);
       }
 
       ICollection collection = this.objectTable.Values;
@@ -345,29 +352,38 @@ namespace PdfSharp.Pdf
     //  }
 
     /// <summary>
-    /// Calculates the transitive closure of the specifed PdfObject, i.e. all indirect objects
+    /// Calculates the transitive closure of the specified PdfObject, i.e. all indirect objects
     /// recursively reachable from the specified object.
     /// </summary>
     public PdfReference[] TransitiveClosure(PdfObject pdfObject)
     {
+      return TransitiveClosure(pdfObject, Int16.MaxValue);
+    }
+
+    /// <summary>
+    /// Calculates the transitive closure of the specified PdfObject with the specified depth, i.e. all indirect objects
+    /// recursively reachable from the specified object in up to maximally depth steps.
+    /// </summary>
+    public PdfReference[] TransitiveClosure(PdfObject pdfObject, int depth)
+    {
       CheckConsistence();
-      Hashtable objects = new Hashtable();
-      this.overflow = new Hashtable();
-      TransitiveClosureImplementation(objects, pdfObject);
+      Dictionary<PdfItem, object> objects = new Dictionary<PdfItem, object>();
+      this.overflow = new Dictionary<PdfItem, object>();
+      TransitiveClosureImplementation(objects, pdfObject, ref depth);
     TryAgain:
       if (this.overflow.Count > 0)
       {
-        object[] array = new object[this.overflow.Count];
+        PdfObject[] array = new PdfObject[this.overflow.Count];
         this.overflow.Keys.CopyTo(array, 0);
-        this.overflow = new Hashtable();
+        this.overflow = new Dictionary<PdfItem, object>();
         for (int idx = 0; idx < array.Length; idx++)
         {
-          object o = array[idx];
-          o.GetType();
-          PdfObject obj = array[idx] as PdfObject;
+          //PdfObject o = array[idx];
+          //o.GetType();
+          PdfObject obj = array[idx];
           //if (!objects.Contains(obj))
           //  objects.Add(obj, null);
-          TransitiveClosureImplementation(objects, obj);
+          TransitiveClosureImplementation(objects, obj, ref depth);
         }
         goto TryAgain;
       }
@@ -397,10 +413,12 @@ namespace PdfSharp.Pdf
       return irefs;
     }
 
-    static int nestingLevel = 0;
-    Hashtable overflow = new Hashtable();
-    void TransitiveClosureImplementation(Hashtable objects, PdfObject pdfObject)
+    static int nestingLevel;
+    Dictionary<PdfItem, object> overflow = new Dictionary<PdfItem, object>();
+    void TransitiveClosureImplementation(Dictionary<PdfItem, object> objects, PdfObject pdfObject, ref int depth)
     {
+      if (depth-- == 0)
+        return;
       try
       {
         nestingLevel++;
@@ -408,7 +426,7 @@ namespace PdfSharp.Pdf
         {
           //Debug.WriteLine(String.Format("Nestinglevel={0}", nestingLevel));
           //GetType();
-          if (!this.overflow.Contains(pdfObject))
+          if (!this.overflow.ContainsKey(pdfObject))
             this.overflow.Add(pdfObject, null);
           return;
         }
@@ -463,7 +481,7 @@ namespace PdfSharp.Pdf
               if (iref.ObjectID.ObjectNumber == 23)
                 GetType();
 #endif
-              if (!objects.Contains(iref))
+              if (!objects.ContainsKey(iref))
               {
                 PdfObject value = iref.Value;
 
@@ -473,7 +491,7 @@ namespace PdfSharp.Pdf
                   // ... from trailer hack
                   if (value == null)
                   {
-                    iref = (PdfReference)this.objectTable[iref.ObjectID];
+                    iref = this.objectTable[iref.ObjectID];
                     Debug.Assert(iref.Value != null);
                     value = iref.Value;
                   }
@@ -481,7 +499,7 @@ namespace PdfSharp.Pdf
                   objects.Add(iref, null);
                   //Debug.WriteLine(String.Format("objects.Add('{0}', null);", iref.ObjectID.ToString()));
                   if (value is PdfArray || value is PdfDictionary)
-                    TransitiveClosureImplementation(objects, value);
+                    TransitiveClosureImplementation(objects, value, ref depth);
                 }
                 //else
                 //{
@@ -495,7 +513,7 @@ namespace PdfSharp.Pdf
               //if (pdfObject28 != null)
               //  Debug.Assert(Object.ReferenceEquals(pdfObject28.Document, this.document));
               if (pdfObject28 != null && (pdfObject28 is PdfDictionary || pdfObject28 is PdfArray))
-                TransitiveClosureImplementation(objects, pdfObject28);
+                TransitiveClosureImplementation(objects, pdfObject28, ref depth);
             }
           }
         }
diff --git a/lib/PdfSharp/PdfSharp.Pdf/PdfString.cs b/lib/PdfSharp/PdfSharp.Pdf/PdfString.cs
index c0ea4f7..9357c85 100644
--- a/lib/PdfSharp/PdfSharp.Pdf/PdfString.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf/PdfString.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -48,7 +48,7 @@ namespace PdfSharp.Pdf
     /// The characters of the string are actually bytes with an unknown or context specific meaning or encoding.
     /// With this encoding the 8 high bits of each character is zero.
     /// </summary>
-    RawEncoding       = 0x00,
+    RawEncoding = 0x00,
 
     /// <summary>
     /// Not yet used by PDFsharp.
@@ -89,16 +89,16 @@ namespace PdfSharp.Pdf
   [Flags]
   enum PdfStringFlags
   {
-    RawEncoding       = 0x00,
-    StandardEncoding  = 0x01,  // not used by PDFsharp
-    PDFDocEncoding    = 0x02,
-    WinAnsiEncoding   = 0x03,
-    MacRomanEncoding  = 0x04,  // not used by PDFsharp
+    RawEncoding = 0x00,
+    StandardEncoding = 0x01,  // not used by PDFsharp
+    PDFDocEncoding = 0x02,
+    WinAnsiEncoding = 0x03,
+    MacRomanEncoding = 0x04,  // not used by PDFsharp
     MacExpertEncoding = 0x05,  // not used by PDFsharp
-    Unicode           = 0x06,
-    EncodingMask      = 0x0F,
+    Unicode = 0x06,
+    EncodingMask = 0x0F,
 
-    HexLiteral        = 0x80,
+    HexLiteral = 0x80,
   }
 
   /// <summary>
@@ -195,9 +195,9 @@ namespace PdfSharp.Pdf
     internal byte[] EncryptionValue
     {
       // TODO: Unicode case is not handled!
-      get {return this.value == null ? new byte[0] : PdfEncoders.RawEncoding.GetBytes(this.value);}
+      get { return this.value == null ? new byte[0] : PdfEncoders.RawEncoding.GetBytes(this.value); }
       // BUG: May lead to trouble with the value semantics of PdfString
-      set {this.value = PdfEncoders.RawEncoding.GetString(value);}
+      set { this.value = PdfEncoders.RawEncoding.GetString(value, 0, value.Length); }
     }
 
     /// <summary>
@@ -209,6 +209,50 @@ namespace PdfSharp.Pdf
     }
 
     /// <summary>
+    /// Hack for document encoded bookmarks.
+    /// </summary>
+    public string ToStringFromPdfDocEncoded()
+    {
+      int length = this.value.Length;
+      char[] bytes = new char[length];
+      for (int idx = 0; idx < length; idx++)
+      {
+        char ch = this.value[idx];
+        if (ch <= 255)
+        {
+          bytes[idx] = Encode[ch];
+        }
+        else
+        {
+          Debugger.Break();
+        }
+      }
+      StringBuilder sb = new StringBuilder(length);
+      for (int idx = 0; idx < length; idx++)
+        sb.Append((char)bytes[idx]);
+      return sb.ToString();
+    }
+    static char[] Encode = new char[]
+    {
+      '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07', '\x08', '\x09', '\x0A', '\x0B', '\x0C', '\x0D', '\x0E', '\x0F',
+      '\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17', '\x18', '\x19', '\x1A', '\x1B', '\x1C', '\x1D', '\x1E', '\x1F',
+      '\x20', '\x21', '\x22', '\x23', '\x24', '\x25', '\x26', '\x27', '\x28', '\x29', '\x2A', '\x2B', '\x2C', '\x2D', '\x2E', '\x2F',
+      '\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', '\x38', '\x39', '\x3A', '\x3B', '\x3C', '\x3D', '\x3E', '\x3F',
+      '\x40', '\x41', '\x42', '\x43', '\x44', '\x45', '\x46', '\x47', '\x48', '\x49', '\x4A', '\x4B', '\x4C', '\x4D', '\x4E', '\x4F',
+      '\x50', '\x51', '\x52', '\x53', '\x54', '\x55', '\x56', '\x57', '\x58', '\x59', '\x5A', '\x5B', '\x5C', '\x5D', '\x5E', '\x5F',
+      '\x60', '\x61', '\x62', '\x63', '\x64', '\x65', '\x66', '\x67', '\x68', '\x69', '\x6A', '\x6B', '\x6C', '\x6D', '\x6E', '\x6F',
+      '\x70', '\x71', '\x72', '\x73', '\x74', '\x75', '\x76', '\x77', '\x78', '\x79', '\x7A', '\x7B', '\x7C', '\x7D', '\x7E', '\x7F',
+      '\x2022', '\x2020', '\x2021', '\x2026', '\x2014', '\x2013', '\x0192', '\x2044', '\x2039', '\x203A', '\x2212', '\x2030', '\x201E', '\x201C', '\x201D', '\x2018',
+      '\x2019', '\x201A', '\x2122', '\xFB01', '\xFB02', '\x0141', '\x0152', '\x0160', '\x0178', '\x017D', '\x0131', '\x0142', '\x0153', '\x0161', '\x017E', '\xFFFD',
+      '\x20AC', '\xA1', '\xA2', '\xA3', '\xA4', '\xA5', '\xA6', '\xA7', '\xA8', '\xA9', '\xAA', '\xAB', '\xAC', '\xAD', '\xAE', '\xAF',
+      '\xB0', '\xB1', '\xB2', '\xB3', '\xB4', '\xB5', '\xB6', '\xB7', '\xB8', '\xB9', '\xBA', '\xBB', '\xBC', '\xBD', '\xBE', '\xBF',
+      '\xC0', '\xC1', '\xC2', '\xC3', '\xC4', '\xC5', '\xC6', '\xC7', '\xC8', '\xC9', '\xCA', '\xCB', '\xCC', '\xCD', '\xCE', '\xCF',
+      '\xD0', '\xD1', '\xD2', '\xD3', '\xD4', '\xD5', '\xD6', '\xD7', '\xD8', '\xD9', '\xDA', '\xDB', '\xDC', '\xDD', '\xDE', '\xDF',
+      '\xE0', '\xE1', '\xE2', '\xE3', '\xE4', '\xE5', '\xE6', '\xE7', '\xE8', '\xE9', '\xEA', '\xEB', '\xEC', '\xED', '\xEE', '\xEF',
+      '\xF0', '\xF1', '\xF2', '\xF3', '\xF4', '\xF5', '\xF6', '\xF7', '\xF8', '\xF9', '\xFA', '\xFB', '\xFC', '\xFD', '\xFE', '\xFF',
+    };
+
+    /// <summary>
     /// Writes the string DocEncoded.
     /// </summary>
     internal override void WriteObject(PdfWriter writer)
diff --git a/lib/PdfSharp/PdfSharp.Pdf/PdfStringObject.cs b/lib/PdfSharp/PdfSharp.Pdf/PdfStringObject.cs
index 869cbe1..ef60d5a 100644
--- a/lib/PdfSharp/PdfSharp.Pdf/PdfStringObject.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf/PdfStringObject.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -58,7 +58,8 @@ namespace PdfSharp.Pdf
     /// </summary>
     /// <param name="document">The document.</param>
     /// <param name="value">The value.</param>
-    public PdfStringObject(PdfDocument document, string value) : base(document)
+    public PdfStringObject(PdfDocument document, string value)
+      : base(document)
     {
       this.value = value;
       this.flags = PdfStringFlags.RawEncoding;
@@ -90,7 +91,7 @@ namespace PdfSharp.Pdf
     /// </summary>
     public int Length
     {
-      get {return this.value == null ? 0 : this.value.Length;}
+      get { return this.value == null ? 0 : this.value.Length; }
     }
 
     /// <summary>
@@ -99,7 +100,7 @@ namespace PdfSharp.Pdf
     public PdfStringEncoding Encoding
     {
       get { return (PdfStringEncoding)(this.flags & PdfStringFlags.EncodingMask); }
-      set { this.flags = (this.flags & ~PdfStringFlags.EncodingMask) | ((PdfStringFlags)value & PdfStringFlags.EncodingMask);}
+      set { this.flags = (this.flags & ~PdfStringFlags.EncodingMask) | ((PdfStringFlags)value & PdfStringFlags.EncodingMask); }
     }
 
     /// <summary>
@@ -108,7 +109,7 @@ namespace PdfSharp.Pdf
     public bool HexLiteral
     {
       get { return (this.flags & PdfStringFlags.HexLiteral) != 0; }
-      set { this.flags = value ? this.flags | PdfStringFlags.HexLiteral : this.flags & ~PdfStringFlags.HexLiteral;}
+      set { this.flags = value ? this.flags | PdfStringFlags.HexLiteral : this.flags & ~PdfStringFlags.HexLiteral; }
     }
 
     PdfStringFlags flags;
@@ -118,8 +119,8 @@ namespace PdfSharp.Pdf
     /// </summary>
     public string Value
     {
-      get { return this.value == null ? "" : this.value; }
-      set { this.value = value == null ? "" : value; }
+      get { return this.value ?? ""; }
+      set { this.value = value ?? ""; }
     }
     string value;
 
@@ -129,8 +130,8 @@ namespace PdfSharp.Pdf
     internal byte[] EncryptionValue
     {
       // TODO: Unicode case is not handled!
-      get {return this.value == null ? new byte[0] : PdfEncoders.RawEncoding.GetBytes(this.value);}
-      set {this.value = PdfEncoders.RawEncoding.GetString(value);}
+      get { return this.value == null ? new byte[0] : PdfEncoders.RawEncoding.GetBytes(this.value); }
+      set { this.value = PdfEncoders.RawEncoding.GetString(value, 0, value.Length); }
     }
 
     /// <summary>
diff --git a/lib/PdfSharp/PdfSharp.Pdf/PdfUInteger.cs b/lib/PdfSharp/PdfSharp.Pdf/PdfUInteger.cs
index ebc5be3..b260f1b 100644
--- a/lib/PdfSharp/PdfSharp.Pdf/PdfUInteger.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf/PdfUInteger.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Pdf/PdfUIntegerObject.cs b/lib/PdfSharp/PdfSharp.Pdf/PdfUIntegerObject.cs
index ccee6f1..d5e3878 100644
--- a/lib/PdfSharp/PdfSharp.Pdf/PdfUIntegerObject.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf/PdfUIntegerObject.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Pdf/PdfViewerPreferences.cs b/lib/PdfSharp/PdfSharp.Pdf/PdfViewerPreferences.cs
index cf7d7ed..c7d8b95 100644
--- a/lib/PdfSharp/PdfSharp.Pdf/PdfViewerPreferences.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf/PdfViewerPreferences.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Pdf/TrimMargins.cs b/lib/PdfSharp/PdfSharp.Pdf/TrimMargins.cs
index 25199c2..4692180 100644
--- a/lib/PdfSharp/PdfSharp.Pdf/TrimMargins.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf/TrimMargins.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Pdf/enums/DocumentState.cs b/lib/PdfSharp/PdfSharp.Pdf/enums/DocumentState.cs
index 8b41cd7..b9ddde5 100644
--- a/lib/PdfSharp/PdfSharp.Pdf/enums/DocumentState.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf/enums/DocumentState.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -27,11 +27,14 @@
 // DEALINGS IN THE SOFTWARE.
 #endregion
 
+using System;
+
 namespace PdfSharp.Pdf
 {
   /// <summary>
   /// Identifies the state of the document
   /// </summary>
+  [Flags]
   enum DocumentState
   {
     /// <summary>
diff --git a/lib/PdfSharp/PdfSharp.Pdf/enums/PdfColorMode.cs b/lib/PdfSharp/PdfSharp.Pdf/enums/PdfColorMode.cs
index 79322b4..d37fcdc 100644
--- a/lib/PdfSharp/PdfSharp.Pdf/enums/PdfColorMode.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf/enums/PdfColorMode.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Pdf/enums/PdfCustomValueCompression.cs b/lib/PdfSharp/PdfSharp.Pdf/enums/PdfCustomValueCompression.cs
index a9dc219..115c591 100644
--- a/lib/PdfSharp/PdfSharp.Pdf/enums/PdfCustomValueCompression.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf/enums/PdfCustomValueCompression.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -40,12 +40,12 @@ namespace PdfSharp.Pdf
     Default,
 
     /// <summary>
-    /// Left custom values uncompressed.
+    /// Leave custom values uncompressed.
     /// </summary>
     Uncompressed,
 
     /// <summary>
-    /// Compress custom values using FalteDecode.
+    /// Compress custom values using FlateDecode.
     /// </summary>
     Compressed,
   }
diff --git a/lib/PdfSharp/PdfSharp.Pdf/enums/PdfFontEmbedding.cs b/lib/PdfSharp/PdfSharp.Pdf/enums/PdfFontEmbedding.cs
index d438342..f4c0395 100644
--- a/lib/PdfSharp/PdfSharp.Pdf/enums/PdfFontEmbedding.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf/enums/PdfFontEmbedding.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Pdf/enums/PdfFontEncoding.cs b/lib/PdfSharp/PdfSharp.Pdf/enums/PdfFontEncoding.cs
index f12977a..d18de9b 100644
--- a/lib/PdfSharp/PdfSharp.Pdf/enums/PdfFontEncoding.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf/enums/PdfFontEncoding.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Pdf/enums/PdfOutlineStyle.cs b/lib/PdfSharp/PdfSharp.Pdf/enums/PdfOutlineStyle.cs
index cef686b..87eb918 100644
--- a/lib/PdfSharp/PdfSharp.Pdf/enums/PdfOutlineStyle.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf/enums/PdfOutlineStyle.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Pdf/enums/PdfPageLayout.cs b/lib/PdfSharp/PdfSharp.Pdf/enums/PdfPageLayout.cs
index 44b9b14..7ce4a98 100644
--- a/lib/PdfSharp/PdfSharp.Pdf/enums/PdfPageLayout.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf/enums/PdfPageLayout.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Pdf/enums/PdfPageMode.cs b/lib/PdfSharp/PdfSharp.Pdf/enums/PdfPageMode.cs
index d0f30a1..91a3309 100644
--- a/lib/PdfSharp/PdfSharp.Pdf/enums/PdfPageMode.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf/enums/PdfPageMode.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Pdf/enums/PdfReadingDirection.cs b/lib/PdfSharp/PdfSharp.Pdf/enums/PdfReadingDirection.cs
index cc37ef2..79e8329 100644
--- a/lib/PdfSharp/PdfSharp.Pdf/enums/PdfReadingDirection.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf/enums/PdfReadingDirection.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.Pdf/enums/PdfTextStringEncoding.cs b/lib/PdfSharp/PdfSharp.Pdf/enums/PdfTextStringEncoding.cs
index 452174d..cd1fa2d 100644
--- a/lib/PdfSharp/PdfSharp.Pdf/enums/PdfTextStringEncoding.cs
+++ b/lib/PdfSharp/PdfSharp.Pdf/enums/PdfTextStringEncoding.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp.SharpZipLib/Checksums/Adler32.cs b/lib/PdfSharp/PdfSharp.SharpZipLib/Checksums/Adler32.cs
index 6d7f5a2..acad607 100644
--- a/lib/PdfSharp/PdfSharp.SharpZipLib/Checksums/Adler32.cs
+++ b/lib/PdfSharp/PdfSharp.SharpZipLib/Checksums/Adler32.cs
@@ -37,164 +37,171 @@
 
 using System;
 
-namespace PdfSharp.SharpZipLib.Checksums 
+namespace PdfSharp.SharpZipLib.Checksums
 {
-	
-	/// <summary>
-	/// Computes Adler32 checksum for a stream of data. An Adler32
-	/// checksum is not as reliable as a CRC32 checksum, but a lot faster to
-	/// compute.
-	/// 
-	/// The specification for Adler32 may be found in RFC 1950.
-	/// ZLIB Compressed Data Format Specification version 3.3)
-	/// 
-	/// 
-	/// From that document:
-	/// 
-	///      "ADLER32 (Adler-32 checksum)
-	///       This contains a checksum value of the uncompressed data
-	///       (excluding any dictionary data) computed according to Adler-32
-	///       algorithm. This algorithm is a 32-bit extension and improvement
-	///       of the Fletcher algorithm, used in the ITU-T X.224 / ISO 8073
-	///       standard.
-	/// 
-	///       Adler-32 is composed of two sums accumulated per byte: s1 is
-	///       the sum of all bytes, s2 is the sum of all s1 values. Both sums
-	///       are done modulo 65521. s1 is initialized to 1, s2 to zero.  The
-	///       Adler-32 checksum is stored as s2*65536 + s1 in most-
-	///       significant-byte first (network) order."
-	/// 
-	///  "8.2. The Adler-32 algorithm
-	/// 
-	///    The Adler-32 algorithm is much faster than the CRC32 algorithm yet
-	///    still provides an extremely low probability of undetected errors.
-	/// 
-	///    The modulo on unsigned long accumulators can be delayed for 5552
-	///    bytes, so the modulo operation time is negligible.  If the bytes
-	///    are a, b, c, the second sum is 3a + 2b + c + 3, and so is position
-	///    and order sensitive, unlike the first sum, which is just a
-	///    checksum.  That 65521 is prime is important to avoid a possible
-	///    large class of two-byte errors that leave the check unchanged.
-	///    (The Fletcher checksum uses 255, which is not prime and which also
-	///    makes the Fletcher check insensitive to single byte changes 0 -
-	///    255.)
-	/// 
-	///    The sum s1 is initialized to 1 instead of zero to make the length
-	///    of the sequence part of s2, so that the length does not have to be
-	///    checked separately. (Any sequence of zeroes has a Fletcher
-	///    checksum of zero.)"
-	/// </summary>
-	/// <see cref="PdfSharp.SharpZipLib.Zip.Compression.Streams.InflaterInputStream"/>
-	/// <see cref="PdfSharp.SharpZipLib.Zip.Compression.Streams.DeflaterOutputStream"/>
-	internal sealed class Adler32 : IChecksum
-	{
-		/// <summary>
-		/// largest prime smaller than 65536
-		/// </summary>
-		readonly static uint BASE = 65521;
-		
-		uint checksum;
-		
-		/// <summary>
-		/// Returns the Adler32 data checksum computed so far.
-		/// </summary>
-		public long Value {
-			get {
-				return checksum;
-			}
-		}
-		
-		/// <summary>
-		/// Creates a new instance of the <code>Adler32</code> class.
-		/// The checksum starts off with a value of 1.
-		/// </summary>
-		public Adler32()
-		{
-			Reset();
-		}
-		
-		/// <summary>
-		/// Resets the Adler32 checksum to the initial value.
-		/// </summary>
-		public void Reset()
-		{
-			checksum = 1; //Initialize to 1
-		}
-		
-		/// <summary>
-		/// Updates the checksum with the byte b.
-		/// </summary>
-		/// <param name="bval">
-		/// the data value to add. The high byte of the int is ignored.
-		/// </param>
-		public void Update(int bval)
-		{
-			//We could make a length 1 byte array and call update again, but I
-			//would rather not have that overhead
-			uint s1 = checksum & 0xFFFF;
-			uint s2 = checksum >> 16;
-			
-			s1 = (s1 + ((uint)bval & 0xFF)) % BASE;
-			s2 = (s1 + s2) % BASE;
-			
-			checksum = (s2 << 16) + s1;
-		}
-		
-		/// <summary>
-		/// Updates the checksum with the bytes taken from the array.
-		/// </summary>
-		/// <param name="buffer">
-		/// buffer an array of bytes
-		/// </param>
-		public void Update(byte[] buffer)
-		{
-			Update(buffer, 0, buffer.Length);
-		}
-		
-		/// <summary>
-		/// Updates the checksum with the bytes taken from the array.
-		/// </summary>
-		/// <param name="buf">
-		/// an array of bytes
-		/// </param>
-		/// <param name="off">
-		/// the start of the data used for this update
-		/// </param>
-		/// <param name="len">
-		/// the number of bytes to use for this update
-		/// </param>
-		public void Update(byte[] buf, int off, int len)
-		{
-			if (buf == null) {
-				throw new ArgumentNullException("buf");
-			}
-			
-			if (off < 0 || len < 0 || off + len > buf.Length) {
-				throw new ArgumentOutOfRangeException();
-			}
-			
-			//(By Per Bothner)
-			uint s1 = checksum & 0xFFFF;
-			uint s2 = checksum >> 16;
-			
-			while (len > 0) {
-				// We can defer the modulo operation:
-				// s1 maximally grows from 65521 to 65521 + 255 * 3800
-				// s2 maximally grows by 3800 * median(s1) = 2090079800 < 2^31
-				int n = 3800;
-				if (n > len) {
-					n = len;
-				}
-				len -= n;
-				while (--n >= 0) {
-					s1 = s1 + (uint)(buf[off++] & 0xFF);
-					s2 = s2 + s1;
-				}
-				s1 %= BASE;
-				s2 %= BASE;
-			}
-			
-			checksum = (s2 << 16) | s1;
-		}
-	}
+
+  /// <summary>
+  /// Computes Adler32 checksum for a stream of data. An Adler32
+  /// checksum is not as reliable as a CRC32 checksum, but a lot faster to
+  /// compute.
+  /// 
+  /// The specification for Adler32 may be found in RFC 1950.
+  /// ZLIB Compressed Data Format Specification version 3.3)
+  /// 
+  /// 
+  /// From that document:
+  /// 
+  ///      "ADLER32 (Adler-32 checksum)
+  ///       This contains a checksum value of the uncompressed data
+  ///       (excluding any dictionary data) computed according to Adler-32
+  ///       algorithm. This algorithm is a 32-bit extension and improvement
+  ///       of the Fletcher algorithm, used in the ITU-T X.224 / ISO 8073
+  ///       standard.
+  /// 
+  ///       Adler-32 is composed of two sums accumulated per byte: s1 is
+  ///       the sum of all bytes, s2 is the sum of all s1 values. Both sums
+  ///       are done modulo 65521. s1 is initialized to 1, s2 to zero.  The
+  ///       Adler-32 checksum is stored as s2*65536 + s1 in most-
+  ///       significant-byte first (network) order."
+  /// 
+  ///  "8.2. The Adler-32 algorithm
+  /// 
+  ///    The Adler-32 algorithm is much faster than the CRC32 algorithm yet
+  ///    still provides an extremely low probability of undetected errors.
+  /// 
+  ///    The modulo on unsigned long accumulators can be delayed for 5552
+  ///    bytes, so the modulo operation time is negligible.  If the bytes
+  ///    are a, b, c, the second sum is 3a + 2b + c + 3, and so is position
+  ///    and order sensitive, unlike the first sum, which is just a
+  ///    checksum.  That 65521 is prime is important to avoid a possible
+  ///    large class of two-byte errors that leave the check unchanged.
+  ///    (The Fletcher checksum uses 255, which is not prime and which also
+  ///    makes the Fletcher check insensitive to single byte changes 0 -
+  ///    255.)
+  /// 
+  ///    The sum s1 is initialized to 1 instead of zero to make the length
+  ///    of the sequence part of s2, so that the length does not have to be
+  ///    checked separately. (Any sequence of zeroes has a Fletcher
+  ///    checksum of zero.)"
+  /// </summary>
+  /// <see cref="PdfSharp.SharpZipLib.Zip.Compression.Streams.InflaterInputStream"/>
+  /// <see cref="PdfSharp.SharpZipLib.Zip.Compression.Streams.DeflaterOutputStream"/>
+  internal sealed class Adler32 : IChecksum
+  {
+    /// <summary>
+    /// largest prime smaller than 65536
+    /// </summary>
+    readonly static uint BASE = 65521;
+
+    uint checksum;
+
+    /// <summary>
+    /// Returns the Adler32 data checksum computed so far.
+    /// </summary>
+    public long Value
+    {
+      get
+      {
+        return checksum;
+      }
+    }
+
+    /// <summary>
+    /// Creates a new instance of the <code>Adler32</code> class.
+    /// The checksum starts off with a value of 1.
+    /// </summary>
+    public Adler32()
+    {
+      Reset();
+    }
+
+    /// <summary>
+    /// Resets the Adler32 checksum to the initial value.
+    /// </summary>
+    public void Reset()
+    {
+      checksum = 1; //Initialize to 1
+    }
+
+    /// <summary>
+    /// Updates the checksum with the byte b.
+    /// </summary>
+    /// <param name="bval">
+    /// the data value to add. The high byte of the int is ignored.
+    /// </param>
+    public void Update(int bval)
+    {
+      //We could make a length 1 byte array and call update again, but I
+      //would rather not have that overhead
+      uint s1 = checksum & 0xFFFF;
+      uint s2 = checksum >> 16;
+
+      s1 = (s1 + ((uint)bval & 0xFF)) % BASE;
+      s2 = (s1 + s2) % BASE;
+
+      checksum = (s2 << 16) + s1;
+    }
+
+    /// <summary>
+    /// Updates the checksum with the bytes taken from the array.
+    /// </summary>
+    /// <param name="buffer">
+    /// buffer an array of bytes
+    /// </param>
+    public void Update(byte[] buffer)
+    {
+      Update(buffer, 0, buffer.Length);
+    }
+
+    /// <summary>
+    /// Updates the checksum with the bytes taken from the array.
+    /// </summary>
+    /// <param name="buf">
+    /// an array of bytes
+    /// </param>
+    /// <param name="off">
+    /// the start of the data used for this update
+    /// </param>
+    /// <param name="len">
+    /// the number of bytes to use for this update
+    /// </param>
+    public void Update(byte[] buf, int off, int len)
+    {
+      if (buf == null)
+      {
+        throw new ArgumentNullException("buf");
+      }
+
+      if (off < 0 || len < 0 || off + len > buf.Length)
+      {
+        throw new ArgumentOutOfRangeException();
+      }
+
+      //(By Per Bothner)
+      uint s1 = checksum & 0xFFFF;
+      uint s2 = checksum >> 16;
+
+      while (len > 0)
+      {
+        // We can defer the modulo operation:
+        // s1 maximally grows from 65521 to 65521 + 255 * 3800
+        // s2 maximally grows by 3800 * median(s1) = 2090079800 < 2^31
+        int n = 3800;
+        if (n > len)
+        {
+          n = len;
+        }
+        len -= n;
+        while (--n >= 0)
+        {
+          s1 = s1 + (uint)(buf[off++] & 0xFF);
+          s2 = s2 + s1;
+        }
+        s1 %= BASE;
+        s2 %= BASE;
+      }
+
+      checksum = (s2 << 16) | s1;
+    }
+  }
 }
diff --git a/lib/PdfSharp/PdfSharp.SharpZipLib/Zip/Compression/Deflater.cs b/lib/PdfSharp/PdfSharp.SharpZipLib/Zip/Compression/Deflater.cs
index 975ede8..072aa59 100644
--- a/lib/PdfSharp/PdfSharp.SharpZipLib/Zip/Compression/Deflater.cs
+++ b/lib/PdfSharp/PdfSharp.SharpZipLib/Zip/Compression/Deflater.cs
@@ -41,512 +41,550 @@ using System;
 
 namespace PdfSharp.SharpZipLib.Zip.Compression
 {
-	
-	/// <summary>
-	/// This is the Deflater class.  The deflater class compresses input
-	/// with the deflate algorithm described in RFC 1951.  It has several
-	/// compression levels and three different strategies described below.
-	///
-	/// This class is <i>not</i> thread safe.  This is inherent in the API, due
-	/// to the split of deflate and setInput.
-	/// 
-	/// author of the original java version : Jochen Hoenicke
-	/// </summary>
-	internal class Deflater
-	{
-		/// <summary>
-		/// The best and slowest compression level.  This tries to find very
-		/// long and distant string repetitions.
-		/// </summary>
-		public static  int BEST_COMPRESSION = 9;
-		
-		/// <summary>
-		/// The worst but fastest compression level.
-		/// </summary>
-		public static  int BEST_SPEED = 1;
-		
-		/// <summary>
-		/// The default compression level.
-		/// </summary>
-		public static  int DEFAULT_COMPRESSION = -1;
-		
-		/// <summary>
-		/// This level won't compress at all but output uncompressed blocks.
-		/// </summary>
-		public static  int NO_COMPRESSION = 0;
-				
-		/// <summary>
-		/// The compression method.  This is the only method supported so far.
-		/// There is no need to use this constant at all.
-		/// </summary>
-		public static  int DEFLATED = 8;
-		
-		/*
-		* The Deflater can do the following state transitions:
-			*
-			* (1) -> INIT_STATE   ----> INIT_FINISHING_STATE ---.
-			*        /  | (2)      (5)                         |
-			*       /   v          (5)                         |
-			*   (3)| SETDICT_STATE ---> SETDICT_FINISHING_STATE |(3)
-			*       \   | (3)                 |        ,-------'
-			*        |  |                     | (3)   /
-			*        v  v          (5)        v      v
-			* (1) -> BUSY_STATE   ----> FINISHING_STATE
-			*                                | (6)
-			*                                v
-			*                           FINISHED_STATE
-			*    \_____________________________________/
-			*          | (7)
-			*          v
-			*        CLOSED_STATE
-			*
-			* (1) If we should produce a header we start in INIT_STATE, otherwise
-			*     we start in BUSY_STATE.
-			* (2) A dictionary may be set only when we are in INIT_STATE, then
-			*     we change the state as indicated.
-			* (3) Whether a dictionary is set or not, on the first call of deflate
-			*     we change to BUSY_STATE.
-			* (4) -- intentionally left blank -- :)
-			* (5) FINISHING_STATE is entered, when flush() is called to indicate that
-			*     there is no more INPUT.  There are also states indicating, that
-			*     the header wasn't written yet.
-			* (6) FINISHED_STATE is entered, when everything has been flushed to the
-			*     internal pending output buffer.
-			* (7) At any time (7)
-			*
-			*/
-			
-		private static  int IS_SETDICT              = 0x01;
-		private static  int IS_FLUSHING             = 0x04;
-		private static  int IS_FINISHING            = 0x08;
-		
-		private static  int INIT_STATE              = 0x00;
-		private static  int SETDICT_STATE           = 0x01;
-		//		private static  int INIT_FINISHING_STATE    = 0x08;
-		//		private static  int SETDICT_FINISHING_STATE = 0x09;
-		private static  int BUSY_STATE              = 0x10;
-		private static  int FLUSHING_STATE          = 0x14;
-		private static  int FINISHING_STATE         = 0x1c;
-		private static  int FINISHED_STATE          = 0x1e;
-		private static  int CLOSED_STATE            = 0x7f;
-		
-		/// <summary>
-		/// Compression level.
-		/// </summary>
-		private int level;
-		
-		/// <summary>
-		/// If true no Zlib/RFC1950 headers or footers are generated
-		/// </summary>
-		private bool noZlibHeaderOrFooter;
-		
-		/// <summary>
-		/// The current state.
-		/// </summary>
-		private int state;
-		
-		/// <summary>
-		/// The total bytes of output written.
-		/// </summary>
-		private long totalOut;
-		
-		/// <summary>
-		/// The pending output.
-		/// </summary>
-		private DeflaterPending pending;
-		
-		/// <summary>
-		/// The deflater engine.
-		/// </summary>
-		private DeflaterEngine engine;
-		
-		/// <summary>
-		/// Creates a new deflater with default compression level.
-		/// </summary>
-		public Deflater() : this(DEFAULT_COMPRESSION, false)
-		{
-			
-		}
-		
-		/// <summary>
-		/// Creates a new deflater with given compression level.
-		/// </summary>
-		/// <param name="lvl">
-		/// the compression level, a value between NO_COMPRESSION
-		/// and BEST_COMPRESSION, or DEFAULT_COMPRESSION.
-		/// </param>
-		/// <exception cref="System.ArgumentOutOfRangeException">if lvl is out of range.</exception>
-		public Deflater(int lvl) : this(lvl, false)
-		{
-			
-		}
-		
-		/// <summary>
-		/// Creates a new deflater with given compression level.
-		/// </summary>
-		/// <param name="level">
-		/// the compression level, a value between NO_COMPRESSION
-		/// and BEST_COMPRESSION.
-		/// </param>
-		/// <param name="noZlibHeaderOrFooter">
-		/// true, if we should suppress the Zlib/RFC1950 header at the
-		/// beginning and the adler checksum at the end of the output.  This is
-		/// useful for the GZIP/PKZIP formats.
-		/// </param>
-		/// <exception cref="System.ArgumentOutOfRangeException">if lvl is out of range.</exception>
-		public Deflater(int level, bool noZlibHeaderOrFooter)
-		{
-			if (level == DEFAULT_COMPRESSION) {
-				level = 6;
-			} else if (level < NO_COMPRESSION || level > BEST_COMPRESSION) {
-				throw new ArgumentOutOfRangeException("level");
-			}
-			
-			pending = new DeflaterPending();
-			engine = new DeflaterEngine(pending);
-			this.noZlibHeaderOrFooter = noZlibHeaderOrFooter;
-			SetStrategy(DeflateStrategy.Default);
-			SetLevel(level);
-			Reset();
-		}
-		
-		
-		/// <summary>
-		/// Resets the deflater.  The deflater acts afterwards as if it was
-		/// just created with the same compression level and strategy as it
-		/// had before.
-		/// </summary>
-		public void Reset()
-		{
-			state = (noZlibHeaderOrFooter ? BUSY_STATE : INIT_STATE);
-			totalOut = 0;
-			pending.Reset();
-			engine.Reset();
-		}
-		
-		/// <summary>
-		/// Gets the current adler checksum of the data that was processed so far.
-		/// </summary>
-		public int Adler {
-			get {
-				return engine.Adler;
-			}
-		}
-		
-		/// <summary>
-		/// Gets the number of input bytes processed so far.
-		/// </summary>
-		public int TotalIn {
-			get {
-				return engine.TotalIn;
-			}
-		}
-		
-		/// <summary>
-		/// Gets the number of output bytes so far.
-		/// </summary>
-		public long TotalOut {
-			get {
-				return totalOut;
-			}
-		}
-		
-		/// <summary>
-		/// Flushes the current input block.  Further calls to deflate() will
-		/// produce enough output to inflate everything in the current input
-		/// block.  This is not part of Sun's JDK so I have made it package
-		/// private.  It is used by DeflaterOutputStream to implement
-		/// flush().
-		/// </summary>
-		public void Flush() 
-		{
-			state |= IS_FLUSHING;
-		}
-		
-		/// <summary>
-		/// Finishes the deflater with the current input block.  It is an error
-		/// to give more input after this method was called.  This method must
-		/// be called to force all bytes to be flushed.
-		/// </summary>
-		public void Finish() 
-		{
-			state |= IS_FLUSHING | IS_FINISHING;
-		}
-		
-		/// <summary>
-		/// Returns true if the stream was finished and no more output bytes
-		/// are available.
-		/// </summary>
-		public bool IsFinished {
-			get {
-				return state == FINISHED_STATE && pending.IsFlushed;
-			}
-		}
-		
-		/// <summary>
-		/// Returns true, if the input buffer is empty.
-		/// You should then call setInput(). 
-		/// NOTE: This method can also return true when the stream
-		/// was finished.
-		/// </summary>
-		public bool IsNeedingInput {
-			get {
-				return engine.NeedsInput();
-			}
-		}
-		
-		/// <summary>
-		/// Sets the data which should be compressed next.  This should be only
-		/// called when needsInput indicates that more input is needed.
-		/// If you call setInput when needsInput() returns false, the
-		/// previous input that is still pending will be thrown away.
-		/// The given byte array should not be changed, before needsInput() returns
-		/// true again.
-		/// This call is equivalent to <code>setInput(input, 0, input.length)</code>.
-		/// </summary>
-		/// <param name="input">
-		/// the buffer containing the input data.
-		/// </param>
-		/// <exception cref="System.InvalidOperationException">
-		/// if the buffer was finished() or ended().
-		/// </exception>
-		public void SetInput(byte[] input)
-		{
-			SetInput(input, 0, input.Length);
-		}
-		
-		/// <summary>
-		/// Sets the data which should be compressed next.  This should be
-		/// only called when needsInput indicates that more input is needed.
-		/// The given byte array should not be changed, before needsInput() returns
-		/// true again.
-		/// </summary>
-		/// <param name="input">
-		/// the buffer containing the input data.
-		/// </param>
-		/// <param name="off">
-		/// the start of the data.
-		/// </param>
-		/// <param name="len">
-		/// the length of the data.
-		/// </param>
-		/// <exception cref="System.InvalidOperationException">
-		/// if the buffer was finished() or ended() or if previous input is still pending.
-		/// </exception>
-		public void SetInput(byte[] input, int off, int len)
-		{
-			if ((state & IS_FINISHING) != 0) {
-				throw new InvalidOperationException("finish()/end() already called");
-			}
-			engine.SetInput(input, off, len);
-		}
-		
-		/// <summary>
-		/// Sets the compression level.  There is no guarantee of the exact
-		/// position of the change, but if you call this when needsInput is
-		/// true the change of compression level will occur somewhere near
-		/// before the end of the so far given input.
-		/// </summary>
-		/// <param name="lvl">
-		/// the new compression level.
-		/// </param>
-		public void SetLevel(int lvl)
-		{
-			if (lvl == DEFAULT_COMPRESSION) {
-				lvl = 6;
-			} else if (lvl < NO_COMPRESSION || lvl > BEST_COMPRESSION) {
-				throw new ArgumentOutOfRangeException("lvl");
-			}
-			
-			if (level != lvl) {
-				level = lvl;
-				engine.SetLevel(lvl);
-			}
-		}
-		
-		/// <summary>
-		/// Get current compression level
-		/// </summary>
-		/// <returns>Returns the current compression level</returns>
-		public int GetLevel() {
-			return level;
-		}
-		
-		/// <summary>
-		/// Sets the compression strategy. Strategy is one of
-		/// DEFAULT_STRATEGY, HUFFMAN_ONLY and FILTERED.  For the exact
-		/// position where the strategy is changed, the same as for
-		/// setLevel() applies.
-		/// </summary>
-		/// <param name="strategy">
-		/// The new compression strategy.
-		/// </param>
-		public void SetStrategy(DeflateStrategy strategy)
-		{
-			engine.Strategy = strategy;
-		}
-		
-		/// <summary>
-		/// Deflates the current input block with to the given array.
-		/// </summary>
-		/// <param name="output">
-		/// The buffer where compressed data is stored
-		/// </param>
-		/// <returns>
-		/// The number of compressed bytes added to the output, or 0 if either
-		/// needsInput() or finished() returns true or length is zero.
-		/// </returns>
-		public int Deflate(byte[] output)
-		{
-			return Deflate(output, 0, output.Length);
-		}
-		
-		/// <summary>
-		/// Deflates the current input block to the given array.
-		/// </summary>
-		/// <param name="output">
-		/// Buffer to store the compressed data.
-		/// </param>
-		/// <param name="offset">
-		/// Offset into the output array.
-		/// </param>
-		/// <param name="length">
-		/// The maximum number of bytes that may be stored.
-		/// </param>
-		/// <returns>
-		/// The number of compressed bytes added to the output, or 0 if either
-		/// needsInput() or finished() returns true or length is zero.
-		/// </returns>
-		/// <exception cref="System.InvalidOperationException">
-		/// If end() was previously called.
-		/// </exception>
-		/// <exception cref="System.ArgumentOutOfRangeException">
-		/// If offset and/or length don't match the array length.
-		/// </exception>
-		public int Deflate(byte[] output, int offset, int length)
-		{
-			int origLength = length;
-			
-			if (state == CLOSED_STATE) {
-				throw new InvalidOperationException("Deflater closed");
-			}
-			
-			if (state < BUSY_STATE) {
-				/* output header */
-				int header = (DEFLATED +
-					((DeflaterConstants.MAX_WBITS - 8) << 4)) << 8;
-				int level_flags = (level - 1) >> 1;
-				if (level_flags < 0 || level_flags > 3) {
-					level_flags = 3;
-				}
-				header |= level_flags << 6;
-				if ((state & IS_SETDICT) != 0) {
-					/* Dictionary was set */
-					header |= DeflaterConstants.PRESET_DICT;
-				}
-				header += 31 - (header % 31);
-				
-				
-				pending.WriteShortMSB(header);
-				if ((state & IS_SETDICT) != 0) {
-					int chksum = engine.Adler;
-					engine.ResetAdler();
-					pending.WriteShortMSB(chksum >> 16);
-					pending.WriteShortMSB(chksum & 0xffff);
-				}
-				
-				state = BUSY_STATE | (state & (IS_FLUSHING | IS_FINISHING));
-			}
-			
-			for (;;) {
-				int count = pending.Flush(output, offset, length);
-				offset   += count;
-				totalOut += count;
-				length   -= count;
-				
-				if (length == 0 || state == FINISHED_STATE) {
-					break;
-				}
-				
-				if (!engine.Deflate((state & IS_FLUSHING) != 0, (state & IS_FINISHING) != 0)) {
-					if (state == BUSY_STATE) {
-						/* We need more input now */
-						return origLength - length;
-					} else if (state == FLUSHING_STATE) {
-						if (level != NO_COMPRESSION) {
-							/* We have to supply some lookahead.  8 bit lookahead
-							 * is needed by the zlib inflater, and we must fill
-							 * the next byte, so that all bits are flushed.
-							 */
-							int neededbits = 8 + ((-pending.BitCount) & 7);
-							while (neededbits > 0) {
-								/* write a static tree block consisting solely of
-								 * an EOF:
-								 */
-								pending.WriteBits(2, 10);
-								neededbits -= 10;
-							}
-						}
-						state = BUSY_STATE;
-					} else if (state == FINISHING_STATE) {
-						pending.AlignToByte();
-
-						// Compressed data is complete.  Write footer information if required.
-						if (!noZlibHeaderOrFooter) {
-							int adler = engine.Adler;
-							pending.WriteShortMSB(adler >> 16);
-							pending.WriteShortMSB(adler & 0xffff);
-						}
-						state = FINISHED_STATE;
-					}
-				}
-			}
-			return origLength - length;
-		}
-		
-		/// <summary>
-		/// Sets the dictionary which should be used in the deflate process.
-		/// This call is equivalent to <code>setDictionary(dict, 0, dict.Length)</code>.
-		/// </summary>
-		/// <param name="dict">
-		/// the dictionary.
-		/// </param>
-		/// <exception cref="System.InvalidOperationException">
-		/// if setInput () or deflate () were already called or another dictionary was already set.
-		/// </exception>
-		public void SetDictionary(byte[] dict)
-		{
-			SetDictionary(dict, 0, dict.Length);
-		}
-		
-		/// <summary>
-		/// Sets the dictionary which should be used in the deflate process.
-		/// The dictionary is a byte array containing strings that are
-		/// likely to occur in the data which should be compressed.  The
-		/// dictionary is not stored in the compressed output, only a
-		/// checksum.  To decompress the output you need to supply the same
-		/// dictionary again.
-		/// </summary>
-		/// <param name="dict">
-		/// The dictionary data
-		/// </param>
-		/// <param name="offset">
-		/// An offset into the dictionary.
-		/// </param>
-		/// <param name="length">
-		/// The length of the dictionary data to use
-		/// </param>
-		/// <exception cref="System.InvalidOperationException">
-		/// If setInput () or deflate () were already called or another dictionary was already set.
-		/// </exception>
-		public void SetDictionary(byte[] dict, int offset, int length)
-		{
-			if (state != INIT_STATE) {
-				throw new InvalidOperationException();
-			}
-			
-			state = SETDICT_STATE;
-			engine.SetDictionary(dict, offset, length);
-		}
-	}
+
+  /// <summary>
+  /// This is the Deflater class.  The deflater class compresses input
+  /// with the deflate algorithm described in RFC 1951.  It has several
+  /// compression levels and three different strategies described below.
+  ///
+  /// This class is <i>not</i> thread safe.  This is inherent in the API, due
+  /// to the split of deflate and setInput.
+  /// 
+  /// Author of the original java version: Jochen Hoenicke
+  /// </summary>
+  internal class Deflater
+  {
+    /// <summary>
+    /// The best and slowest compression level.  This tries to find very
+    /// long and distant string repetitions.
+    /// </summary>
+    public static int BEST_COMPRESSION = 9;
+
+    /// <summary>
+    /// The worst but fastest compression level.
+    /// </summary>
+    public static int BEST_SPEED = 1;
+
+    /// <summary>
+    /// The default compression level.
+    /// </summary>
+    public static int DEFAULT_COMPRESSION = -1;
+
+    /// <summary>
+    /// This level won't compress at all but output uncompressed blocks.
+    /// </summary>
+    public static int NO_COMPRESSION = 0;
+
+    /// <summary>
+    /// The compression method.  This is the only method supported so far.
+    /// There is no need to use this constant at all.
+    /// </summary>
+    public static int DEFLATED = 8;
+
+    /*
+    * The Deflater can do the following state transitions:
+      *
+      * (1) -> INIT_STATE   ----> INIT_FINISHING_STATE ---.
+      *        /  | (2)      (5)                         |
+      *       /   v          (5)                         |
+      *   (3)| SETDICT_STATE ---> SETDICT_FINISHING_STATE |(3)
+      *       \   | (3)                 |        ,-------'
+      *        |  |                     | (3)   /
+      *        v  v          (5)        v      v
+      * (1) -> BUSY_STATE   ----> FINISHING_STATE
+      *                                | (6)
+      *                                v
+      *                           FINISHED_STATE
+      *    \_____________________________________/
+      *          | (7)
+      *          v
+      *        CLOSED_STATE
+      *
+      * (1) If we should produce a header we start in INIT_STATE, otherwise
+      *     we start in BUSY_STATE.
+      * (2) A dictionary may be set only when we are in INIT_STATE, then
+      *     we change the state as indicated.
+      * (3) Whether a dictionary is set or not, on the first call of deflate
+      *     we change to BUSY_STATE.
+      * (4) -- intentionally left blank -- :)
+      * (5) FINISHING_STATE is entered, when flush() is called to indicate that
+      *     there is no more INPUT.  There are also states indicating, that
+      *     the header wasn't written yet.
+      * (6) FINISHED_STATE is entered, when everything has been flushed to the
+      *     internal pending output buffer.
+      * (7) At any time (7)
+      *
+      */
+
+    private static int IS_SETDICT = 0x01;
+    private static int IS_FLUSHING = 0x04;
+    private static int IS_FINISHING = 0x08;
+
+    private static int INIT_STATE = 0x00;
+    private static int SETDICT_STATE = 0x01;
+    //		private static  int INIT_FINISHING_STATE    = 0x08;
+    //		private static  int SETDICT_FINISHING_STATE = 0x09;
+    private static int BUSY_STATE = 0x10;
+    private static int FLUSHING_STATE = 0x14;
+    private static int FINISHING_STATE = 0x1c;
+    private static int FINISHED_STATE = 0x1e;
+    private static int CLOSED_STATE = 0x7f;
+
+    /// <summary>
+    /// Compression level.
+    /// </summary>
+    private int level;
+
+    /// <summary>
+    /// If true no Zlib/RFC1950 headers or footers are generated
+    /// </summary>
+    private bool noZlibHeaderOrFooter;
+
+    /// <summary>
+    /// The current state.
+    /// </summary>
+    private int state;
+
+    /// <summary>
+    /// The total bytes of output written.
+    /// </summary>
+    private long totalOut;
+
+    /// <summary>
+    /// The pending output.
+    /// </summary>
+    private DeflaterPending pending;
+
+    /// <summary>
+    /// The deflater engine.
+    /// </summary>
+    private DeflaterEngine engine;
+
+    /// <summary>
+    /// Creates a new deflater with default compression level.
+    /// </summary>
+    public Deflater()
+      : this(DEFAULT_COMPRESSION, false)
+    {
+
+    }
+
+    /// <summary>
+    /// Creates a new deflater with given compression level.
+    /// </summary>
+    /// <param name="lvl">
+    /// the compression level, a value between NO_COMPRESSION
+    /// and BEST_COMPRESSION, or DEFAULT_COMPRESSION.
+    /// </param>
+    /// <exception cref="System.ArgumentOutOfRangeException">if lvl is out of range.</exception>
+    public Deflater(int lvl)
+      : this(lvl, false)
+    {
+
+    }
+
+    /// <summary>
+    /// Creates a new deflater with given compression level.
+    /// </summary>
+    /// <param name="level">
+    /// the compression level, a value between NO_COMPRESSION
+    /// and BEST_COMPRESSION.
+    /// </param>
+    /// <param name="noZlibHeaderOrFooter">
+    /// true, if we should suppress the Zlib/RFC1950 header at the
+    /// beginning and the adler checksum at the end of the output.  This is
+    /// useful for the GZIP/PKZIP formats.
+    /// </param>
+    /// <exception cref="System.ArgumentOutOfRangeException">if lvl is out of range.</exception>
+    public Deflater(int level, bool noZlibHeaderOrFooter)
+    {
+      if (level == DEFAULT_COMPRESSION)
+      {
+        level = 6;
+      }
+      else if (level < NO_COMPRESSION || level > BEST_COMPRESSION)
+      {
+        throw new ArgumentOutOfRangeException("level");
+      }
+
+      pending = new DeflaterPending();
+      engine = new DeflaterEngine(pending);
+      this.noZlibHeaderOrFooter = noZlibHeaderOrFooter;
+      SetStrategy(DeflateStrategy.Default);
+      SetLevel(level);
+      Reset();
+    }
+
+
+    /// <summary>
+    /// Resets the deflater.  The deflater acts afterwards as if it was
+    /// just created with the same compression level and strategy as it
+    /// had before.
+    /// </summary>
+    public void Reset()
+    {
+      state = (noZlibHeaderOrFooter ? BUSY_STATE : INIT_STATE);
+      totalOut = 0;
+      pending.Reset();
+      engine.Reset();
+    }
+
+    /// <summary>
+    /// Gets the current adler checksum of the data that was processed so far.
+    /// </summary>
+    public int Adler
+    {
+      get
+      {
+        return engine.Adler;
+      }
+    }
+
+    /// <summary>
+    /// Gets the number of input bytes processed so far.
+    /// </summary>
+    public int TotalIn
+    {
+      get
+      {
+        return engine.TotalIn;
+      }
+    }
+
+    /// <summary>
+    /// Gets the number of output bytes so far.
+    /// </summary>
+    public long TotalOut
+    {
+      get
+      {
+        return totalOut;
+      }
+    }
+
+    /// <summary>
+    /// Flushes the current input block.  Further calls to deflate() will
+    /// produce enough output to inflate everything in the current input
+    /// block.  This is not part of Sun's JDK so I have made it package
+    /// private.  It is used by DeflaterOutputStream to implement
+    /// flush().
+    /// </summary>
+    public void Flush()
+    {
+      state |= IS_FLUSHING;
+    }
+
+    /// <summary>
+    /// Finishes the deflater with the current input block.  It is an error
+    /// to give more input after this method was called.  This method must
+    /// be called to force all bytes to be flushed.
+    /// </summary>
+    public void Finish()
+    {
+      state |= IS_FLUSHING | IS_FINISHING;
+    }
+
+    /// <summary>
+    /// Returns true if the stream was finished and no more output bytes
+    /// are available.
+    /// </summary>
+    public bool IsFinished
+    {
+      get
+      {
+        return state == FINISHED_STATE && pending.IsFlushed;
+      }
+    }
+
+    /// <summary>
+    /// Returns true, if the input buffer is empty.
+    /// You should then call setInput(). 
+    /// NOTE: This method can also return true when the stream
+    /// was finished.
+    /// </summary>
+    public bool IsNeedingInput
+    {
+      get
+      {
+        return engine.NeedsInput();
+      }
+    }
+
+    /// <summary>
+    /// Sets the data which should be compressed next.  This should be only
+    /// called when needsInput indicates that more input is needed.
+    /// If you call setInput when needsInput() returns false, the
+    /// previous input that is still pending will be thrown away.
+    /// The given byte array should not be changed, before needsInput() returns
+    /// true again.
+    /// This call is equivalent to <code>setInput(input, 0, input.length)</code>.
+    /// </summary>
+    /// <param name="input">
+    /// the buffer containing the input data.
+    /// </param>
+    /// <exception cref="System.InvalidOperationException">
+    /// if the buffer was finished() or ended().
+    /// </exception>
+    public void SetInput(byte[] input)
+    {
+      SetInput(input, 0, input.Length);
+    }
+
+    /// <summary>
+    /// Sets the data which should be compressed next.  This should be
+    /// only called when needsInput indicates that more input is needed.
+    /// The given byte array should not be changed, before needsInput() returns
+    /// true again.
+    /// </summary>
+    /// <param name="input">
+    /// the buffer containing the input data.
+    /// </param>
+    /// <param name="off">
+    /// the start of the data.
+    /// </param>
+    /// <param name="len">
+    /// the length of the data.
+    /// </param>
+    /// <exception cref="System.InvalidOperationException">
+    /// if the buffer was finished() or ended() or if previous input is still pending.
+    /// </exception>
+    public void SetInput(byte[] input, int off, int len)
+    {
+      if ((state & IS_FINISHING) != 0)
+      {
+        throw new InvalidOperationException("finish()/end() already called");
+      }
+      engine.SetInput(input, off, len);
+    }
+
+    /// <summary>
+    /// Sets the compression level.  There is no guarantee of the exact
+    /// position of the change, but if you call this when needsInput is
+    /// true the change of compression level will occur somewhere near
+    /// before the end of the so far given input.
+    /// </summary>
+    /// <param name="lvl">
+    /// the new compression level.
+    /// </param>
+    public void SetLevel(int lvl)
+    {
+      if (lvl == DEFAULT_COMPRESSION)
+      {
+        lvl = 6;
+      }
+      else if (lvl < NO_COMPRESSION || lvl > BEST_COMPRESSION)
+      {
+        throw new ArgumentOutOfRangeException("lvl");
+      }
+
+      if (level != lvl)
+      {
+        level = lvl;
+        engine.SetLevel(lvl);
+      }
+    }
+
+    /// <summary>
+    /// Get current compression level
+    /// </summary>
+    /// <returns>Returns the current compression level</returns>
+    public int GetLevel()
+    {
+      return level;
+    }
+
+    /// <summary>
+    /// Sets the compression strategy. Strategy is one of
+    /// DEFAULT_STRATEGY, HUFFMAN_ONLY and FILTERED.  For the exact
+    /// position where the strategy is changed, the same as for
+    /// setLevel() applies.
+    /// </summary>
+    /// <param name="strategy">
+    /// The new compression strategy.
+    /// </param>
+    public void SetStrategy(DeflateStrategy strategy)
+    {
+      engine.Strategy = strategy;
+    }
+
+    /// <summary>
+    /// Deflates the current input block with to the given array.
+    /// </summary>
+    /// <param name="output">
+    /// The buffer where compressed data is stored
+    /// </param>
+    /// <returns>
+    /// The number of compressed bytes added to the output, or 0 if either
+    /// needsInput() or finished() returns true or length is zero.
+    /// </returns>
+    public int Deflate(byte[] output)
+    {
+      return Deflate(output, 0, output.Length);
+    }
+
+    /// <summary>
+    /// Deflates the current input block to the given array.
+    /// </summary>
+    /// <param name="output">
+    /// Buffer to store the compressed data.
+    /// </param>
+    /// <param name="offset">
+    /// Offset into the output array.
+    /// </param>
+    /// <param name="length">
+    /// The maximum number of bytes that may be stored.
+    /// </param>
+    /// <returns>
+    /// The number of compressed bytes added to the output, or 0 if either
+    /// needsInput() or finished() returns true or length is zero.
+    /// </returns>
+    /// <exception cref="System.InvalidOperationException">
+    /// If end() was previously called.
+    /// </exception>
+    /// <exception cref="System.ArgumentOutOfRangeException">
+    /// If offset and/or length don't match the array length.
+    /// </exception>
+    public int Deflate(byte[] output, int offset, int length)
+    {
+      int origLength = length;
+
+      if (state == CLOSED_STATE)
+      {
+        throw new InvalidOperationException("Deflater closed");
+      }
+
+      if (state < BUSY_STATE)
+      {
+        /* output header */
+        int header = (DEFLATED +
+          ((DeflaterConstants.MAX_WBITS - 8) << 4)) << 8;
+        int level_flags = (level - 1) >> 1;
+        if (level_flags < 0 || level_flags > 3)
+        {
+          level_flags = 3;
+        }
+        header |= level_flags << 6;
+        if ((state & IS_SETDICT) != 0)
+        {
+          /* Dictionary was set */
+          header |= DeflaterConstants.PRESET_DICT;
+        }
+        header += 31 - (header % 31);
+
+
+        pending.WriteShortMSB(header);
+        if ((state & IS_SETDICT) != 0)
+        {
+          int chksum = engine.Adler;
+          engine.ResetAdler();
+          pending.WriteShortMSB(chksum >> 16);
+          pending.WriteShortMSB(chksum & 0xffff);
+        }
+
+        state = BUSY_STATE | (state & (IS_FLUSHING | IS_FINISHING));
+      }
+
+      for (; ; )
+      {
+        int count = pending.Flush(output, offset, length);
+        offset += count;
+        totalOut += count;
+        length -= count;
+
+        if (length == 0 || state == FINISHED_STATE)
+        {
+          break;
+        }
+
+        if (!engine.Deflate((state & IS_FLUSHING) != 0, (state & IS_FINISHING) != 0))
+        {
+          if (state == BUSY_STATE)
+          {
+            /* We need more input now */
+            return origLength - length;
+          }
+          else if (state == FLUSHING_STATE)
+          {
+            if (level != NO_COMPRESSION)
+            {
+              /* We have to supply some lookahead.  8 bit lookahead
+               * is needed by the zlib inflater, and we must fill
+               * the next byte, so that all bits are flushed.
+               */
+              int neededbits = 8 + ((-pending.BitCount) & 7);
+              while (neededbits > 0)
+              {
+                /* write a static tree block consisting solely of
+                 * an EOF:
+                 */
+                pending.WriteBits(2, 10);
+                neededbits -= 10;
+              }
+            }
+            state = BUSY_STATE;
+          }
+          else if (state == FINISHING_STATE)
+          {
+            pending.AlignToByte();
+
+            // Compressed data is complete.  Write footer information if required.
+            if (!noZlibHeaderOrFooter)
+            {
+              int adler = engine.Adler;
+              pending.WriteShortMSB(adler >> 16);
+              pending.WriteShortMSB(adler & 0xffff);
+            }
+            state = FINISHED_STATE;
+          }
+        }
+      }
+      return origLength - length;
+    }
+
+    /// <summary>
+    /// Sets the dictionary which should be used in the deflate process.
+    /// This call is equivalent to <code>setDictionary(dict, 0, dict.Length)</code>.
+    /// </summary>
+    /// <param name="dict">
+    /// the dictionary.
+    /// </param>
+    /// <exception cref="System.InvalidOperationException">
+    /// if setInput () or deflate () were already called or another dictionary was already set.
+    /// </exception>
+    public void SetDictionary(byte[] dict)
+    {
+      SetDictionary(dict, 0, dict.Length);
+    }
+
+    /// <summary>
+    /// Sets the dictionary which should be used in the deflate process.
+    /// The dictionary is a byte array containing strings that are
+    /// likely to occur in the data which should be compressed.  The
+    /// dictionary is not stored in the compressed output, only a
+    /// checksum.  To decompress the output you need to supply the same
+    /// dictionary again.
+    /// </summary>
+    /// <param name="dict">
+    /// The dictionary data
+    /// </param>
+    /// <param name="offset">
+    /// An offset into the dictionary.
+    /// </param>
+    /// <param name="length">
+    /// The length of the dictionary data to use
+    /// </param>
+    /// <exception cref="System.InvalidOperationException">
+    /// If setInput () or deflate () were already called or another dictionary was already set.
+    /// </exception>
+    public void SetDictionary(byte[] dict, int offset, int length)
+    {
+      if (state != INIT_STATE)
+      {
+        throw new InvalidOperationException();
+      }
+
+      state = SETDICT_STATE;
+      engine.SetDictionary(dict, offset, length);
+    }
+  }
 }
diff --git a/lib/PdfSharp/PdfSharp.SharpZipLib/Zip/Compression/DeflaterHuffman.cs b/lib/PdfSharp/PdfSharp.SharpZipLib/Zip/Compression/DeflaterHuffman.cs
index 515379f..3f9f148 100644
--- a/lib/PdfSharp/PdfSharp.SharpZipLib/Zip/Compression/DeflaterHuffman.cs
+++ b/lib/PdfSharp/PdfSharp.SharpZipLib/Zip/Compression/DeflaterHuffman.cs
@@ -39,30 +39,30 @@
 
 using System;
 
-namespace PdfSharp.SharpZipLib.Zip.Compression 
+namespace PdfSharp.SharpZipLib.Zip.Compression
 {
-	
-	/// <summary>
-	/// This is the DeflaterHuffman class.
-	/// 
-	/// This class is <i>not</i> thread safe.  This is inherent in the API, due
-	/// to the split of deflate and setInput.
-	/// 
-	/// author of the original java version : Jochen Hoenicke
-	/// </summary>
-	internal class DeflaterHuffman
-	{
-		static  int BUFSIZE = 1 << (DeflaterConstants.DEFAULT_MEM_LEVEL + 6);
-		static  int LITERAL_NUM = 286;
-		static  int DIST_NUM = 30;
-		static  int BITLEN_NUM = 19;
-		static  int REP_3_6    = 16;
-		static  int REP_3_10   = 17;
-		static  int REP_11_138 = 18;
-		static  int EOF_SYMBOL = 256;
-		static  int[] BL_ORDER = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 };
-		
-		static byte[] bit4Reverse = {
+
+  /// <summary>
+  /// This is the DeflaterHuffman class.
+  /// 
+  /// This class is <i>not</i> thread safe.  This is inherent in the API, due
+  /// to the split of deflate and setInput.
+  /// 
+  /// Author of the original java version: Jochen Hoenicke
+  /// </summary>
+  internal class DeflaterHuffman
+  {
+    static int BUFSIZE = 1 << (DeflaterConstants.DEFAULT_MEM_LEVEL + 6);
+    static int LITERAL_NUM = 286;
+    static int DIST_NUM = 30;
+    static int BITLEN_NUM = 19;
+    static int REP_3_6 = 16;
+    static int REP_3_10 = 17;
+    static int REP_11_138 = 18;
+    static int EOF_SYMBOL = 256;
+    static int[] BL_ORDER = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 };
+
+    static byte[] bit4Reverse = {
 			0,
 			8,
 			4,
@@ -80,808 +80,898 @@ namespace PdfSharp.SharpZipLib.Zip.Compression
 			7,
 			15
 		};
-		
-		/// <summary>
-		/// Not documented
-		/// </summary>
-		internal class Tree 
-		{
-			/// <summary>
-			/// Not documented
-			/// </summary>
-			public short[] freqs;
-			
-			/// <summary>
-			/// Not documented
-			/// </summary>
-			public byte[]  length;
-			
-			/// <summary>
-			/// Not documented
-			/// </summary>
-			public int     minNumCodes;
-			
-			/// <summary>
-			/// Not documented
-			/// </summary>
-			public int     numCodes;
-			
-			short[] codes;
-			int[]   bl_counts;
-			int     maxLength;
-			DeflaterHuffman dh;
-			
-			/// <summary>
-			/// Not documented
-			/// </summary>
-			public Tree(DeflaterHuffman dh, int elems, int minCodes, int maxLength) 
-			{
-				this.dh =  dh;
-				this.minNumCodes = minCodes;
-				this.maxLength  = maxLength;
-				freqs  = new short[elems];
-				bl_counts = new int[maxLength];
-			}
-			
-			/// <summary>
-			/// Resets the internal state of the tree
-			/// </summary>
-			public void Reset() 
-			{
-				for (int i = 0; i < freqs.Length; i++) {
-					freqs[i] = 0;
-				}
-				codes = null;
-				length = null;
-			}
-			
-			/// <summary>
-			/// Not documented
-			/// </summary>
-			public void WriteSymbol(int code)
-			{
-				//				if (DeflaterConstants.DEBUGGING) {
-				//					freqs[code]--;
-				//					//  	  Console.Write("writeSymbol("+freqs.length+","+code+"): ");
-				//				}
-				dh.pending.WriteBits(codes[code] & 0xffff, length[code]);
-			}
-			
-			/// <summary>
-			/// Check that at least one frequency is non-zero
-			/// </summary>
-			/// <exception cref="SharpZipBaseException">
-			/// No frequencies are non-zero
-			/// </exception>
-			public void CheckEmpty()
-			{
-				bool empty = true;
-				for (int i = 0; i < freqs.Length; i++) {
-					if (freqs[i] != 0) {
-						//Console.WriteLine("freqs[" + i + "] == " + freqs[i]);
-						empty = false;
-					}
-				}
-				
-				if (!empty) {
-					throw new SharpZipBaseException("!Empty");
-				}
-				//Console.WriteLine("checkEmpty suceeded!");
-			}
-
-			/// <summary>
-			/// Set static codes and length
-			/// </summary>
-			/// <param name="stCodes">new codes</param>
-			/// <param name="stLength">length for new codes</param>
-			public void SetStaticCodes(short[] stCodes, byte[] stLength)
-			{
-				codes = stCodes;
-				length = stLength;
-			}
-			
-			/// <summary>
-			/// Build dynamic codes and lengths
-			/// </summary>
-			public void BuildCodes() 
-			{
-				int numSymbols = freqs.Length;
-				int[] nextCode = new int[maxLength];
-				int code = 0;
-				codes = new short[freqs.Length];
-				
-				//				if (DeflaterConstants.DEBUGGING) {
-				//					//Console.WriteLine("buildCodes: "+freqs.Length);
-				//				}
-				
-				for (int bits = 0; bits < maxLength; bits++) {
-					nextCode[bits] = code;
-					code += bl_counts[bits] << (15 - bits);
-					//					if (DeflaterConstants.DEBUGGING) {
-					//						//Console.WriteLine("bits: " + ( bits + 1) + " count: " + bl_counts[bits]
-					//						                  +" nextCode: "+code);
-					//					}
-				}
-				if (DeflaterConstants.DEBUGGING && code != 65536) {
-					throw new SharpZipBaseException("Inconsistent bl_counts!");
-				}
-				
-				for (int i=0; i < numCodes; i++) {
-					int bits = length[i];
-					if (bits > 0) {
-						//						if (DeflaterConstants.DEBUGGING) {
-						//								//Console.WriteLine("codes["+i+"] = rev(" + nextCode[bits-1]+"),
-						//								                  +bits);
-						//						}
-						codes[i] = BitReverse(nextCode[bits-1]);
-						nextCode[bits-1] += 1 << (16 - bits);
-					}
-				}
-			}
-			
-			void BuildLength(int[] childs)
-			{
-				this.length = new byte [freqs.Length];
-				int numNodes = childs.Length / 2;
-				int numLeafs = (numNodes + 1) / 2;
-				int overflow = 0;
-				
-				for (int i = 0; i < maxLength; i++) {
-					bl_counts[i] = 0;
-				}
-				
-				/* First calculate optimal bit lengths */
-				int[] lengths = new int[numNodes];
-				lengths[numNodes-1] = 0;
-				
-				for (int i = numNodes - 1; i >= 0; i--) {
-					if (childs[2*i+1] != -1) {
-						int bitLength = lengths[i] + 1;
-						if (bitLength > maxLength) {
-							bitLength = maxLength;
-							overflow++;
-						}
-						lengths[childs[2*i]] = lengths[childs[2*i+1]] = bitLength;
-					} else {
-						/* A leaf node */
-						int bitLength = lengths[i];
-						bl_counts[bitLength - 1]++;
-						this.length[childs[2*i]] = (byte) lengths[i];
-					}
-				}
-				
-				//				if (DeflaterConstants.DEBUGGING) {
-				//					//Console.WriteLine("Tree "+freqs.Length+" lengths:");
-				//					for (int i=0; i < numLeafs; i++) {
-				//						//Console.WriteLine("Node "+childs[2*i]+" freq: "+freqs[childs[2*i]]
-				//						                  + " len: "+length[childs[2*i]]);
-				//					}
-				//				}
-				
-				if (overflow == 0) {
-					return;
-				}
-				
-				int incrBitLen = maxLength - 1;
-				do {
-					/* Find the first bit length which could increase: */
-					while (bl_counts[--incrBitLen] == 0)
-						;
-					
-					/* Move this node one down and remove a corresponding
-					* amount of overflow nodes.
-					*/
-					do {
-						bl_counts[incrBitLen]--;
-						bl_counts[++incrBitLen]++;
-						overflow -= 1 << (maxLength - 1 - incrBitLen);
-					} while (overflow > 0 && incrBitLen < maxLength - 1);
-				} while (overflow > 0);
-				
-				/* We may have overshot above.  Move some nodes from maxLength to
-				* maxLength-1 in that case.
-				*/
-				bl_counts[maxLength-1] += overflow;
-				bl_counts[maxLength-2] -= overflow;
-				
-				/* Now recompute all bit lengths, scanning in increasing
-				* frequency.  It is simpler to reconstruct all lengths instead of
-				* fixing only the wrong ones. This idea is taken from 'ar'
-				* written by Haruhiko Okumura.
-				*
-				* The nodes were inserted with decreasing frequency into the childs
-				* array.
-				*/
-				int nodePtr = 2 * numLeafs;
-				for (int bits = maxLength; bits != 0; bits--) {
-					int n = bl_counts[bits-1];
-					while (n > 0) {
-						int childPtr = 2*childs[nodePtr++];
-						if (childs[childPtr + 1] == -1) {
-							/* We found another leaf */
-							length[childs[childPtr]] = (byte) bits;
-							n--;
-						}
-					}
-				}
-				//				if (DeflaterConstants.DEBUGGING) {
-				//					//Console.WriteLine("*** After overflow elimination. ***");
-				//					for (int i=0; i < numLeafs; i++) {
-				//						//Console.WriteLine("Node "+childs[2*i]+" freq: "+freqs[childs[2*i]]
-				//						                  + " len: "+length[childs[2*i]]);
-				//					}
-				//				}
-			}
-			
-			/// <summary>
-			/// Not documented
-			/// </summary>
-			public void BuildTree()
-			{
-				int numSymbols = freqs.Length;
-				
-				/* heap is a priority queue, sorted by frequency, least frequent
-				* nodes first.  The heap is a binary tree, with the property, that
-				* the parent node is smaller than both child nodes.  This assures
-				* that the smallest node is the first parent.
-				*
-				* The binary tree is encoded in an array:  0 is root node and
-				* the nodes 2*n+1, 2*n+2 are the child nodes of node n.
-				*/
-				int[] heap = new int[numSymbols];
-				int heapLen = 0;
-				int maxCode = 0;
-				for (int n = 0; n < numSymbols; n++) {
-					int freq = freqs[n];
-					if (freq != 0) {
-						/* Insert n into heap */
-						int pos = heapLen++;
-						int ppos;
-						while (pos > 0 && freqs[heap[ppos = (pos - 1) / 2]] > freq) {
-							heap[pos] = heap[ppos];
-							pos = ppos;
-						}
-						heap[pos] = n;
-						
-						maxCode = n;
-					}
-				}
-				
-				/* We could encode a single literal with 0 bits but then we
-				* don't see the literals.  Therefore we force at least two
-				* literals to avoid this case.  We don't care about order in
-				* this case, both literals get a 1 bit code.
-				*/
-				while (heapLen < 2) {
-					int node = maxCode < 2 ? ++maxCode : 0;
-					heap[heapLen++] = node;
-				}
-				
-				numCodes = Math.Max(maxCode + 1, minNumCodes);
-				
-				int numLeafs = heapLen;
-				int[] childs = new int[4*heapLen - 2];
-				int[] values = new int[2*heapLen - 1];
-				int numNodes = numLeafs;
-				for (int i = 0; i < heapLen; i++) {
-					int node = heap[i];
-					childs[2*i]   = node;
-					childs[2*i+1] = -1;
-					values[i] = freqs[node] << 8;
-					heap[i] = i;
-				}
-				
-				/* Construct the Huffman tree by repeatedly combining the least two
-				* frequent nodes.
-				*/
-				do {
-					int first = heap[0];
-					int last  = heap[--heapLen];
-					
-					/* Propagate the hole to the leafs of the heap */
-					int ppos = 0;
-					int path = 1;
-					
-					while (path < heapLen) {
-						if (path + 1 < heapLen && values[heap[path]] > values[heap[path+1]]) {
-							path++;
-						}
-							
-						heap[ppos] = heap[path];
-						ppos = path;
-						path = path * 2 + 1;
-					}
-						
-					/* Now propagate the last element down along path.  Normally
-					* it shouldn't go too deep.
-					*/
-					int lastVal = values[last];
-					while ((path = ppos) > 0 && values[heap[ppos = (path - 1)/2]] > lastVal) {
-						heap[path] = heap[ppos];
-					}
-					heap[path] = last;
-					
-					
-					int second = heap[0];
-					
-					/* Create a new node father of first and second */
-					last = numNodes++;
-					childs[2*last] = first;
-					childs[2*last+1] = second;
-					int mindepth = Math.Min(values[first] & 0xff, values[second] & 0xff);
-					values[last] = lastVal = values[first] + values[second] - mindepth + 1;
-					
-					/* Again, propagate the hole to the leafs */
-					ppos = 0;
-					path = 1;
-					
-					while (path < heapLen) {
-						if (path + 1 < heapLen && values[heap[path]] > values[heap[path+1]]) {
-							path++;
-						}
-							
-						heap[ppos] = heap[path];
-						ppos = path;
-						path = ppos * 2 + 1;
-					}
-						
-					/* Now propagate the new element down along path */
-					while ((path = ppos) > 0 && values[heap[ppos = (path - 1)/2]] > lastVal) {
-						heap[path] = heap[ppos];
-					}
-					heap[path] = last;
-				} while (heapLen > 1);
-				
-				if (heap[0] != childs.Length / 2 - 1) {
-					throw new SharpZipBaseException("Heap invariant violated");
-				}
-				
-				BuildLength(childs);
-			}
-			
-			/// <summary>
-			/// Get encoded length
-			/// </summary>
-			/// <returns>Encoded length, the sum of frequencies * lengths</returns>
-			public int GetEncodedLength()
-			{
-				int len = 0;
-				for (int i = 0; i < freqs.Length; i++) {
-					len += freqs[i] * length[i];
-				}
-				return len;
-			}
-			
-			/// <summary>
-			/// Not documented
-			/// </summary>
-			public void CalcBLFreq(Tree blTree) 
-			{
-				int max_count;               /* max repeat count */
-				int min_count;               /* min repeat count */
-				int count;                   /* repeat count of the current code */
-				int curlen = -1;             /* length of current code */
-				
-				int i = 0;
-				while (i < numCodes) {
-					count = 1;
-					int nextlen = length[i];
-					if (nextlen == 0) {
-						max_count = 138;
-						min_count = 3;
-					} else {
-						max_count = 6;
-						min_count = 3;
-						if (curlen != nextlen) {
-							blTree.freqs[nextlen]++;
-							count = 0;
-						}
-					}
-					curlen = nextlen;
-					i++;
-					
-					while (i < numCodes && curlen == length[i]) {
-						i++;
-						if (++count >= max_count) {
-							break;
-						}
-					}
-					
-					if (count < min_count) {
-						blTree.freqs[curlen] += (short)count;
-					} else if (curlen != 0) {
-						blTree.freqs[REP_3_6]++;
-					} else if (count <= 10) {
-						blTree.freqs[REP_3_10]++;
-					} else {
-						blTree.freqs[REP_11_138]++;
-					}
-				}
-			}
-		
-			/// <summary>
-			/// Write tree values
-			/// </summary>
-			/// <param name="blTree">Tree to write</param>
-			public void WriteTree(Tree blTree)
-			{
-				int max_count;               /* max repeat count */
-				int min_count;               /* min repeat count */
-				int count;                   /* repeat count of the current code */
-				int curlen = -1;             /* length of current code */
-				
-				int i = 0;
-				while (i < numCodes) {
-					count = 1;
-					int nextlen = length[i];
-					if (nextlen == 0) {
-						max_count = 138;
-						min_count = 3;
-					} else {
-						max_count = 6;
-						min_count = 3;
-						if (curlen != nextlen) {
-							blTree.WriteSymbol(nextlen);
-							count = 0;
-						}
-					}
-					curlen = nextlen;
-					i++;
-					
-					while (i < numCodes && curlen == length[i]) {
-						i++;
-						if (++count >= max_count) {
-							break;
-						}
-					}
-					
-					if (count < min_count) {
-						while (count-- > 0) {
-							blTree.WriteSymbol(curlen);
-						}
-					} else if (curlen != 0) {
-						blTree.WriteSymbol(REP_3_6);
-						dh.pending.WriteBits(count - 3, 2);
-					} else if (count <= 10) {
-						blTree.WriteSymbol(REP_3_10);
-						dh.pending.WriteBits(count - 3, 3);
-					} else {
-						blTree.WriteSymbol(REP_11_138);
-						dh.pending.WriteBits(count - 11, 7);
-					}
-				}
-			}
-		}
-		
-		/// <summary>
-		/// Pending buffer to use
-		/// </summary>
-		public DeflaterPending pending;
-		
-		Tree literalTree, distTree, blTree;
-		
-		short[] d_buf;
-		byte[]  l_buf;
-		int last_lit;
-		int extra_bits;
-		
-		static short[] staticLCodes;
-		static byte[]  staticLLength;
-		static short[] staticDCodes;
-		static byte[]  staticDLength;
-		
-		/// <summary>
-		/// Reverse the bits of a 16 bit value.
-		/// </summary>
-		/// <param name="toReverse">Value to reverse bits</param>
-		/// <returns>Value with bits reversed</returns>
-		public static short BitReverse(int toReverse) 
-		{
-			return (short) (bit4Reverse[toReverse & 0xF] << 12 | 
-			                bit4Reverse[(toReverse >> 4) & 0xF] << 8 | 
-			                bit4Reverse[(toReverse >> 8) & 0xF] << 4 |
-			                bit4Reverse[toReverse >> 12]);
-		}
-		
-		
-		static DeflaterHuffman() 
-		{
-			/* See RFC 1951 3.2.6 */
-			/* Literal codes */
-			staticLCodes = new short[LITERAL_NUM];
-			staticLLength = new byte[LITERAL_NUM];
-			int i = 0;
-			while (i < 144) {
-				staticLCodes[i] = BitReverse((0x030 + i) << 8);
-				staticLLength[i++] = 8;
-			}
-			while (i < 256) {
-				staticLCodes[i] = BitReverse((0x190 - 144 + i) << 7);
-				staticLLength[i++] = 9;
-			}
-			while (i < 280) {
-				staticLCodes[i] = BitReverse((0x000 - 256 + i) << 9);
-				staticLLength[i++] = 7;
-			}
-			while (i < LITERAL_NUM) {
-				staticLCodes[i] = BitReverse((0x0c0 - 280 + i)  << 8);
-				staticLLength[i++] = 8;
-			}
-			
-			/* Distant codes */
-			staticDCodes = new short[DIST_NUM];
-			staticDLength = new byte[DIST_NUM];
-			for (i = 0; i < DIST_NUM; i++) {
-				staticDCodes[i] = BitReverse(i << 11);
-				staticDLength[i] = 5;
-			}
-		}
-		
-		/// <summary>
-		/// Construct instance with pending buffer
-		/// </summary>
-		/// <param name="pending">Pending buffer to use</param>
-		public DeflaterHuffman(DeflaterPending pending)
-		{
-			this.pending = pending;
-			
-			literalTree = new Tree(this, LITERAL_NUM, 257, 15);
-			distTree    = new Tree(this, DIST_NUM, 1, 15);
-			blTree      = new Tree(this, BITLEN_NUM, 4, 7);
-			
-			d_buf = new short[BUFSIZE];
-			l_buf = new byte [BUFSIZE];
-		}
-
-		/// <summary>
-		/// Reset internal state
-		/// </summary>		
-		public void Reset() 
-		{
-			last_lit = 0;
-			extra_bits = 0;
-			literalTree.Reset();
-			distTree.Reset();
-			blTree.Reset();
-		}
-		
-		int Lcode(int len) 
-		{
-			if (len == 255) {
-				return 285;
-			}
-			
-			int code = 257;
-			while (len >= 8) {
-				code += 4;
-				len >>= 1;
-			}
-			return code + len;
-		}
-		
-		int Dcode(int distance) 
-		{
-			int code = 0;
-			while (distance >= 4) {
-				code += 2;
-				distance >>= 1;
-			}
-			return code + distance;
-		}
-
-		/// <summary>
-		/// Write all trees to pending buffer
-		/// </summary>		
-		public void SendAllTrees(int blTreeCodes)
-		{
-			blTree.BuildCodes();
-			literalTree.BuildCodes();
-			distTree.BuildCodes();
-			pending.WriteBits(literalTree.numCodes - 257, 5);
-			pending.WriteBits(distTree.numCodes - 1, 5);
-			pending.WriteBits(blTreeCodes - 4, 4);
-			for (int rank = 0; rank < blTreeCodes; rank++) {
-				pending.WriteBits(blTree.length[BL_ORDER[rank]], 3);
-			}
-			literalTree.WriteTree(blTree);
-			distTree.WriteTree(blTree);
-			//			if (DeflaterConstants.DEBUGGING) {
-			//				blTree.CheckEmpty();
-			//			}
-		}
-
-		/// <summary>
-		/// Compress current buffer writing data to pending buffer
-		/// </summary>
-		public void CompressBlock()
-		{
-			for (int i = 0; i < last_lit; i++) {
-				int litlen = l_buf[i] & 0xff;
-				int dist = d_buf[i];
-				if (dist-- != 0) {
-					//					if (DeflaterConstants.DEBUGGING) {
-					//						Console.Write("["+(dist+1)+","+(litlen+3)+"]: ");
-					//					}
-					
-					int lc = Lcode(litlen);
-					literalTree.WriteSymbol(lc);
-					
-					int bits = (lc - 261) / 4;
-					if (bits > 0 && bits <= 5) {
-						pending.WriteBits(litlen & ((1 << bits) - 1), bits);
-					}
-					
-					int dc = Dcode(dist);
-					distTree.WriteSymbol(dc);
-					
-					bits = dc / 2 - 1;
-					if (bits > 0) {
-						pending.WriteBits(dist & ((1 << bits) - 1), bits);
-					}
-				} else {
-					//					if (DeflaterConstants.DEBUGGING) {
-					//						if (litlen > 32 && litlen < 127) {
-					//							Console.Write("("+(char)litlen+"): ");
-					//						} else {
-					//							Console.Write("{"+litlen+"}: ");
-					//						}
-					//					}
-					literalTree.WriteSymbol(litlen);
-				}
-			}
-			//			if (DeflaterConstants.DEBUGGING) {
-			//				Console.Write("EOF: ");
-			//			}
-			literalTree.WriteSymbol(EOF_SYMBOL);
-			//			if (DeflaterConstants.DEBUGGING) {
-			//				literalTree.CheckEmpty();
-			//				distTree.CheckEmpty();
-			//			}
-		}
-		
-		/// <summary>
-		/// Flush block to output with no compression
-		/// </summary>
-		/// <param name="stored">Data to write</param>
-		/// <param name="storedOffset">Index of first byte to write</param>
-		/// <param name="storedLength">Count of bytes to write</param>
-		/// <param name="lastBlock">True if this is the last block</param>
-		public void FlushStoredBlock(byte[] stored, int storedOffset, int storedLength, bool lastBlock)
-		{
-			//			if (DeflaterConstants.DEBUGGING) {
-			//				//Console.WriteLine("Flushing stored block "+ storedLength);
-			//			}
-			pending.WriteBits((DeflaterConstants.STORED_BLOCK << 1) + (lastBlock ? 1 : 0), 3);
-			pending.AlignToByte();
-			pending.WriteShort(storedLength);
-			pending.WriteShort(~storedLength);
-			pending.WriteBlock(stored, storedOffset, storedLength);
-			Reset();
-		}
-
-		/// <summary>
-		/// Flush block to output with compression
-		/// </summary>		
-		/// <param name="stored">Data to flush</param>
-		/// <param name="storedOffset">Index of first byte to flush</param>
-		/// <param name="storedLength">Count of bytes to flush</param>
-		/// <param name="lastBlock">True if this is the last block</param>
-		public void FlushBlock(byte[] stored, int storedOffset, int storedLength, bool lastBlock)
-		{
-			literalTree.freqs[EOF_SYMBOL]++;
-			
-			/* Build trees */
-			literalTree.BuildTree();
-			distTree.BuildTree();
-			
-			/* Calculate bitlen frequency */
-			literalTree.CalcBLFreq(blTree);
-			distTree.CalcBLFreq(blTree);
-			
-			/* Build bitlen tree */
-			blTree.BuildTree();
-			
-			int blTreeCodes = 4;
-			for (int i = 18; i > blTreeCodes; i--) {
-				if (blTree.length[BL_ORDER[i]] > 0) {
-					blTreeCodes = i+1;
-				}
-			}
-			int opt_len = 14 + blTreeCodes * 3 + blTree.GetEncodedLength() + 
-				literalTree.GetEncodedLength() + distTree.GetEncodedLength() + 
-				extra_bits;
-			
-			int static_len = extra_bits;
-			for (int i = 0; i < LITERAL_NUM; i++) {
-				static_len += literalTree.freqs[i] * staticLLength[i];
-			}
-			for (int i = 0; i < DIST_NUM; i++) {
-				static_len += distTree.freqs[i] * staticDLength[i];
-			}
-			if (opt_len >= static_len) {
-				/* Force static trees */
-				opt_len = static_len;
-			}
-			
-			if (storedOffset >= 0 && storedLength + 4 < opt_len >> 3) {
-				/* Store Block */
-				//				if (DeflaterConstants.DEBUGGING) {
-				//					//Console.WriteLine("Storing, since " + storedLength + " < " + opt_len
-				//					                  + " <= " + static_len);
-				//				}
-				FlushStoredBlock(stored, storedOffset, storedLength, lastBlock);
-			} else if (opt_len == static_len) {
-				/* Encode with static tree */
-				pending.WriteBits((DeflaterConstants.STATIC_TREES << 1) + (lastBlock ? 1 : 0), 3);
-				literalTree.SetStaticCodes(staticLCodes, staticLLength);
-				distTree.SetStaticCodes(staticDCodes, staticDLength);
-				CompressBlock();
-				Reset();
-			} else {
-				/* Encode with dynamic tree */
-				pending.WriteBits((DeflaterConstants.DYN_TREES << 1) + (lastBlock ? 1 : 0), 3);
-				SendAllTrees(blTreeCodes);
-				CompressBlock();
-				Reset();
-			}
-		}
-		
-		/// <summary>
-		/// Get value indicating if internal buffer is full
-		/// </summary>
-		/// <returns>true if buffer is full</returns>
-		public bool IsFull()
-		{
-			return last_lit >= BUFSIZE;
-		}
-		
-		/// <summary>
-		/// Add literal to buffer
-		/// </summary>
-		/// <param name="lit"></param>
-		/// <returns>Value indicating internal buffer is full</returns>
-		public bool TallyLit(int lit)
-		{
-			//			if (DeflaterConstants.DEBUGGING) {
-			//				if (lit > 32 && lit < 127) {
-			//					//Console.WriteLine("("+(char)lit+")");
-			//				} else {
-			//					//Console.WriteLine("{"+lit+"}");
-			//				}
-			//			}
-			d_buf[last_lit] = 0;
-			l_buf[last_lit++] = (byte)lit;
-			literalTree.freqs[lit]++;
-			return IsFull();
-		}
-		
-		/// <summary>
-		/// Add distance code and length to literal and distance trees
-		/// </summary>
-		/// <param name="dist">Distance code</param>
-		/// <param name="len">Length</param>
-		/// <returns>Value indicating if internal buffer is full</returns>
-		public bool TallyDist(int dist, int len)
-		{
-			//			if (DeflaterConstants.DEBUGGING) {
-			//				//Console.WriteLine("["+dist+","+len+"]");
-			//			}
-			
-			d_buf[last_lit]   = (short)dist;
-			l_buf[last_lit++] = (byte)(len - 3);
-			
-			int lc = Lcode(len - 3);
-			literalTree.freqs[lc]++;
-			if (lc >= 265 && lc < 285) {
-				extra_bits += (lc - 261) / 4;
-			}
-			
-			int dc = Dcode(dist - 1);
-			distTree.freqs[dc]++;
-			if (dc >= 4) {
-				extra_bits += dc / 2 - 1;
-			}
-			return IsFull();
-		}
-	}
+
+    /// <summary>
+    /// Not documented
+    /// </summary>
+    internal class Tree
+    {
+      /// <summary>
+      /// Not documented
+      /// </summary>
+      public short[] freqs;
+
+      /// <summary>
+      /// Not documented
+      /// </summary>
+      public byte[] length;
+
+      /// <summary>
+      /// Not documented
+      /// </summary>
+      public int minNumCodes;
+
+      /// <summary>
+      /// Not documented
+      /// </summary>
+      public int numCodes;
+
+      short[] codes;
+      int[] bl_counts;
+      int maxLength;
+      DeflaterHuffman dh;
+
+      /// <summary>
+      /// Not documented
+      /// </summary>
+      public Tree(DeflaterHuffman dh, int elems, int minCodes, int maxLength)
+      {
+        this.dh = dh;
+        this.minNumCodes = minCodes;
+        this.maxLength = maxLength;
+        freqs = new short[elems];
+        bl_counts = new int[maxLength];
+      }
+
+      /// <summary>
+      /// Resets the internal state of the tree
+      /// </summary>
+      public void Reset()
+      {
+        for (int i = 0; i < freqs.Length; i++)
+        {
+          freqs[i] = 0;
+        }
+        codes = null;
+        length = null;
+      }
+
+      /// <summary>
+      /// Not documented
+      /// </summary>
+      public void WriteSymbol(int code)
+      {
+        //				if (DeflaterConstants.DEBUGGING) {
+        //					freqs[code]--;
+        //					//  	  Console.Write("writeSymbol("+freqs.length+","+code+"): ");
+        //				}
+        dh.pending.WriteBits(codes[code] & 0xffff, length[code]);
+      }
+
+      /// <summary>
+      /// Check that at least one frequency is non-zero
+      /// </summary>
+      /// <exception cref="SharpZipBaseException">
+      /// No frequencies are non-zero
+      /// </exception>
+      public void CheckEmpty()
+      {
+        bool empty = true;
+        for (int i = 0; i < freqs.Length; i++)
+        {
+          if (freqs[i] != 0)
+          {
+            //Console.WriteLine("freqs[" + i + "] == " + freqs[i]);
+            empty = false;
+          }
+        }
+
+        if (!empty)
+        {
+          throw new SharpZipBaseException("!Empty");
+        }
+        //Console.WriteLine("checkEmpty suceeded!");
+      }
+
+      /// <summary>
+      /// Set static codes and length
+      /// </summary>
+      /// <param name="stCodes">new codes</param>
+      /// <param name="stLength">length for new codes</param>
+      public void SetStaticCodes(short[] stCodes, byte[] stLength)
+      {
+        codes = stCodes;
+        length = stLength;
+      }
+
+      /// <summary>
+      /// Build dynamic codes and lengths
+      /// </summary>
+      public void BuildCodes()
+      {
+        int numSymbols = freqs.Length;
+        int[] nextCode = new int[maxLength];
+        int code = 0;
+        codes = new short[freqs.Length];
+
+        //				if (DeflaterConstants.DEBUGGING) {
+        //					//Console.WriteLine("buildCodes: "+freqs.Length);
+        //				}
+
+        for (int bits = 0; bits < maxLength; bits++)
+        {
+          nextCode[bits] = code;
+          code += bl_counts[bits] << (15 - bits);
+          //					if (DeflaterConstants.DEBUGGING) {
+          //						//Console.WriteLine("bits: " + ( bits + 1) + " count: " + bl_counts[bits]
+          //						                  +" nextCode: "+code);
+          //					}
+        }
+        if (DeflaterConstants.DEBUGGING && code != 65536)
+        {
+          throw new SharpZipBaseException("Inconsistent bl_counts!");
+        }
+
+        for (int i = 0; i < numCodes; i++)
+        {
+          int bits = length[i];
+          if (bits > 0)
+          {
+            //						if (DeflaterConstants.DEBUGGING) {
+            //								//Console.WriteLine("codes["+i+"] = rev(" + nextCode[bits-1]+"),
+            //								                  +bits);
+            //						}
+            codes[i] = BitReverse(nextCode[bits - 1]);
+            nextCode[bits - 1] += 1 << (16 - bits);
+          }
+        }
+      }
+
+      void BuildLength(int[] childs)
+      {
+        this.length = new byte[freqs.Length];
+        int numNodes = childs.Length / 2;
+        int numLeafs = (numNodes + 1) / 2;
+        int overflow = 0;
+
+        for (int i = 0; i < maxLength; i++)
+        {
+          bl_counts[i] = 0;
+        }
+
+        /* First calculate optimal bit lengths */
+        int[] lengths = new int[numNodes];
+        lengths[numNodes - 1] = 0;
+
+        for (int i = numNodes - 1; i >= 0; i--)
+        {
+          if (childs[2 * i + 1] != -1)
+          {
+            int bitLength = lengths[i] + 1;
+            if (bitLength > maxLength)
+            {
+              bitLength = maxLength;
+              overflow++;
+            }
+            lengths[childs[2 * i]] = lengths[childs[2 * i + 1]] = bitLength;
+          }
+          else
+          {
+            /* A leaf node */
+            int bitLength = lengths[i];
+            bl_counts[bitLength - 1]++;
+            this.length[childs[2 * i]] = (byte)lengths[i];
+          }
+        }
+
+        //				if (DeflaterConstants.DEBUGGING) {
+        //					//Console.WriteLine("Tree "+freqs.Length+" lengths:");
+        //					for (int i=0; i < numLeafs; i++) {
+        //						//Console.WriteLine("Node "+childs[2*i]+" freq: "+freqs[childs[2*i]]
+        //						                  + " len: "+length[childs[2*i]]);
+        //					}
+        //				}
+
+        if (overflow == 0)
+        {
+          return;
+        }
+
+        int incrBitLen = maxLength - 1;
+        do
+        {
+          /* Find the first bit length which could increase: */
+          while (bl_counts[--incrBitLen] == 0)
+            ;
+
+          /* Move this node one down and remove a corresponding
+          * amount of overflow nodes.
+          */
+          do
+          {
+            bl_counts[incrBitLen]--;
+            bl_counts[++incrBitLen]++;
+            overflow -= 1 << (maxLength - 1 - incrBitLen);
+          } while (overflow > 0 && incrBitLen < maxLength - 1);
+        } while (overflow > 0);
+
+        /* We may have overshot above.  Move some nodes from maxLength to
+        * maxLength-1 in that case.
+        */
+        bl_counts[maxLength - 1] += overflow;
+        bl_counts[maxLength - 2] -= overflow;
+
+        /* Now recompute all bit lengths, scanning in increasing
+        * frequency.  It is simpler to reconstruct all lengths instead of
+        * fixing only the wrong ones. This idea is taken from 'ar'
+        * written by Haruhiko Okumura.
+        *
+        * The nodes were inserted with decreasing frequency into the childs
+        * array.
+        */
+        int nodePtr = 2 * numLeafs;
+        for (int bits = maxLength; bits != 0; bits--)
+        {
+          int n = bl_counts[bits - 1];
+          while (n > 0)
+          {
+            int childPtr = 2 * childs[nodePtr++];
+            if (childs[childPtr + 1] == -1)
+            {
+              /* We found another leaf */
+              length[childs[childPtr]] = (byte)bits;
+              n--;
+            }
+          }
+        }
+        //				if (DeflaterConstants.DEBUGGING) {
+        //					//Console.WriteLine("*** After overflow elimination. ***");
+        //					for (int i=0; i < numLeafs; i++) {
+        //						//Console.WriteLine("Node "+childs[2*i]+" freq: "+freqs[childs[2*i]]
+        //						                  + " len: "+length[childs[2*i]]);
+        //					}
+        //				}
+      }
+
+      /// <summary>
+      /// Not documented
+      /// </summary>
+      public void BuildTree()
+      {
+        int numSymbols = freqs.Length;
+
+        /* heap is a priority queue, sorted by frequency, least frequent
+        * nodes first.  The heap is a binary tree, with the property, that
+        * the parent node is smaller than both child nodes.  This assures
+        * that the smallest node is the first parent.
+        *
+        * The binary tree is encoded in an array:  0 is root node and
+        * the nodes 2*n+1, 2*n+2 are the child nodes of node n.
+        */
+        int[] heap = new int[numSymbols];
+        int heapLen = 0;
+        int maxCode = 0;
+        for (int n = 0; n < numSymbols; n++)
+        {
+          int freq = freqs[n];
+          if (freq != 0)
+          {
+            /* Insert n into heap */
+            int pos = heapLen++;
+            int ppos;
+            while (pos > 0 && freqs[heap[ppos = (pos - 1) / 2]] > freq)
+            {
+              heap[pos] = heap[ppos];
+              pos = ppos;
+            }
+            heap[pos] = n;
+
+            maxCode = n;
+          }
+        }
+
+        /* We could encode a single literal with 0 bits but then we
+        * don't see the literals.  Therefore we force at least two
+        * literals to avoid this case.  We don't care about order in
+        * this case, both literals get a 1 bit code.
+        */
+        while (heapLen < 2)
+        {
+          int node = maxCode < 2 ? ++maxCode : 0;
+          heap[heapLen++] = node;
+        }
+
+        numCodes = Math.Max(maxCode + 1, minNumCodes);
+
+        int numLeafs = heapLen;
+        int[] childs = new int[4 * heapLen - 2];
+        int[] values = new int[2 * heapLen - 1];
+        int numNodes = numLeafs;
+        for (int i = 0; i < heapLen; i++)
+        {
+          int node = heap[i];
+          childs[2 * i] = node;
+          childs[2 * i + 1] = -1;
+          values[i] = freqs[node] << 8;
+          heap[i] = i;
+        }
+
+        /* Construct the Huffman tree by repeatedly combining the least two
+        * frequent nodes.
+        */
+        do
+        {
+          int first = heap[0];
+          int last = heap[--heapLen];
+
+          /* Propagate the hole to the leafs of the heap */
+          int ppos = 0;
+          int path = 1;
+
+          while (path < heapLen)
+          {
+            if (path + 1 < heapLen && values[heap[path]] > values[heap[path + 1]])
+            {
+              path++;
+            }
+
+            heap[ppos] = heap[path];
+            ppos = path;
+            path = path * 2 + 1;
+          }
+
+          /* Now propagate the last element down along path.  Normally
+          * it shouldn't go too deep.
+          */
+          int lastVal = values[last];
+          while ((path = ppos) > 0 && values[heap[ppos = (path - 1) / 2]] > lastVal)
+          {
+            heap[path] = heap[ppos];
+          }
+          heap[path] = last;
+
+
+          int second = heap[0];
+
+          /* Create a new node father of first and second */
+          last = numNodes++;
+          childs[2 * last] = first;
+          childs[2 * last + 1] = second;
+          int mindepth = Math.Min(values[first] & 0xff, values[second] & 0xff);
+          values[last] = lastVal = values[first] + values[second] - mindepth + 1;
+
+          /* Again, propagate the hole to the leafs */
+          ppos = 0;
+          path = 1;
+
+          while (path < heapLen)
+          {
+            if (path + 1 < heapLen && values[heap[path]] > values[heap[path + 1]])
+            {
+              path++;
+            }
+
+            heap[ppos] = heap[path];
+            ppos = path;
+            path = ppos * 2 + 1;
+          }
+
+          /* Now propagate the new element down along path */
+          while ((path = ppos) > 0 && values[heap[ppos = (path - 1) / 2]] > lastVal)
+          {
+            heap[path] = heap[ppos];
+          }
+          heap[path] = last;
+        } while (heapLen > 1);
+
+        if (heap[0] != childs.Length / 2 - 1)
+        {
+          throw new SharpZipBaseException("Heap invariant violated");
+        }
+
+        BuildLength(childs);
+      }
+
+      /// <summary>
+      /// Get encoded length
+      /// </summary>
+      /// <returns>Encoded length, the sum of frequencies * lengths</returns>
+      public int GetEncodedLength()
+      {
+        int len = 0;
+        for (int i = 0; i < freqs.Length; i++)
+        {
+          len += freqs[i] * length[i];
+        }
+        return len;
+      }
+
+      /// <summary>
+      /// Not documented
+      /// </summary>
+      public void CalcBLFreq(Tree blTree)
+      {
+        int max_count;               /* max repeat count */
+        int min_count;               /* min repeat count */
+        int count;                   /* repeat count of the current code */
+        int curlen = -1;             /* length of current code */
+
+        int i = 0;
+        while (i < numCodes)
+        {
+          count = 1;
+          int nextlen = length[i];
+          if (nextlen == 0)
+          {
+            max_count = 138;
+            min_count = 3;
+          }
+          else
+          {
+            max_count = 6;
+            min_count = 3;
+            if (curlen != nextlen)
+            {
+              blTree.freqs[nextlen]++;
+              count = 0;
+            }
+          }
+          curlen = nextlen;
+          i++;
+
+          while (i < numCodes && curlen == length[i])
+          {
+            i++;
+            if (++count >= max_count)
+            {
+              break;
+            }
+          }
+
+          if (count < min_count)
+          {
+            blTree.freqs[curlen] += (short)count;
+          }
+          else if (curlen != 0)
+          {
+            blTree.freqs[REP_3_6]++;
+          }
+          else if (count <= 10)
+          {
+            blTree.freqs[REP_3_10]++;
+          }
+          else
+          {
+            blTree.freqs[REP_11_138]++;
+          }
+        }
+      }
+
+      /// <summary>
+      /// Write tree values
+      /// </summary>
+      /// <param name="blTree">Tree to write</param>
+      public void WriteTree(Tree blTree)
+      {
+        int max_count;               /* max repeat count */
+        int min_count;               /* min repeat count */
+        int count;                   /* repeat count of the current code */
+        int curlen = -1;             /* length of current code */
+
+        int i = 0;
+        while (i < numCodes)
+        {
+          count = 1;
+          int nextlen = length[i];
+          if (nextlen == 0)
+          {
+            max_count = 138;
+            min_count = 3;
+          }
+          else
+          {
+            max_count = 6;
+            min_count = 3;
+            if (curlen != nextlen)
+            {
+              blTree.WriteSymbol(nextlen);
+              count = 0;
+            }
+          }
+          curlen = nextlen;
+          i++;
+
+          while (i < numCodes && curlen == length[i])
+          {
+            i++;
+            if (++count >= max_count)
+            {
+              break;
+            }
+          }
+
+          if (count < min_count)
+          {
+            while (count-- > 0)
+            {
+              blTree.WriteSymbol(curlen);
+            }
+          }
+          else if (curlen != 0)
+          {
+            blTree.WriteSymbol(REP_3_6);
+            dh.pending.WriteBits(count - 3, 2);
+          }
+          else if (count <= 10)
+          {
+            blTree.WriteSymbol(REP_3_10);
+            dh.pending.WriteBits(count - 3, 3);
+          }
+          else
+          {
+            blTree.WriteSymbol(REP_11_138);
+            dh.pending.WriteBits(count - 11, 7);
+          }
+        }
+      }
+    }
+
+    /// <summary>
+    /// Pending buffer to use
+    /// </summary>
+    public DeflaterPending pending;
+
+    Tree literalTree, distTree, blTree;
+
+    short[] d_buf;
+    byte[] l_buf;
+    int last_lit;
+    int extra_bits;
+
+    static short[] staticLCodes;
+    static byte[] staticLLength;
+    static short[] staticDCodes;
+    static byte[] staticDLength;
+
+    /// <summary>
+    /// Reverse the bits of a 16 bit value.
+    /// </summary>
+    /// <param name="toReverse">Value to reverse bits</param>
+    /// <returns>Value with bits reversed</returns>
+    public static short BitReverse(int toReverse)
+    {
+      return (short)(bit4Reverse[toReverse & 0xF] << 12 |
+                      bit4Reverse[(toReverse >> 4) & 0xF] << 8 |
+                      bit4Reverse[(toReverse >> 8) & 0xF] << 4 |
+                      bit4Reverse[toReverse >> 12]);
+    }
+
+
+    static DeflaterHuffman()
+    {
+      /* See RFC 1951 3.2.6 */
+      /* Literal codes */
+      staticLCodes = new short[LITERAL_NUM];
+      staticLLength = new byte[LITERAL_NUM];
+      int i = 0;
+      while (i < 144)
+      {
+        staticLCodes[i] = BitReverse((0x030 + i) << 8);
+        staticLLength[i++] = 8;
+      }
+      while (i < 256)
+      {
+        staticLCodes[i] = BitReverse((0x190 - 144 + i) << 7);
+        staticLLength[i++] = 9;
+      }
+      while (i < 280)
+      {
+        staticLCodes[i] = BitReverse((0x000 - 256 + i) << 9);
+        staticLLength[i++] = 7;
+      }
+      while (i < LITERAL_NUM)
+      {
+        staticLCodes[i] = BitReverse((0x0c0 - 280 + i) << 8);
+        staticLLength[i++] = 8;
+      }
+
+      /* Distant codes */
+      staticDCodes = new short[DIST_NUM];
+      staticDLength = new byte[DIST_NUM];
+      for (i = 0; i < DIST_NUM; i++)
+      {
+        staticDCodes[i] = BitReverse(i << 11);
+        staticDLength[i] = 5;
+      }
+    }
+
+    /// <summary>
+    /// Construct instance with pending buffer
+    /// </summary>
+    /// <param name="pending">Pending buffer to use</param>
+    public DeflaterHuffman(DeflaterPending pending)
+    {
+      this.pending = pending;
+
+      literalTree = new Tree(this, LITERAL_NUM, 257, 15);
+      distTree = new Tree(this, DIST_NUM, 1, 15);
+      blTree = new Tree(this, BITLEN_NUM, 4, 7);
+
+      d_buf = new short[BUFSIZE];
+      l_buf = new byte[BUFSIZE];
+    }
+
+    /// <summary>
+    /// Reset internal state
+    /// </summary>		
+    public void Reset()
+    {
+      last_lit = 0;
+      extra_bits = 0;
+      literalTree.Reset();
+      distTree.Reset();
+      blTree.Reset();
+    }
+
+    int Lcode(int len)
+    {
+      if (len == 255)
+      {
+        return 285;
+      }
+
+      int code = 257;
+      while (len >= 8)
+      {
+        code += 4;
+        len >>= 1;
+      }
+      return code + len;
+    }
+
+    int Dcode(int distance)
+    {
+      int code = 0;
+      while (distance >= 4)
+      {
+        code += 2;
+        distance >>= 1;
+      }
+      return code + distance;
+    }
+
+    /// <summary>
+    /// Write all trees to pending buffer
+    /// </summary>		
+    public void SendAllTrees(int blTreeCodes)
+    {
+      blTree.BuildCodes();
+      literalTree.BuildCodes();
+      distTree.BuildCodes();
+      pending.WriteBits(literalTree.numCodes - 257, 5);
+      pending.WriteBits(distTree.numCodes - 1, 5);
+      pending.WriteBits(blTreeCodes - 4, 4);
+      for (int rank = 0; rank < blTreeCodes; rank++)
+      {
+        pending.WriteBits(blTree.length[BL_ORDER[rank]], 3);
+      }
+      literalTree.WriteTree(blTree);
+      distTree.WriteTree(blTree);
+      //			if (DeflaterConstants.DEBUGGING) {
+      //				blTree.CheckEmpty();
+      //			}
+    }
+
+    /// <summary>
+    /// Compress current buffer writing data to pending buffer
+    /// </summary>
+    public void CompressBlock()
+    {
+      for (int i = 0; i < last_lit; i++)
+      {
+        int litlen = l_buf[i] & 0xff;
+        int dist = d_buf[i];
+        if (dist-- != 0)
+        {
+          //					if (DeflaterConstants.DEBUGGING) {
+          //						Console.Write("["+(dist+1)+","+(litlen+3)+"]: ");
+          //					}
+
+          int lc = Lcode(litlen);
+          literalTree.WriteSymbol(lc);
+
+          int bits = (lc - 261) / 4;
+          if (bits > 0 && bits <= 5)
+          {
+            pending.WriteBits(litlen & ((1 << bits) - 1), bits);
+          }
+
+          int dc = Dcode(dist);
+          distTree.WriteSymbol(dc);
+
+          bits = dc / 2 - 1;
+          if (bits > 0)
+          {
+            pending.WriteBits(dist & ((1 << bits) - 1), bits);
+          }
+        }
+        else
+        {
+          //					if (DeflaterConstants.DEBUGGING) {
+          //						if (litlen > 32 && litlen < 127) {
+          //							Console.Write("("+(char)litlen+"): ");
+          //						} else {
+          //							Console.Write("{"+litlen+"}: ");
+          //						}
+          //					}
+          literalTree.WriteSymbol(litlen);
+        }
+      }
+      //			if (DeflaterConstants.DEBUGGING) {
+      //				Console.Write("EOF: ");
+      //			}
+      literalTree.WriteSymbol(EOF_SYMBOL);
+      //			if (DeflaterConstants.DEBUGGING) {
+      //				literalTree.CheckEmpty();
+      //				distTree.CheckEmpty();
+      //			}
+    }
+
+    /// <summary>
+    /// Flush block to output with no compression
+    /// </summary>
+    /// <param name="stored">Data to write</param>
+    /// <param name="storedOffset">Index of first byte to write</param>
+    /// <param name="storedLength">Count of bytes to write</param>
+    /// <param name="lastBlock">True if this is the last block</param>
+    public void FlushStoredBlock(byte[] stored, int storedOffset, int storedLength, bool lastBlock)
+    {
+      //			if (DeflaterConstants.DEBUGGING) {
+      //				//Console.WriteLine("Flushing stored block "+ storedLength);
+      //			}
+      pending.WriteBits((DeflaterConstants.STORED_BLOCK << 1) + (lastBlock ? 1 : 0), 3);
+      pending.AlignToByte();
+      pending.WriteShort(storedLength);
+      pending.WriteShort(~storedLength);
+      pending.WriteBlock(stored, storedOffset, storedLength);
+      Reset();
+    }
+
+    /// <summary>
+    /// Flush block to output with compression
+    /// </summary>		
+    /// <param name="stored">Data to flush</param>
+    /// <param name="storedOffset">Index of first byte to flush</param>
+    /// <param name="storedLength">Count of bytes to flush</param>
+    /// <param name="lastBlock">True if this is the last block</param>
+    public void FlushBlock(byte[] stored, int storedOffset, int storedLength, bool lastBlock)
+    {
+      literalTree.freqs[EOF_SYMBOL]++;
+
+      /* Build trees */
+      literalTree.BuildTree();
+      distTree.BuildTree();
+
+      /* Calculate bitlen frequency */
+      literalTree.CalcBLFreq(blTree);
+      distTree.CalcBLFreq(blTree);
+
+      /* Build bitlen tree */
+      blTree.BuildTree();
+
+      int blTreeCodes = 4;
+      for (int i = 18; i > blTreeCodes; i--)
+      {
+        if (blTree.length[BL_ORDER[i]] > 0)
+        {
+          blTreeCodes = i + 1;
+        }
+      }
+      int opt_len = 14 + blTreeCodes * 3 + blTree.GetEncodedLength() +
+        literalTree.GetEncodedLength() + distTree.GetEncodedLength() +
+        extra_bits;
+
+      int static_len = extra_bits;
+      for (int i = 0; i < LITERAL_NUM; i++)
+      {
+        static_len += literalTree.freqs[i] * staticLLength[i];
+      }
+      for (int i = 0; i < DIST_NUM; i++)
+      {
+        static_len += distTree.freqs[i] * staticDLength[i];
+      }
+      if (opt_len >= static_len)
+      {
+        /* Force static trees */
+        opt_len = static_len;
+      }
+
+      if (storedOffset >= 0 && storedLength + 4 < opt_len >> 3)
+      {
+        /* Store Block */
+        //				if (DeflaterConstants.DEBUGGING) {
+        //					//Console.WriteLine("Storing, since " + storedLength + " < " + opt_len
+        //					                  + " <= " + static_len);
+        //				}
+        FlushStoredBlock(stored, storedOffset, storedLength, lastBlock);
+      }
+      else if (opt_len == static_len)
+      {
+        /* Encode with static tree */
+        pending.WriteBits((DeflaterConstants.STATIC_TREES << 1) + (lastBlock ? 1 : 0), 3);
+        literalTree.SetStaticCodes(staticLCodes, staticLLength);
+        distTree.SetStaticCodes(staticDCodes, staticDLength);
+        CompressBlock();
+        Reset();
+      }
+      else
+      {
+        /* Encode with dynamic tree */
+        pending.WriteBits((DeflaterConstants.DYN_TREES << 1) + (lastBlock ? 1 : 0), 3);
+        SendAllTrees(blTreeCodes);
+        CompressBlock();
+        Reset();
+      }
+    }
+
+    /// <summary>
+    /// Get value indicating if internal buffer is full
+    /// </summary>
+    /// <returns>true if buffer is full</returns>
+    public bool IsFull()
+    {
+      return last_lit >= BUFSIZE;
+    }
+
+    /// <summary>
+    /// Add literal to buffer
+    /// </summary>
+    /// <param name="lit"></param>
+    /// <returns>Value indicating internal buffer is full</returns>
+    public bool TallyLit(int lit)
+    {
+      //			if (DeflaterConstants.DEBUGGING) {
+      //				if (lit > 32 && lit < 127) {
+      //					//Console.WriteLine("("+(char)lit+")");
+      //				} else {
+      //					//Console.WriteLine("{"+lit+"}");
+      //				}
+      //			}
+      d_buf[last_lit] = 0;
+      l_buf[last_lit++] = (byte)lit;
+      literalTree.freqs[lit]++;
+      return IsFull();
+    }
+
+    /// <summary>
+    /// Add distance code and length to literal and distance trees
+    /// </summary>
+    /// <param name="dist">Distance code</param>
+    /// <param name="len">Length</param>
+    /// <returns>Value indicating if internal buffer is full</returns>
+    public bool TallyDist(int dist, int len)
+    {
+      //			if (DeflaterConstants.DEBUGGING) {
+      //				//Console.WriteLine("["+dist+","+len+"]");
+      //			}
+
+      d_buf[last_lit] = (short)dist;
+      l_buf[last_lit++] = (byte)(len - 3);
+
+      int lc = Lcode(len - 3);
+      literalTree.freqs[lc]++;
+      if (lc >= 265 && lc < 285)
+      {
+        extra_bits += (lc - 261) / 4;
+      }
+
+      int dc = Dcode(dist - 1);
+      distTree.freqs[dc]++;
+      if (dc >= 4)
+      {
+        extra_bits += dc / 2 - 1;
+      }
+      return IsFull();
+    }
+  }
 }
diff --git a/lib/PdfSharp/PdfSharp.SharpZipLib/Zip/Compression/DeflaterPending.cs b/lib/PdfSharp/PdfSharp.SharpZipLib/Zip/Compression/DeflaterPending.cs
index 6f2e4eb..6b9c2f7 100644
--- a/lib/PdfSharp/PdfSharp.SharpZipLib/Zip/Compression/DeflaterPending.cs
+++ b/lib/PdfSharp/PdfSharp.SharpZipLib/Zip/Compression/DeflaterPending.cs
@@ -37,21 +37,22 @@
 // obligated to do so.  If you do not wish to do so, delete this
 // exception statement from your version.
 
-namespace PdfSharp.SharpZipLib.Zip.Compression 
+namespace PdfSharp.SharpZipLib.Zip.Compression
 {
-	
-	/// <summary>
-	/// This class stores the pending output of the Deflater.
-	/// 
-	/// author of the original java version : Jochen Hoenicke
-	/// </summary>
-	internal class DeflaterPending : PendingBuffer
-	{
-		/// <summary>
-		/// Construct instance with default buffer size
-		/// </summary>
-		public DeflaterPending() : base(DeflaterConstants.PENDING_BUF_SIZE)
-		{
-		}
-	}
+
+  /// <summary>
+  /// This class stores the pending output of the Deflater.
+  /// 
+  /// Author of the original java version: Jochen Hoenicke
+  /// </summary>
+  internal class DeflaterPending : PendingBuffer
+  {
+    /// <summary>
+    /// Construct instance with default buffer size
+    /// </summary>
+    public DeflaterPending()
+      : base(DeflaterConstants.PENDING_BUF_SIZE)
+    {
+    }
+  }
 }
diff --git a/lib/PdfSharp/PdfSharp.SharpZipLib/Zip/Compression/Inflater.cs b/lib/PdfSharp/PdfSharp.SharpZipLib/Zip/Compression/Inflater.cs
index c2b2343..3b71506 100644
--- a/lib/PdfSharp/PdfSharp.SharpZipLib/Zip/Compression/Inflater.cs
+++ b/lib/PdfSharp/PdfSharp.SharpZipLib/Zip/Compression/Inflater.cs
@@ -42,745 +42,809 @@ using System;
 using PdfSharp.SharpZipLib.Checksums;
 using PdfSharp.SharpZipLib.Zip.Compression.Streams;
 
-namespace PdfSharp.SharpZipLib.Zip.Compression 
+namespace PdfSharp.SharpZipLib.Zip.Compression
 {
-	
-	/// <summary>
-	/// Inflater is used to decompress data that has been compressed according
-	/// to the "deflate" standard described in rfc1951.
-	/// 
-	/// By default Zlib (rfc1950) headers and footers are expected in the input.
-	/// You can use constructor <code> public Inflater(bool noHeader)</code> passing true
-	/// if there is no Zlib header information
-	///
-	/// The usage is as following.  First you have to set some input with
-	/// <code>setInput()</code>, then inflate() it.  If inflate doesn't
-	/// inflate any bytes there may be three reasons:
-	/// <ul>
-	/// <li>needsInput() returns true because the input buffer is empty.
-	/// You have to provide more input with <code>setInput()</code>.
-	/// NOTE: needsInput() also returns true when, the stream is finished.
-	/// </li>
-	/// <li>needsDictionary() returns true, you have to provide a preset
-	///    dictionary with <code>setDictionary()</code>.</li>
-	/// <li>finished() returns true, the inflater has finished.</li>
-	/// </ul>
-	/// Once the first output byte is produced, a dictionary will not be
-	/// needed at a later stage.
-	///
-	/// author of the original java version : John Leuner, Jochen Hoenicke
-	/// </summary>
-	internal class Inflater
-	{
-		/// <summary>
-		/// Copy lengths for literal codes 257..285
-		/// </summary>
-		static int[] CPLENS = {
-								 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
-								 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258
-							  };
-		
-		/// <summary>
-		/// Extra bits for literal codes 257..285
-		/// </summary>
-		static int[] CPLEXT = {
+
+  /// <summary>
+  /// Inflater is used to decompress data that has been compressed according
+  /// to the "deflate" standard described in rfc1951.
+  /// 
+  /// By default Zlib (rfc1950) headers and footers are expected in the input.
+  /// You can use constructor <code> public Inflater(bool noHeader)</code> passing true
+  /// if there is no Zlib header information
+  ///
+  /// The usage is as following.  First you have to set some input with
+  /// <code>setInput()</code>, then inflate() it.  If inflate doesn't
+  /// inflate any bytes there may be three reasons:
+  /// <ul>
+  /// <li>needsInput() returns true because the input buffer is empty.
+  /// You have to provide more input with <code>setInput()</code>.
+  /// NOTE: needsInput() also returns true when, the stream is finished.
+  /// </li>
+  /// <li>needsDictionary() returns true, you have to provide a preset
+  ///    dictionary with <code>setDictionary()</code>.</li>
+  /// <li>finished() returns true, the inflater has finished.</li>
+  /// </ul>
+  /// Once the first output byte is produced, a dictionary will not be
+  /// needed at a later stage.
+  ///
+  /// Authors of the original java version: John Leuner, Jochen Hoenicke
+  /// </summary>
+  internal class Inflater
+  {
+    /// <summary>
+    /// Copy lengths for literal codes 257..285
+    /// </summary>
+    static int[] CPLENS = {
+				         3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
+				         35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258
+			          };
+
+    /// <summary>
+    /// Extra bits for literal codes 257..285
+    /// </summary>
+    static int[] CPLEXT = {
 								 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
 								 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0
 							  };
-		
-		/// <summary>
-		/// Copy offsets for distance codes 0..29
-		/// </summary>
-		static int[] CPDIST = {
+
+    /// <summary>
+    /// Copy offsets for distance codes 0..29
+    /// </summary>
+    static int[] CPDIST = {
 								1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
 								257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
 								8193, 12289, 16385, 24577
 							  };
-		
-		/// <summary>
-		/// Extra bits for distance codes
-		/// </summary>
-		static int[] CPDEXT = {
+
+    /// <summary>
+    /// Extra bits for distance codes
+    /// </summary>
+    static int[] CPDEXT = {
 								0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
 								7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
 								12, 12, 13, 13
 							  };
-		
-		/// <summary>
-		/// These are the possible states for an inflater
-		/// </summary>
-		const int DECODE_HEADER           = 0;
-		const int DECODE_DICT             = 1;
-		const int DECODE_BLOCKS           = 2;
-		const int DECODE_STORED_LEN1      = 3;
-		const int DECODE_STORED_LEN2      = 4;
-		const int DECODE_STORED           = 5;
-		const int DECODE_DYN_HEADER       = 6;
-		const int DECODE_HUFFMAN          = 7;
-		const int DECODE_HUFFMAN_LENBITS  = 8;
-		const int DECODE_HUFFMAN_DIST     = 9;
-		const int DECODE_HUFFMAN_DISTBITS = 10;
-		const int DECODE_CHKSUM           = 11;
-		const int FINISHED                = 12;
-		
-		/// <summary>
-		/// This variable contains the current state.
-		/// </summary>
-		int mode;
-		
-		/// <summary>
-		/// The adler checksum of the dictionary or of the decompressed
-		/// stream, as it is written in the header resp. footer of the
-		/// compressed stream. 
-		/// Only valid if mode is DECODE_DICT or DECODE_CHKSUM.
-		/// </summary>
-		int readAdler;
-		
-		/// <summary>
-		/// The number of bits needed to complete the current state.  This
-		/// is valid, if mode is DECODE_DICT, DECODE_CHKSUM,
-		/// DECODE_HUFFMAN_LENBITS or DECODE_HUFFMAN_DISTBITS.
-		/// </summary>
-		int neededBits;
-		int repLength;
-		int repDist;
-		int uncomprLen;
-		
-		/// <summary>
-		/// True, if the last block flag was set in the last block of the
-		/// inflated stream.  This means that the stream ends after the
-		/// current block.
-		/// </summary>
-		bool isLastBlock;
-		
-		/// <summary>
-		/// The total number of inflated bytes.
-		/// </summary>
-		int totalOut;
-		
-		/// <summary>
-		/// The total number of bytes set with setInput().  This is not the
-		/// value returned by the TotalIn property, since this also includes the
-		/// unprocessed input.
-		/// </summary>
-		int totalIn;
-		
-		/// <summary>
-		/// This variable stores the noHeader flag that was given to the constructor.
-		/// True means, that the inflated stream doesn't contain a Zlib header or 
-		/// footer.
-		/// </summary>
-		bool noHeader;
-		
-		StreamManipulator input;
-		OutputWindow outputWindow;
-		InflaterDynHeader dynHeader;
-		InflaterHuffmanTree litlenTree, distTree;
-		Adler32 adler;
-		
-		/// <summary>
-		/// Creates a new inflater or RFC1951 decompressor
-		/// RFC1950/Zlib headers and footers will be expected in the input data
-		/// </summary>
-		public Inflater() : this(false)
-		{
-		}
-		
-		/// <summary>
-		/// Creates a new inflater.
-		/// </summary>
-		/// <param name="noHeader">
-		/// True if no RFC1950/Zlib header and footer fields are expected in the input data
-		/// 
-		/// This is used for GZIPed/Zipped input.
-		/// 
-		/// For compatibility with
-		/// Sun JDK you should provide one byte of input more than needed in
-		/// this case.
-		/// </param>
-		public Inflater(bool noHeader)
-		{
-			this.noHeader = noHeader;
-			this.adler = new Adler32();
-			input = new StreamManipulator();
-			outputWindow = new OutputWindow();
-			mode = noHeader ? DECODE_BLOCKS : DECODE_HEADER;
-		}
-		
-		/// <summary>
-		/// Resets the inflater so that a new stream can be decompressed.  All
-		/// pending input and output will be discarded.
-		/// </summary>
-		public void Reset()
-		{
-			mode = noHeader ? DECODE_BLOCKS : DECODE_HEADER;
-			totalIn = totalOut = 0;
-			input.Reset();
-			outputWindow.Reset();
-			dynHeader = null;
-			litlenTree = null;
-			distTree = null;
-			isLastBlock = false;
-			adler.Reset();
-		}
-		
-		/// <summary>
-		/// Decodes a zlib/RFC1950 header.
-		/// </summary>
-		/// <returns>
-		/// False if more input is needed.
-		/// </returns>
-		/// <exception cref="SharpZipBaseException">
-		/// The header is invalid.
-		/// </exception>
-		private bool DecodeHeader()
-		{
-			int header = input.PeekBits(16);
-			if (header < 0) {
-				return false;
-			}
-			input.DropBits(16);
-			
-			/* The header is written in "wrong" byte order */
-			header = ((header << 8) | (header >> 8)) & 0xffff;
-			if (header % 31 != 0) {
-				throw new SharpZipBaseException("Header checksum illegal");
-			}
-			
-			if ((header & 0x0f00) != (Deflater.DEFLATED << 8)) {
-				throw new SharpZipBaseException("Compression Method unknown");
-			}
-			
-			/* Maximum size of the backwards window in bits.
-			* We currently ignore this, but we could use it to make the
-			* inflater window more space efficient. On the other hand the
-			* full window (15 bits) is needed most times, anyway.
-			int max_wbits = ((header & 0x7000) >> 12) + 8;
-			*/
-			
-			if ((header & 0x0020) == 0) { // Dictionary flag?
-				mode = DECODE_BLOCKS;
-			} else {
-				mode = DECODE_DICT;
-				neededBits = 32;
-			}
-			return true;
-		}
-		
-		/// <summary>
-		/// Decodes the dictionary checksum after the deflate header.
-		/// </summary>
-		/// <returns>
-		/// False if more input is needed.
-		/// </returns>
-		private bool DecodeDict()
-		{
-			while (neededBits > 0) {
-				int dictByte = input.PeekBits(8);
-				if (dictByte < 0) {
-					return false;
-				}
-				input.DropBits(8);
-				readAdler = (readAdler << 8) | dictByte;
-				neededBits -= 8;
-			}
-			return false;
-		}
-		
-		/// <summary>
-		/// Decodes the huffman encoded symbols in the input stream.
-		/// </summary>
-		/// <returns>
-		/// false if more input is needed, true if output window is
-		/// full or the current block ends.
-		/// </returns>
-		/// <exception cref="SharpZipBaseException">
-		/// if deflated stream is invalid.
-		/// </exception>
-		private bool DecodeHuffman()
-		{
-			int free = outputWindow.GetFreeSpace();
-			while (free >= 258) {
-				int symbol;
-				switch (mode) {
-					case DECODE_HUFFMAN:
-						/* This is the inner loop so it is optimized a bit */
-						while (((symbol = litlenTree.GetSymbol(input)) & ~0xff) == 0) {
-							outputWindow.Write(symbol);
-							if (--free < 258) {
-								return true;
-							}
-						}
-						
-						if (symbol < 257) {
-							if (symbol < 0) {
-								return false;
-							} else {
-								/* symbol == 256: end of block */
-								distTree = null;
-								litlenTree = null;
-								mode = DECODE_BLOCKS;
-								return true;
-							}
-						}
-						
-						try {
-							repLength = CPLENS[symbol - 257];
-							neededBits = CPLEXT[symbol - 257];
-						} catch (Exception) {
-							throw new SharpZipBaseException("Illegal rep length code");
-						}
-						goto case DECODE_HUFFMAN_LENBITS; /* fall through */
-						
-					case DECODE_HUFFMAN_LENBITS:
-						if (neededBits > 0) {
-							mode = DECODE_HUFFMAN_LENBITS;
-							int i = input.PeekBits(neededBits);
-							if (i < 0) {
-								return false;
-							}
-							input.DropBits(neededBits);
-							repLength += i;
-						}
-						mode = DECODE_HUFFMAN_DIST;
-						goto case DECODE_HUFFMAN_DIST;/* fall through */
-						
-					case DECODE_HUFFMAN_DIST:
-						symbol = distTree.GetSymbol(input);
-						if (symbol < 0) {
-							return false;
-						}
-						
-						try {
-							repDist = CPDIST[symbol];
-							neededBits = CPDEXT[symbol];
-						} catch (Exception) {
-							throw new SharpZipBaseException("Illegal rep dist code");
-						}
-						
-						goto case DECODE_HUFFMAN_DISTBITS;/* fall through */
-						
-					case DECODE_HUFFMAN_DISTBITS:
-						if (neededBits > 0) {
-							mode = DECODE_HUFFMAN_DISTBITS;
-							int i = input.PeekBits(neededBits);
-							if (i < 0) {
-								return false;
-							}
-							input.DropBits(neededBits);
-							repDist += i;
-						}
-						
-						outputWindow.Repeat(repLength, repDist);
-						free -= repLength;
-						mode = DECODE_HUFFMAN;
-						break;
-					
-					default:
-						throw new SharpZipBaseException("Inflater unknown mode");
-				}
-			}
-			return true;
-		}
-		
-		/// <summary>
-		/// Decodes the adler checksum after the deflate stream.
-		/// </summary>
-		/// <returns>
-		/// false if more input is needed.
-		/// </returns>
-		/// <exception cref="SharpZipBaseException">
-		/// If checksum doesn't match.
-		/// </exception>
-		private bool DecodeChksum()
-		{
-			while (neededBits > 0) {
-				int chkByte = input.PeekBits(8);
-				if (chkByte < 0) {
-					return false;
-				}
-				input.DropBits(8);
-				readAdler = (readAdler << 8) | chkByte;
-				neededBits -= 8;
-			}
 
-			if ((int) adler.Value != readAdler) {
-				throw new SharpZipBaseException("Adler chksum doesn't match: " + (int)adler.Value + " vs. " + readAdler);
-			}
-			mode = FINISHED;
-			return false;
-		}
-		
-		/// <summary>
-		/// Decodes the deflated stream.
-		/// </summary>
-		/// <returns>
-		/// false if more input is needed, or if finished.
-		/// </returns>
-		/// <exception cref="SharpZipBaseException">
-		/// if deflated stream is invalid.
-		/// </exception>
-		private bool Decode()
-		{
-			switch (mode) {
-				case DECODE_HEADER:
-					return DecodeHeader();
-				case DECODE_DICT:
-					return DecodeDict();
-				case DECODE_CHKSUM:
-					return DecodeChksum();
-				
-				case DECODE_BLOCKS:
-					if (isLastBlock) {
-						if (noHeader) {
-							mode = FINISHED;
-							return false;
-						} else {
-							input.SkipToByteBoundary();
-							neededBits = 32;
-							mode = DECODE_CHKSUM;
-							return true;
-						}
-					}
-					
-					int type = input.PeekBits(3);
-					if (type < 0) {
-						return false;
-					}
-					input.DropBits(3);
-					
-					if ((type & 1) != 0) {
-						isLastBlock = true;
-					}
-					switch (type >> 1){
-						case DeflaterConstants.STORED_BLOCK:
-							input.SkipToByteBoundary();
-							mode = DECODE_STORED_LEN1;
-							break;
-						case DeflaterConstants.STATIC_TREES:
-							litlenTree = InflaterHuffmanTree.defLitLenTree;
-							distTree = InflaterHuffmanTree.defDistTree;
-							mode = DECODE_HUFFMAN;
-							break;
-						case DeflaterConstants.DYN_TREES:
-							dynHeader = new InflaterDynHeader();
-							mode = DECODE_DYN_HEADER;
-							break;
-						default:
-							throw new SharpZipBaseException("Unknown block type " + type);
-					}
-					return true;
-				
-				case DECODE_STORED_LEN1: 
-				{
-					if ((uncomprLen = input.PeekBits(16)) < 0) {
-						return false;
-					}
-					input.DropBits(16);
-					mode = DECODE_STORED_LEN2;
-				}
-					goto case DECODE_STORED_LEN2; /* fall through */
-					
-				case DECODE_STORED_LEN2: 
-				{
-					int nlen = input.PeekBits(16);
-					if (nlen < 0) {
-						return false;
-					}
-					input.DropBits(16);
-					if (nlen != (uncomprLen ^ 0xffff)) {
-						throw new SharpZipBaseException("broken uncompressed block");
-					}
-					mode = DECODE_STORED;
-				}
-					goto case DECODE_STORED;/* fall through */
-					
-				case DECODE_STORED: 
-				{
-					int more = outputWindow.CopyStored(input, uncomprLen);
-					uncomprLen -= more;
-					if (uncomprLen == 0) {
-						mode = DECODE_BLOCKS;
-						return true;
-					}
-					return !input.IsNeedingInput;
-				}
-				
-				case DECODE_DYN_HEADER:
-					if (!dynHeader.Decode(input)) {
-						return false;
-					}
-					
-					litlenTree = dynHeader.BuildLitLenTree();
-					distTree = dynHeader.BuildDistTree();
-					mode = DECODE_HUFFMAN;
-					goto case DECODE_HUFFMAN; /* fall through */
-					
-				case DECODE_HUFFMAN:
-				case DECODE_HUFFMAN_LENBITS:
-				case DECODE_HUFFMAN_DIST:
-				case DECODE_HUFFMAN_DISTBITS:
-					return DecodeHuffman();
-				
-				case FINISHED:
-					return false;
-				
-				default:
-					throw new SharpZipBaseException("Inflater.Decode unknown mode");
-			}
-		}
-			
-		/// <summary>
-		/// Sets the preset dictionary.  This should only be called, if
-		/// needsDictionary() returns true and it should set the same
-		/// dictionary, that was used for deflating.  The getAdler()
-		/// function returns the checksum of the dictionary needed.
-		/// </summary>
-		/// <param name="buffer">
-		/// The dictionary.
-		/// </param>
-		public void SetDictionary(byte[] buffer)
-		{
-			SetDictionary(buffer, 0, buffer.Length);
-		}
-		
-		/// <summary>
-		/// Sets the preset dictionary.  This should only be called, if
-		/// needsDictionary() returns true and it should set the same
-		/// dictionary, that was used for deflating.  The getAdler()
-		/// function returns the checksum of the dictionary needed.
-		/// </summary>
-		/// <param name="buffer">
-		/// The dictionary.
-		/// </param>
-		/// <param name="offset">
-		/// The offset into buffer where the dictionary starts.
-		/// </param>
-		/// <param name="len">
-		/// The length of the dictionary.
-		/// </param>
-		/// <exception cref="System.InvalidOperationException">
-		/// No dictionary is needed.
-		/// </exception>
-		/// <exception cref="SharpZipBaseException">
-		/// The adler checksum for the buffer is invalid
-		/// </exception>
-		public void SetDictionary(byte[] buffer, int offset, int len)
-		{
-			if (!IsNeedingDictionary) {
-				throw new InvalidOperationException();
-			}
-			
-			adler.Update(buffer, offset, len);
-			if ((int)adler.Value != readAdler) {
-				throw new SharpZipBaseException("Wrong adler checksum");
-			}
-			adler.Reset();
-			outputWindow.CopyDict(buffer, offset, len);
-			mode = DECODE_BLOCKS;
-		}
-		
-		/// <summary>
-		/// Sets the input.  This should only be called, if needsInput()
-		/// returns true.
-		/// </summary>
-		/// <param name="buf">
-		/// the input.
-		/// </param>
-		public void SetInput(byte[] buf)
-		{
-			SetInput(buf, 0, buf.Length);
-		}
-		
-		/// <summary>
-		/// Sets the input.  This should only be called, if needsInput()
-		/// returns true.
-		/// </summary>
-		/// <param name="buffer">
-		/// The source of input data
-		/// </param>
-		/// <param name="offset">
-		/// The offset into buffer where the input starts.
-		/// </param>
-		/// <param name="length">
-		/// The number of bytes of input to use.
-		/// </param>
-		/// <exception cref="System.InvalidOperationException">
-		/// No input is needed.
-		/// </exception>
-		/// <exception cref="System.ArgumentOutOfRangeException">
-		/// The off and/or len are wrong.
-		/// </exception>
-		public void SetInput(byte[] buffer, int offset, int length)
-		{
-			input.SetInput(buffer, offset, length);
-			totalIn += length;
-		}
-		
-		/// <summary>
-		/// Inflates the compressed stream to the output buffer.  If this
-		/// returns 0, you should check, whether needsDictionary(),
-		/// needsInput() or finished() returns true, to determine why no
-		/// further output is produced.
-		/// </summary>
-		/// <param name = "buf">
-		/// the output buffer.
-		/// </param>
-		/// <returns>
-		/// the number of bytes written to the buffer, 0 if no further
-		/// output can be produced.
-		/// </returns>
-		/// <exception cref="System.ArgumentOutOfRangeException">
-		/// if buf has length 0.
-		/// </exception>
-		/// <exception cref="System.FormatException">
-		/// if deflated stream is invalid.
-		/// </exception>
-		public int Inflate(byte[] buf)
-		{
-			return Inflate(buf, 0, buf.Length);
-		}
-		
-		/// <summary>
-		/// Inflates the compressed stream to the output buffer.  If this
-		/// returns 0, you should check, whether needsDictionary(),
-		/// needsInput() or finished() returns true, to determine why no
-		/// further output is produced.
-		/// </summary>
-		/// <param name = "buf">
-		/// the output buffer.
-		/// </param>
-		/// <param name = "offset">
-		/// the offset into buffer where the output should start.
-		/// </param>
-		/// <param name = "len">
-		/// the maximum length of the output.
-		/// </param>
-		/// <returns>
-		/// the number of bytes written to the buffer, 0 if no further output can be produced.
-		/// </returns>
-		/// <exception cref="System.ArgumentOutOfRangeException">
-		/// if len is &lt;= 0.
-		/// </exception>
-		/// <exception cref="System.ArgumentOutOfRangeException">
-		/// if the offset and/or len are wrong.
-		/// </exception>
-		/// <exception cref="System.FormatException">
-		/// if deflated stream is invalid.
-		/// </exception>
-		public int Inflate(byte[] buf, int offset, int len)
-		{
-			if (len < 0) {
-				throw new ArgumentOutOfRangeException("len < 0");
-			}
-			
-			// Special case: len may be zero
-			if (len == 0) {
-				if (IsFinished == false) {// -jr- 08-Nov-2003 INFLATE_BUG fix..
-					Decode();
-				}
-				return 0;
-			}
-/*
-			// Check for correct buff, off, len triple
-			if (off < 0 || off + len >= buf.Length) {
-				throw new ArgumentException("off/len outside buf bounds");
-			}
-*/
-			int count = 0;
-			int more;
-			do {
-				if (mode != DECODE_CHKSUM) {
-					/* Don't give away any output, if we are waiting for the
-					* checksum in the input stream.
-					*
-					* With this trick we have always:
-					*   needsInput() and not finished()
-					*   implies more output can be produced.
-					*/
-					more = outputWindow.CopyOutput(buf, offset, len);
-					adler.Update(buf, offset, more);
-					offset += more;
-					count += more;
-					totalOut += more;
-					len -= more;
-					if (len == 0) {
-						return count;
-					}
-				}
-			} while (Decode() || (outputWindow.GetAvailable() > 0 && mode != DECODE_CHKSUM));
-			return count;
-		}
-		
-		/// <summary>
-		/// Returns true, if the input buffer is empty.
-		/// You should then call setInput(). 
-		/// NOTE: This method also returns true when the stream is finished.
-		/// </summary>
-		public bool IsNeedingInput {
-			get {
-				return input.IsNeedingInput;
-			}
-		}
-		
-		/// <summary>
-		/// Returns true, if a preset dictionary is needed to inflate the input.
-		/// </summary>
-		public bool IsNeedingDictionary {
-			get {
-				return mode == DECODE_DICT && neededBits == 0;
-			}
-		}
-		
-		/// <summary>
-		/// Returns true, if the inflater has finished.  This means, that no
-		/// input is needed and no output can be produced.
-		/// </summary>
-		public bool IsFinished {
-			get {
-				return mode == FINISHED && outputWindow.GetAvailable() == 0;
-			}
-		}
-		
-		/// <summary>
-		/// Gets the adler checksum.  This is either the checksum of all
-		/// uncompressed bytes returned by inflate(), or if needsDictionary()
-		/// returns true (and thus no output was yet produced) this is the
-		/// adler checksum of the expected dictionary.
-		/// </summary>
-		/// <returns>
-		/// the adler checksum.
-		/// </returns>
-		public int Adler {
-			get {
-				return IsNeedingDictionary ? readAdler : (int) adler.Value;
-			}
-		}
-		
-		/// <summary>
-		/// Gets the total number of output bytes returned by inflate().
-		/// </summary>
-		/// <returns>
-		/// the total number of output bytes.
-		/// </returns>
-		public int TotalOut {
-			get {
-				return totalOut;
-			}
-		}
-		
-		/// <summary>
-		/// Gets the total number of processed compressed input bytes.
-		/// </summary>
-		/// <returns>
-		/// The total number of bytes of processed input bytes.
-		/// </returns>
-		public int TotalIn {
-			get {
-				return totalIn - RemainingInput;
-			}
-		}
-		
+    /// <summary>
+    /// These are the possible states for an inflater
+    /// </summary>
+    const int DECODE_HEADER = 0;
+    const int DECODE_DICT = 1;
+    const int DECODE_BLOCKS = 2;
+    const int DECODE_STORED_LEN1 = 3;
+    const int DECODE_STORED_LEN2 = 4;
+    const int DECODE_STORED = 5;
+    const int DECODE_DYN_HEADER = 6;
+    const int DECODE_HUFFMAN = 7;
+    const int DECODE_HUFFMAN_LENBITS = 8;
+    const int DECODE_HUFFMAN_DIST = 9;
+    const int DECODE_HUFFMAN_DISTBITS = 10;
+    const int DECODE_CHKSUM = 11;
+    const int FINISHED = 12;
+
+    /// <summary>
+    /// This variable contains the current state.
+    /// </summary>
+    int mode;
+
+    /// <summary>
+    /// The adler checksum of the dictionary or of the decompressed
+    /// stream, as it is written in the header resp. footer of the
+    /// compressed stream. 
+    /// Only valid if mode is DECODE_DICT or DECODE_CHKSUM.
+    /// </summary>
+    int readAdler;
+
+    /// <summary>
+    /// The number of bits needed to complete the current state.  This
+    /// is valid, if mode is DECODE_DICT, DECODE_CHKSUM,
+    /// DECODE_HUFFMAN_LENBITS or DECODE_HUFFMAN_DISTBITS.
+    /// </summary>
+    int neededBits;
+    int repLength;
+    int repDist;
+    int uncomprLen;
+
+    /// <summary>
+    /// True, if the last block flag was set in the last block of the
+    /// inflated stream.  This means that the stream ends after the
+    /// current block.
+    /// </summary>
+    bool isLastBlock;
+
+    /// <summary>
+    /// The total number of inflated bytes.
+    /// </summary>
+    int totalOut;
+
+    /// <summary>
+    /// The total number of bytes set with setInput().  This is not the
+    /// value returned by the TotalIn property, since this also includes the
+    /// unprocessed input.
+    /// </summary>
+    int totalIn;
+
+    /// <summary>
+    /// This variable stores the noHeader flag that was given to the constructor.
+    /// True means, that the inflated stream doesn't contain a Zlib header or 
+    /// footer.
+    /// </summary>
+    bool noHeader;
+
+    StreamManipulator input;
+    OutputWindow outputWindow;
+    InflaterDynHeader dynHeader;
+    InflaterHuffmanTree litlenTree, distTree;
+    Adler32 adler;
+
+    /// <summary>
+    /// Creates a new inflater or RFC1951 decompressor
+    /// RFC1950/Zlib headers and footers will be expected in the input data
+    /// </summary>
+    public Inflater()
+      : this(false)
+    {
+    }
+
+    /// <summary>
+    /// Creates a new inflater.
+    /// </summary>
+    /// <param name="noHeader">
+    /// True if no RFC1950/Zlib header and footer fields are expected in the input data
+    /// 
+    /// This is used for GZIPed/Zipped input.
+    /// 
+    /// For compatibility with
+    /// Sun JDK you should provide one byte of input more than needed in
+    /// this case.
+    /// </param>
+    public Inflater(bool noHeader)
+    {
+      this.noHeader = noHeader;
+      this.adler = new Adler32();
+      input = new StreamManipulator();
+      outputWindow = new OutputWindow();
+      mode = noHeader ? DECODE_BLOCKS : DECODE_HEADER;
+    }
+
+    /// <summary>
+    /// Resets the inflater so that a new stream can be decompressed.  All
+    /// pending input and output will be discarded.
+    /// </summary>
+    public void Reset()
+    {
+      mode = noHeader ? DECODE_BLOCKS : DECODE_HEADER;
+      totalIn = totalOut = 0;
+      input.Reset();
+      outputWindow.Reset();
+      dynHeader = null;
+      litlenTree = null;
+      distTree = null;
+      isLastBlock = false;
+      adler.Reset();
+    }
+
+    /// <summary>
+    /// Decodes a zlib/RFC1950 header.
+    /// </summary>
+    /// <returns>
+    /// False if more input is needed.
+    /// </returns>
+    /// <exception cref="SharpZipBaseException">
+    /// The header is invalid.
+    /// </exception>
+    private bool DecodeHeader()
+    {
+      int header = input.PeekBits(16);
+      if (header < 0)
+      {
+        return false;
+      }
+      input.DropBits(16);
+
+      /* The header is written in "wrong" byte order */
+      header = ((header << 8) | (header >> 8)) & 0xffff;
+      if (header % 31 != 0)
+      {
+        throw new SharpZipBaseException("Header checksum illegal");
+      }
+
+      if ((header & 0x0f00) != (Deflater.DEFLATED << 8))
+      {
+        throw new SharpZipBaseException("Compression Method unknown");
+      }
+
+      /* Maximum size of the backwards window in bits.
+      * We currently ignore this, but we could use it to make the
+      * inflater window more space efficient. On the other hand the
+      * full window (15 bits) is needed most times, anyway.
+      int max_wbits = ((header & 0x7000) >> 12) + 8;
+      */
+
+      if ((header & 0x0020) == 0)
+      { // Dictionary flag?
+        mode = DECODE_BLOCKS;
+      }
+      else
+      {
+        mode = DECODE_DICT;
+        neededBits = 32;
+      }
+      return true;
+    }
+
+    /// <summary>
+    /// Decodes the dictionary checksum after the deflate header.
+    /// </summary>
+    /// <returns>
+    /// False if more input is needed.
+    /// </returns>
+    private bool DecodeDict()
+    {
+      while (neededBits > 0)
+      {
+        int dictByte = input.PeekBits(8);
+        if (dictByte < 0)
+        {
+          return false;
+        }
+        input.DropBits(8);
+        readAdler = (readAdler << 8) | dictByte;
+        neededBits -= 8;
+      }
+      return false;
+    }
+
+    /// <summary>
+    /// Decodes the huffman encoded symbols in the input stream.
+    /// </summary>
+    /// <returns>
+    /// false if more input is needed, true if output window is
+    /// full or the current block ends.
+    /// </returns>
+    /// <exception cref="SharpZipBaseException">
+    /// if deflated stream is invalid.
+    /// </exception>
+    private bool DecodeHuffman()
+    {
+      int free = outputWindow.GetFreeSpace();
+      while (free >= 258)
+      {
+        int symbol;
+        switch (mode)
+        {
+          case DECODE_HUFFMAN:
+            /* This is the inner loop so it is optimized a bit */
+            while (((symbol = litlenTree.GetSymbol(input)) & ~0xff) == 0)
+            {
+              outputWindow.Write(symbol);
+              if (--free < 258)
+              {
+                return true;
+              }
+            }
+
+            if (symbol < 257)
+            {
+              if (symbol < 0)
+              {
+                return false;
+              }
+              else
+              {
+                /* symbol == 256: end of block */
+                distTree = null;
+                litlenTree = null;
+                mode = DECODE_BLOCKS;
+                return true;
+              }
+            }
+
+            try
+            {
+              repLength = CPLENS[symbol - 257];
+              neededBits = CPLEXT[symbol - 257];
+            }
+            catch (Exception)
+            {
+              throw new SharpZipBaseException("Illegal rep length code");
+            }
+            goto case DECODE_HUFFMAN_LENBITS; /* fall through */
+
+          case DECODE_HUFFMAN_LENBITS:
+            if (neededBits > 0)
+            {
+              mode = DECODE_HUFFMAN_LENBITS;
+              int i = input.PeekBits(neededBits);
+              if (i < 0)
+              {
+                return false;
+              }
+              input.DropBits(neededBits);
+              repLength += i;
+            }
+            mode = DECODE_HUFFMAN_DIST;
+            goto case DECODE_HUFFMAN_DIST;/* fall through */
+
+          case DECODE_HUFFMAN_DIST:
+            symbol = distTree.GetSymbol(input);
+            if (symbol < 0)
+            {
+              return false;
+            }
+
+            try
+            {
+              repDist = CPDIST[symbol];
+              neededBits = CPDEXT[symbol];
+            }
+            catch (Exception)
+            {
+              throw new SharpZipBaseException("Illegal rep dist code");
+            }
+
+            goto case DECODE_HUFFMAN_DISTBITS;/* fall through */
+
+          case DECODE_HUFFMAN_DISTBITS:
+            if (neededBits > 0)
+            {
+              mode = DECODE_HUFFMAN_DISTBITS;
+              int i = input.PeekBits(neededBits);
+              if (i < 0)
+              {
+                return false;
+              }
+              input.DropBits(neededBits);
+              repDist += i;
+            }
+
+            outputWindow.Repeat(repLength, repDist);
+            free -= repLength;
+            mode = DECODE_HUFFMAN;
+            break;
+
+          default:
+            throw new SharpZipBaseException("Inflater unknown mode");
+        }
+      }
+      return true;
+    }
+
+    /// <summary>
+    /// Decodes the adler checksum after the deflate stream.
+    /// </summary>
+    /// <returns>
+    /// false if more input is needed.
+    /// </returns>
+    /// <exception cref="SharpZipBaseException">
+    /// If checksum doesn't match.
+    /// </exception>
+    private bool DecodeChksum()
+    {
+      while (neededBits > 0)
+      {
+        int chkByte = input.PeekBits(8);
+        if (chkByte < 0)
+        {
+          return false;
+        }
+        input.DropBits(8);
+        readAdler = (readAdler << 8) | chkByte;
+        neededBits -= 8;
+      }
+
+      if ((int)adler.Value != readAdler)
+      {
+        throw new SharpZipBaseException("Adler chksum doesn't match: " + (int)adler.Value + " vs. " + readAdler);
+      }
+      mode = FINISHED;
+      return false;
+    }
+
+    /// <summary>
+    /// Decodes the deflated stream.
+    /// </summary>
+    /// <returns>
+    /// false if more input is needed, or if finished.
+    /// </returns>
+    /// <exception cref="SharpZipBaseException">
+    /// if deflated stream is invalid.
+    /// </exception>
+    private bool Decode()
+    {
+      switch (mode)
+      {
+        case DECODE_HEADER:
+          return DecodeHeader();
+        case DECODE_DICT:
+          return DecodeDict();
+        case DECODE_CHKSUM:
+          return DecodeChksum();
+
+        case DECODE_BLOCKS:
+          if (isLastBlock)
+          {
+            if (noHeader)
+            {
+              mode = FINISHED;
+              return false;
+            }
+            else
+            {
+              input.SkipToByteBoundary();
+              neededBits = 32;
+              mode = DECODE_CHKSUM;
+              return true;
+            }
+          }
+
+          int type = input.PeekBits(3);
+          if (type < 0)
+          {
+            return false;
+          }
+          input.DropBits(3);
+
+          if ((type & 1) != 0)
+          {
+            isLastBlock = true;
+          }
+          switch (type >> 1)
+          {
+            case DeflaterConstants.STORED_BLOCK:
+              input.SkipToByteBoundary();
+              mode = DECODE_STORED_LEN1;
+              break;
+            case DeflaterConstants.STATIC_TREES:
+              litlenTree = InflaterHuffmanTree.defLitLenTree;
+              distTree = InflaterHuffmanTree.defDistTree;
+              mode = DECODE_HUFFMAN;
+              break;
+            case DeflaterConstants.DYN_TREES:
+              dynHeader = new InflaterDynHeader();
+              mode = DECODE_DYN_HEADER;
+              break;
+            default:
+              throw new SharpZipBaseException("Unknown block type " + type);
+          }
+          return true;
+
+        case DECODE_STORED_LEN1:
+          {
+            if ((uncomprLen = input.PeekBits(16)) < 0)
+            {
+              return false;
+            }
+            input.DropBits(16);
+            mode = DECODE_STORED_LEN2;
+          }
+          goto case DECODE_STORED_LEN2; /* fall through */
+
+        case DECODE_STORED_LEN2:
+          {
+            int nlen = input.PeekBits(16);
+            if (nlen < 0)
+            {
+              return false;
+            }
+            input.DropBits(16);
+            if (nlen != (uncomprLen ^ 0xffff))
+            {
+              throw new SharpZipBaseException("broken uncompressed block");
+            }
+            mode = DECODE_STORED;
+          }
+          goto case DECODE_STORED;/* fall through */
+
+        case DECODE_STORED:
+          {
+            int more = outputWindow.CopyStored(input, uncomprLen);
+            uncomprLen -= more;
+            if (uncomprLen == 0)
+            {
+              mode = DECODE_BLOCKS;
+              return true;
+            }
+            return !input.IsNeedingInput;
+          }
+
+        case DECODE_DYN_HEADER:
+          if (!dynHeader.Decode(input))
+          {
+            return false;
+          }
+
+          litlenTree = dynHeader.BuildLitLenTree();
+          distTree = dynHeader.BuildDistTree();
+          mode = DECODE_HUFFMAN;
+          goto case DECODE_HUFFMAN; /* fall through */
+
+        case DECODE_HUFFMAN:
+        case DECODE_HUFFMAN_LENBITS:
+        case DECODE_HUFFMAN_DIST:
+        case DECODE_HUFFMAN_DISTBITS:
+          return DecodeHuffman();
+
+        case FINISHED:
+          return false;
+
+        default:
+          throw new SharpZipBaseException("Inflater.Decode unknown mode");
+      }
+    }
+
+    /// <summary>
+    /// Sets the preset dictionary.  This should only be called, if
+    /// needsDictionary() returns true and it should set the same
+    /// dictionary, that was used for deflating.  The getAdler()
+    /// function returns the checksum of the dictionary needed.
+    /// </summary>
+    /// <param name="buffer">
+    /// The dictionary.
+    /// </param>
+    public void SetDictionary(byte[] buffer)
+    {
+      SetDictionary(buffer, 0, buffer.Length);
+    }
+
+    /// <summary>
+    /// Sets the preset dictionary.  This should only be called, if
+    /// needsDictionary() returns true and it should set the same
+    /// dictionary, that was used for deflating.  The getAdler()
+    /// function returns the checksum of the dictionary needed.
+    /// </summary>
+    /// <param name="buffer">
+    /// The dictionary.
+    /// </param>
+    /// <param name="offset">
+    /// The offset into buffer where the dictionary starts.
+    /// </param>
+    /// <param name="len">
+    /// The length of the dictionary.
+    /// </param>
+    /// <exception cref="System.InvalidOperationException">
+    /// No dictionary is needed.
+    /// </exception>
+    /// <exception cref="SharpZipBaseException">
+    /// The adler checksum for the buffer is invalid
+    /// </exception>
+    public void SetDictionary(byte[] buffer, int offset, int len)
+    {
+      if (!IsNeedingDictionary)
+      {
+        throw new InvalidOperationException();
+      }
+
+      adler.Update(buffer, offset, len);
+      if ((int)adler.Value != readAdler)
+      {
+        throw new SharpZipBaseException("Wrong adler checksum");
+      }
+      adler.Reset();
+      outputWindow.CopyDict(buffer, offset, len);
+      mode = DECODE_BLOCKS;
+    }
+
+    /// <summary>
+    /// Sets the input.  This should only be called, if needsInput()
+    /// returns true.
+    /// </summary>
+    /// <param name="buf">
+    /// the input.
+    /// </param>
+    public void SetInput(byte[] buf)
+    {
+      SetInput(buf, 0, buf.Length);
+    }
+
+    /// <summary>
+    /// Sets the input.  This should only be called, if needsInput()
+    /// returns true.
+    /// </summary>
+    /// <param name="buffer">
+    /// The source of input data
+    /// </param>
+    /// <param name="offset">
+    /// The offset into buffer where the input starts.
+    /// </param>
+    /// <param name="length">
+    /// The number of bytes of input to use.
+    /// </param>
+    /// <exception cref="System.InvalidOperationException">
+    /// No input is needed.
+    /// </exception>
+    /// <exception cref="System.ArgumentOutOfRangeException">
+    /// The off and/or len are wrong.
+    /// </exception>
+    public void SetInput(byte[] buffer, int offset, int length)
+    {
+      input.SetInput(buffer, offset, length);
+      totalIn += length;
+    }
+
+    /// <summary>
+    /// Inflates the compressed stream to the output buffer.  If this
+    /// returns 0, you should check, whether needsDictionary(),
+    /// needsInput() or finished() returns true, to determine why no
+    /// further output is produced.
+    /// </summary>
+    /// <param name = "buf">
+    /// the output buffer.
+    /// </param>
+    /// <returns>
+    /// the number of bytes written to the buffer, 0 if no further
+    /// output can be produced.
+    /// </returns>
+    /// <exception cref="System.ArgumentOutOfRangeException">
+    /// if buf has length 0.
+    /// </exception>
+    /// <exception cref="System.FormatException">
+    /// if deflated stream is invalid.
+    /// </exception>
+    public int Inflate(byte[] buf)
+    {
+      return Inflate(buf, 0, buf.Length);
+    }
+
+    /// <summary>
+    /// Inflates the compressed stream to the output buffer.  If this
+    /// returns 0, you should check, whether needsDictionary(),
+    /// needsInput() or finished() returns true, to determine why no
+    /// further output is produced.
+    /// </summary>
+    /// <param name = "buf">
+    /// the output buffer.
+    /// </param>
+    /// <param name = "offset">
+    /// the offset into buffer where the output should start.
+    /// </param>
+    /// <param name = "len">
+    /// the maximum length of the output.
+    /// </param>
+    /// <returns>
+    /// the number of bytes written to the buffer, 0 if no further output can be produced.
+    /// </returns>
+    /// <exception cref="System.ArgumentOutOfRangeException">
+    /// if len is &lt;= 0.
+    /// </exception>
+    /// <exception cref="System.ArgumentOutOfRangeException">
+    /// if the offset and/or len are wrong.
+    /// </exception>
+    /// <exception cref="System.FormatException">
+    /// if deflated stream is invalid.
+    /// </exception>
+    public int Inflate(byte[] buf, int offset, int len)
+    {
+      if (len < 0)
+      {
+        throw new ArgumentOutOfRangeException("len < 0");
+      }
+
+      // Special case: len may be zero
+      if (len == 0)
+      {
+        if (IsFinished == false)
+        {// -jr- 08-Nov-2003 INFLATE_BUG fix..
+          Decode();
+        }
+        return 0;
+      }
+      /*
+            // Check for correct buff, off, len triple
+            if (off < 0 || off + len >= buf.Length) {
+              throw new ArgumentException("off/len outside buf bounds");
+            }
+      */
+      int count = 0;
+      int more;
+      do
+      {
+        if (mode != DECODE_CHKSUM)
+        {
+          /* Don't give away any output, if we are waiting for the
+          * checksum in the input stream.
+          *
+          * With this trick we have always:
+          *   needsInput() and not finished()
+          *   implies more output can be produced.
+          */
+          more = outputWindow.CopyOutput(buf, offset, len);
+          adler.Update(buf, offset, more);
+          offset += more;
+          count += more;
+          totalOut += more;
+          len -= more;
+          if (len == 0)
+          {
+            return count;
+          }
+        }
+      } while (Decode() || (outputWindow.GetAvailable() > 0 && mode != DECODE_CHKSUM));
+      return count;
+    }
+
+    /// <summary>
+    /// Returns true, if the input buffer is empty.
+    /// You should then call setInput(). 
+    /// NOTE: This method also returns true when the stream is finished.
+    /// </summary>
+    public bool IsNeedingInput
+    {
+      get
+      {
+        return input.IsNeedingInput;
+      }
+    }
+
+    /// <summary>
+    /// Returns true, if a preset dictionary is needed to inflate the input.
+    /// </summary>
+    public bool IsNeedingDictionary
+    {
+      get
+      {
+        return mode == DECODE_DICT && neededBits == 0;
+      }
+    }
+
+    /// <summary>
+    /// Returns true, if the inflater has finished.  This means, that no
+    /// input is needed and no output can be produced.
+    /// </summary>
+    public bool IsFinished
+    {
+      get
+      {
+        return mode == FINISHED && outputWindow.GetAvailable() == 0;
+      }
+    }
+
+    /// <summary>
+    /// Gets the adler checksum.  This is either the checksum of all
+    /// uncompressed bytes returned by inflate(), or if needsDictionary()
+    /// returns true (and thus no output was yet produced) this is the
+    /// adler checksum of the expected dictionary.
+    /// </summary>
+    /// <returns>
+    /// the adler checksum.
+    /// </returns>
+    public int Adler
+    {
+      get
+      {
+        return IsNeedingDictionary ? readAdler : (int)adler.Value;
+      }
+    }
+
+    /// <summary>
+    /// Gets the total number of output bytes returned by inflate().
+    /// </summary>
+    /// <returns>
+    /// the total number of output bytes.
+    /// </returns>
+    public int TotalOut
+    {
+      get
+      {
+        return totalOut;
+      }
+    }
+
+    /// <summary>
+    /// Gets the total number of processed compressed input bytes.
+    /// </summary>
+    /// <returns>
+    /// The total number of bytes of processed input bytes.
+    /// </returns>
+    public int TotalIn
+    {
+      get
+      {
+        return totalIn - RemainingInput;
+      }
+    }
+
 #if TEST_HAK		
 		/// <summary>
 		/// -jr test hak trying to figure out a bug
@@ -800,19 +864,21 @@ namespace PdfSharp.SharpZipLib.Zip.Compression
 			}
 		}
 #endif
-		
-		/// <summary>
-		/// Gets the number of unprocessed input bytes.  Useful, if the end of the
-		/// stream is reached and you want to further process the bytes after
-		/// the deflate stream.
-		/// </summary>
-		/// <returns>
-		/// The number of bytes of the input which have not been processed.
-		/// </returns>
-		public int RemainingInput {
-			get {
-				return input.AvailableBytes;
-			}
-		}
-	}
+
+    /// <summary>
+    /// Gets the number of unprocessed input bytes.  Useful, if the end of the
+    /// stream is reached and you want to further process the bytes after
+    /// the deflate stream.
+    /// </summary>
+    /// <returns>
+    /// The number of bytes of the input which have not been processed.
+    /// </returns>
+    public int RemainingInput
+    {
+      get
+      {
+        return input.AvailableBytes;
+      }
+    }
+  }
 }
diff --git a/lib/PdfSharp/PdfSharp.SharpZipLib/Zip/Compression/InflaterHuffmanTree.cs b/lib/PdfSharp/PdfSharp.SharpZipLib/Zip/Compression/InflaterHuffmanTree.cs
index 0fa60ba..eace070 100644
--- a/lib/PdfSharp/PdfSharp.SharpZipLib/Zip/Compression/InflaterHuffmanTree.cs
+++ b/lib/PdfSharp/PdfSharp.SharpZipLib/Zip/Compression/InflaterHuffmanTree.cs
@@ -125,13 +125,13 @@ namespace PdfSharp.SharpZipLib.Zip.Compression
 					treeSize += (end - start) >> (16 - bits);
 				}
 			}
-			
-/* -jr comment this out! doesnt work for dynamic trees and pkzip 2.04g
-			if (code != 65536) 
-			{
-				throw new SharpZipBaseException("Code lengths don't add up properly.");
-			}
-*/
+
+      /* -jr comment this out! doesn't work for dynamic trees and pkzip 2.04g
+            if (code != 65536) 
+            {
+              throw new SharpZipBaseException("Code lengths don't add up properly.");
+            }
+      */
 			/* Now create and fill the extra tables from longest to shortest
 			* bit len.  This way the sub trees will be aligned.
 			*/
diff --git a/lib/PdfSharp/PdfSharp.SharpZipLib/Zip/Compression/PendingBuffer.cs b/lib/PdfSharp/PdfSharp.SharpZipLib/Zip/Compression/PendingBuffer.cs
index 0080825..76a294d 100644
--- a/lib/PdfSharp/PdfSharp.SharpZipLib/Zip/Compression/PendingBuffer.cs
+++ b/lib/PdfSharp/PdfSharp.SharpZipLib/Zip/Compression/PendingBuffer.cs
@@ -39,236 +39,255 @@
 
 using System;
 
-namespace PdfSharp.SharpZipLib.Zip.Compression 
+namespace PdfSharp.SharpZipLib.Zip.Compression
 {
-	
-	/// <summary>
-	/// This class is general purpose class for writing data to a buffer.
-	/// 
-	/// It allows you to write bits as well as bytes
-	/// Based on DeflaterPending.java
-	/// 
-	/// author of the original java version : Jochen Hoenicke
-	/// </summary>
-	internal class PendingBuffer
-	{
-		/// <summary>Internal work buffer
-		/// </summary>
-		protected byte[] buf;
-		
-		int    start;
-		int    end;
-		
-		uint    bits;
-		int    bitCount;
 
-		/// <summary>
-		/// construct instance using default buffer size of 4096
-		/// </summary>
-		public PendingBuffer() : this( 4096 )
-		{
-			
-		}
-		
-		/// <summary>
-		/// construct instance using specified buffer size
-		/// </summary>
-		/// <param name="bufsize">
-		/// size to use for internal buffer
-		/// </param>
-		public PendingBuffer(int bufsize)
-		{
-			buf = new byte[bufsize];
-		}
+  /// <summary>
+  /// This class is general purpose class for writing data to a buffer.
+  /// 
+  /// It allows you to write bits as well as bytes
+  /// Based on DeflaterPending.java
+  /// 
+  /// Author of the original java version: Jochen Hoenicke
+  /// </summary>
+  internal class PendingBuffer
+  {
+    /// <summary>Internal work buffer
+    /// </summary>
+    protected byte[] buf;
 
-		/// <summary>
-		/// Clear internal state/buffers
-		/// </summary>
-		public void Reset() 
-		{
-			start = end = bitCount = 0;
-		}
+    int start;
+    int end;
 
-		/// <summary>
-		/// write a byte to buffer
-		/// </summary>
-		/// <param name="b">
-		/// value to write
-		/// </param>
-		public void WriteByte(int b)
-		{
-			if (DeflaterConstants.DEBUGGING && start != 0) {
-				throw new SharpZipBaseException();
-			}
-			buf[end++] = (byte) b;
-		}
+    uint bits;
+    int bitCount;
 
-		/// <summary>
-		/// Write a short value to buffer LSB first
-		/// </summary>
-		/// <param name="s">
-		/// value to write
-		/// </param>
-		public void WriteShort(int s)
-		{
-			if (DeflaterConstants.DEBUGGING && start != 0) {
-				throw new SharpZipBaseException();
-			}
-			buf[end++] = (byte) s;
-			buf[end++] = (byte) (s >> 8);
-		}
+    /// <summary>
+    /// construct instance using default buffer size of 4096
+    /// </summary>
+    public PendingBuffer()
+      : this(4096)
+    {
 
-		/// <summary>
-		/// write an integer LSB first
-		/// </summary>
-		/// <param name="s">value to write</param>
-		public void WriteInt(int s)
-		{
-			if (DeflaterConstants.DEBUGGING && start != 0) {
-				throw new SharpZipBaseException();
-			}
-			buf[end++] = (byte) s;
-			buf[end++] = (byte) (s >> 8);
-			buf[end++] = (byte) (s >> 16);
-			buf[end++] = (byte) (s >> 24);
-		}
-		
-		/// <summary>
-		/// Write a block of data to buffer
-		/// </summary>
-		/// <param name="block">data to write</param>
-		/// <param name="offset">offset of first byte to write</param>
-		/// <param name="len">number of bytes to write</param>
-		public void WriteBlock(byte[] block, int offset, int len)
-		{
-			if (DeflaterConstants.DEBUGGING && start != 0) {
-				throw new SharpZipBaseException();
-			}
-			System.Array.Copy(block, offset, buf, end, len);
-			end += len;
-		}
+    }
 
-		/// <summary>
-		/// The number of bits written to the buffer
-		/// </summary>
-		public int BitCount {
-			get {
-				return bitCount;
-			}
-		}
-		
-		/// <summary>
-		/// Align internal buffer on a byte boundary
-		/// </summary>
-		public void AlignToByte() 
-		{
-			if (DeflaterConstants.DEBUGGING && start != 0) {
-				throw new SharpZipBaseException();
-			}
-			if (bitCount > 0) {
-				buf[end++] = (byte) bits;
-				if (bitCount > 8) {
-					buf[end++] = (byte) (bits >> 8);
-				}
-			}
-			bits = 0;
-			bitCount = 0;
-		}
+    /// <summary>
+    /// construct instance using specified buffer size
+    /// </summary>
+    /// <param name="bufsize">
+    /// size to use for internal buffer
+    /// </param>
+    public PendingBuffer(int bufsize)
+    {
+      buf = new byte[bufsize];
+    }
 
-		/// <summary>
-		/// Write bits to internal buffer
-		/// </summary>
-		/// <param name="b">source of bits</param>
-		/// <param name="count">number of bits to write</param>
-		public void WriteBits(int b, int count)
-		{
-			if (DeflaterConstants.DEBUGGING && start != 0) {
-				throw new SharpZipBaseException();
-			}
-			//			if (DeflaterConstants.DEBUGGING) {
-			//				//Console.WriteLine("writeBits("+b+","+count+")");
-			//			}
-			bits |= (uint)(b << bitCount);
-			bitCount += count;
-			if (bitCount >= 16) {
-				buf[end++] = (byte) bits;
-				buf[end++] = (byte) (bits >> 8);
-				bits >>= 16;
-				bitCount -= 16;
-			}
-		}
+    /// <summary>
+    /// Clear internal state/buffers
+    /// </summary>
+    public void Reset()
+    {
+      start = end = bitCount = 0;
+    }
 
-		/// <summary>
-		/// Write a short value to internal buffer most significant byte first
-		/// </summary>
-		/// <param name="s">value to write</param>
-		public void WriteShortMSB(int s) 
-		{
-			if (DeflaterConstants.DEBUGGING && start != 0) {
-				throw new SharpZipBaseException();
-			}
-			buf[end++] = (byte) (s >> 8);
-			buf[end++] = (byte) s;
-		}
-		
-		/// <summary>
-		/// Indicates if buffer has been flushed
-		/// </summary>
-		public bool IsFlushed {
-			get {
-				return end == 0;
-			}
-		}
-		
-		/// <summary>
-		/// Flushes the pending buffer into the given output array.  If the
-		/// output array is to small, only a partial flush is done.
-		/// </summary>
-		/// <param name="output">
-		/// the output array;
-		/// </param>
-		/// <param name="offset">
-		/// the offset into output array;
-		/// </param>
-		/// <param name="length">		
-		/// length the maximum number of bytes to store;
-		/// </param>
-		/// <exception name="ArgumentOutOfRangeException">
-		/// IndexOutOfBoundsException if offset or length are invalid.
-		/// </exception>
-		public int Flush(byte[] output, int offset, int length) 
-		{
-			if (bitCount >= 8) {
-				buf[end++] = (byte) bits;
-				bits >>= 8;
-				bitCount -= 8;
-			}
-			if (length > end - start) {
-				length = end - start;
-				System.Array.Copy(buf, start, output, offset, length);
-				start = 0;
-				end = 0;
-			} else {
-				System.Array.Copy(buf, start, output, offset, length);
-				start += length;
-			}
-			return length;
-		}
+    /// <summary>
+    /// write a byte to buffer
+    /// </summary>
+    /// <param name="b">
+    /// value to write
+    /// </param>
+    public void WriteByte(int b)
+    {
+      if (DeflaterConstants.DEBUGGING && start != 0)
+      {
+        throw new SharpZipBaseException();
+      }
+      buf[end++] = (byte)b;
+    }
 
-		/// <summary>
-		/// Convert internal buffer to byte array.
-		/// Buffer is empty on completion
-		/// </summary>
-		/// <returns>
-		/// converted buffer contents contents
-		/// </returns>
-		public byte[] ToByteArray()
-		{
-			byte[] ret = new byte[end - start];
-			System.Array.Copy(buf, start, ret, 0, ret.Length);
-			start = 0;
-			end = 0;
-			return ret;
-		}
-	}
-}	
+    /// <summary>
+    /// Write a short value to buffer LSB first
+    /// </summary>
+    /// <param name="s">
+    /// value to write
+    /// </param>
+    public void WriteShort(int s)
+    {
+      if (DeflaterConstants.DEBUGGING && start != 0)
+      {
+        throw new SharpZipBaseException();
+      }
+      buf[end++] = (byte)s;
+      buf[end++] = (byte)(s >> 8);
+    }
+
+    /// <summary>
+    /// write an integer LSB first
+    /// </summary>
+    /// <param name="s">value to write</param>
+    public void WriteInt(int s)
+    {
+      if (DeflaterConstants.DEBUGGING && start != 0)
+      {
+        throw new SharpZipBaseException();
+      }
+      buf[end++] = (byte)s;
+      buf[end++] = (byte)(s >> 8);
+      buf[end++] = (byte)(s >> 16);
+      buf[end++] = (byte)(s >> 24);
+    }
+
+    /// <summary>
+    /// Write a block of data to buffer
+    /// </summary>
+    /// <param name="block">data to write</param>
+    /// <param name="offset">offset of first byte to write</param>
+    /// <param name="len">number of bytes to write</param>
+    public void WriteBlock(byte[] block, int offset, int len)
+    {
+      if (DeflaterConstants.DEBUGGING && start != 0)
+      {
+        throw new SharpZipBaseException();
+      }
+      System.Array.Copy(block, offset, buf, end, len);
+      end += len;
+    }
+
+    /// <summary>
+    /// The number of bits written to the buffer
+    /// </summary>
+    public int BitCount
+    {
+      get
+      {
+        return bitCount;
+      }
+    }
+
+    /// <summary>
+    /// Align internal buffer on a byte boundary
+    /// </summary>
+    public void AlignToByte()
+    {
+      if (DeflaterConstants.DEBUGGING && start != 0)
+      {
+        throw new SharpZipBaseException();
+      }
+      if (bitCount > 0)
+      {
+        buf[end++] = (byte)bits;
+        if (bitCount > 8)
+        {
+          buf[end++] = (byte)(bits >> 8);
+        }
+      }
+      bits = 0;
+      bitCount = 0;
+    }
+
+    /// <summary>
+    /// Write bits to internal buffer
+    /// </summary>
+    /// <param name="b">source of bits</param>
+    /// <param name="count">number of bits to write</param>
+    public void WriteBits(int b, int count)
+    {
+      if (DeflaterConstants.DEBUGGING && start != 0)
+      {
+        throw new SharpZipBaseException();
+      }
+      //			if (DeflaterConstants.DEBUGGING) {
+      //				//Console.WriteLine("writeBits("+b+","+count+")");
+      //			}
+      bits |= (uint)(b << bitCount);
+      bitCount += count;
+      if (bitCount >= 16)
+      {
+        buf[end++] = (byte)bits;
+        buf[end++] = (byte)(bits >> 8);
+        bits >>= 16;
+        bitCount -= 16;
+      }
+    }
+
+    /// <summary>
+    /// Write a short value to internal buffer most significant byte first
+    /// </summary>
+    /// <param name="s">value to write</param>
+    public void WriteShortMSB(int s)
+    {
+      if (DeflaterConstants.DEBUGGING && start != 0)
+      {
+        throw new SharpZipBaseException();
+      }
+      buf[end++] = (byte)(s >> 8);
+      buf[end++] = (byte)s;
+    }
+
+    /// <summary>
+    /// Indicates if buffer has been flushed
+    /// </summary>
+    public bool IsFlushed
+    {
+      get
+      {
+        return end == 0;
+      }
+    }
+
+    /// <summary>
+    /// Flushes the pending buffer into the given output array.  If the
+    /// output array is to small, only a partial flush is done.
+    /// </summary>
+    /// <param name="output">
+    /// the output array;
+    /// </param>
+    /// <param name="offset">
+    /// the offset into output array;
+    /// </param>
+    /// <param name="length">		
+    /// length the maximum number of bytes to store;
+    /// </param>
+    /// <exception name="ArgumentOutOfRangeException">
+    /// IndexOutOfBoundsException if offset or length are invalid.
+    /// </exception>
+    public int Flush(byte[] output, int offset, int length)
+    {
+      if (bitCount >= 8)
+      {
+        buf[end++] = (byte)bits;
+        bits >>= 8;
+        bitCount -= 8;
+      }
+      if (length > end - start)
+      {
+        length = end - start;
+        System.Array.Copy(buf, start, output, offset, length);
+        start = 0;
+        end = 0;
+      }
+      else
+      {
+        System.Array.Copy(buf, start, output, offset, length);
+        start += length;
+      }
+      return length;
+    }
+
+    /// <summary>
+    /// Convert internal buffer to byte array.
+    /// Buffer is empty on completion
+    /// </summary>
+    /// <returns>
+    /// converted buffer contents contents
+    /// </returns>
+    public byte[] ToByteArray()
+    {
+      byte[] ret = new byte[end - start];
+      System.Array.Copy(buf, start, ret, 0, ret.Length);
+      start = 0;
+      end = 0;
+      return ret;
+    }
+  }
+}
diff --git a/lib/PdfSharp/PdfSharp.SharpZipLib/Zip/Compression/Streams/DeflaterOutputStream.cs b/lib/PdfSharp/PdfSharp.SharpZipLib/Zip/Compression/Streams/DeflaterOutputStream.cs
index 0620f9b..acf5d01 100644
--- a/lib/PdfSharp/PdfSharp.SharpZipLib/Zip/Compression/Streams/DeflaterOutputStream.cs
+++ b/lib/PdfSharp/PdfSharp.SharpZipLib/Zip/Compression/Streams/DeflaterOutputStream.cs
@@ -47,7 +47,7 @@ namespace PdfSharp.SharpZipLib.Zip.Compression.Streams
 	/// <summary>
 	/// A special stream deflating or compressing the bytes that are
 	/// written to it.  It uses a Deflater to perform actual deflating.<br/>
-	/// Authors of the original java version : Tom Tromey, Jochen Hoenicke 
+  /// Authors of the original java version: Tom Tromey, Jochen Hoenicke 
 	/// </summary>
 	internal class DeflaterOutputStream : Stream
 	{
@@ -127,7 +127,7 @@ namespace PdfSharp.SharpZipLib.Zip.Compression.Streams
 		
 		/// <summary>
 		/// The current position within the stream.
-		/// Always throws a NotSupportedExceptionNotSupportedException
+		/// Always throws a NotSupportedException
 		/// </summary>
 		/// <exception cref="NotSupportedException">Any attempt to set position</exception>
 		public override long Position {
@@ -183,7 +183,6 @@ namespace PdfSharp.SharpZipLib.Zip.Compression.Streams
 		/// <param name="count"></param>
 		/// <param name="callback"></param>
 		/// <param name="state"></param>
-		/// <returns></returns>
 		/// <exception cref="NotSupportedException">Any access</exception>
 		public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
 		{
@@ -198,7 +197,6 @@ namespace PdfSharp.SharpZipLib.Zip.Compression.Streams
 		/// <param name="count"></param>
 		/// <param name="callback"></param>
 		/// <param name="state"></param>
-		/// <returns></returns>
 		/// <exception cref="NotSupportedException">Any access</exception>
 		public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
 		{
diff --git a/lib/PdfSharp/PdfSharp.SharpZipLib/Zip/Compression/Streams/InflaterInputStream.cs b/lib/PdfSharp/PdfSharp.SharpZipLib/Zip/Compression/Streams/InflaterInputStream.cs
index 585750a..5ead543 100644
--- a/lib/PdfSharp/PdfSharp.SharpZipLib/Zip/Compression/Streams/InflaterInputStream.cs
+++ b/lib/PdfSharp/PdfSharp.SharpZipLib/Zip/Compression/Streams/InflaterInputStream.cs
@@ -43,302 +43,331 @@ using System.IO;
 using PdfSharp.SharpZipLib.Zip.Compression;
 using PdfSharp.SharpZipLib.Checksums;
 
-namespace PdfSharp.SharpZipLib.Zip.Compression.Streams 
+namespace PdfSharp.SharpZipLib.Zip.Compression.Streams
 {
-	
-	/// <summary>
-	/// This filter stream is used to decompress data compressed using the "deflate"
-	/// format. The "deflate" format is described in RFC 1951.
-	///
-	/// Author of the original java version : John Leuner.
-	/// </summary>
-	internal class InflaterInputStream : Stream
-	{
-		/// <summary>
-		/// Decompressor for this stream
-		/// </summary>
-		protected Inflater inf;
-		
-		/// <summary>
-		/// Byte array used for buffering input.
-		/// </summary>
-		protected byte[] buf;
-
-		/// <summary>
-		/// Size of buffer <see cref="buf"></see>
-		/// </summary>
-		protected int len;
-		
-		// Used for reading single bytes the ReadByte() call
-		private byte[] onebytebuffer = new byte[1];
-		
-		/// <summary>
-		/// Base stream the inflater reads from.
-		/// </summary>
-		protected Stream baseInputStream;
-		
+
+  /// <summary>
+  /// This filter stream is used to decompress data compressed using the "deflate"
+  /// format. The "deflate" format is described in RFC 1951.
+  ///
+  /// Author of the original java version: John Leuner.
+  /// </summary>
+  internal class InflaterInputStream : Stream
+  {
+    /// <summary>
+    /// Decompressor for this stream
+    /// </summary>
+    protected Inflater inf;
+
+    /// <summary>
+    /// Byte array used for buffering input.
+    /// </summary>
+    protected byte[] buf;
+
+    /// <summary>
+    /// Size of buffer <see cref="buf"></see>
+    /// </summary>
+    protected int len;
+
+    // Used for reading single bytes the ReadByte() call
+    private byte[] onebytebuffer = new byte[1];
+
+    /// <summary>
+    /// Base stream the inflater reads from.
+    /// </summary>
+    protected Stream baseInputStream;
+
     ////		/// <summary>
     ////		/// The compressed size
     ////		/// </summary>
     ////		protected long csize;
-		
-		bool isStreamOwner = true;
-		
-		/// <summary>
-		/// Get/set flag indicating ownership of underlying stream.
-		/// When the flag is true <see cref="Close"/> will close the underlying stream also.
-		/// </summary>
-		/// <remarks>
-		/// The default value is true.
-		/// </remarks>
-		public bool IsStreamOwner
-		{
-			get { return isStreamOwner; }
-			set { isStreamOwner = value; }
-		}
-		
-		/// <summary>
-		/// Gets a value indicating whether the current stream supports reading
-		/// </summary>
-		public override bool CanRead {
-			get {
-				return baseInputStream.CanRead;
-			}
-		}
-		
-		/// <summary>
-		/// Gets a value of false indicating seeking is not supported for this stream.
-		/// </summary>
-		public override bool CanSeek {
-			get {
-				return false;
-			}
-		}
-		
-		/// <summary>
-		/// Gets a value of false indicating that this stream is not writeable.
-		/// </summary>
-		public override bool CanWrite {
-			get {
-				return false;
-			}
-		}
-		
-		/// <summary>
-		/// A value representing the length of the stream in bytes.
-		/// </summary>
-		public override long Length {
-			get {
-				return len;
-			}
-		}
-		
-		/// <summary>
-		/// The current position within the stream.
-		/// Throws a NotSupportedException when attempting to set the position
-		/// </summary>
-		/// <exception cref="NotSupportedException">Attempting to set the position</exception>
-		public override long Position {
-			get {
-				return baseInputStream.Position;
-			}
-			set {
-				throw new NotSupportedException("InflaterInputStream Position not supported");
-			}
-		}
-		
-		/// <summary>
-		/// Flushes the baseInputStream
-		/// </summary>
-		public override void Flush()
-		{
-			baseInputStream.Flush();
-		}
-		
-		/// <summary>
-		/// Sets the position within the current stream
-		/// Always throws a NotSupportedException
-		/// </summary>
-		/// <exception cref="NotSupportedException">Any access</exception>
-		public override long Seek(long offset, SeekOrigin origin)
-		{
-			throw new NotSupportedException("Seek not supported");
-		}
-		
-		/// <summary>
-		/// Set the length of the current stream
-		/// Always throws a NotSupportedException
-		/// </summary>
-		/// <exception cref="NotSupportedException">Any access</exception>
-		public override void SetLength(long val)
-		{
-			throw new NotSupportedException("InflaterInputStream SetLength not supported");
-		}
-		
-		/// <summary>
-		/// Writes a sequence of bytes to stream and advances the current position
-		/// This method always throws a NotSupportedException
-		/// </summary>
-		/// <exception cref="NotSupportedException">Any access</exception>
-		public override void Write(byte[] array, int offset, int count)
-		{
-			throw new NotSupportedException("InflaterInputStream Write not supported");
-		}
-		
-		/// <summary>
-		/// Writes one byte to the current stream and advances the current position
-		/// Always throws a NotSupportedException
-		/// </summary>
-		/// <exception cref="NotSupportedException">Any access</exception>
-		public override void WriteByte(byte val)
-		{
-			throw new NotSupportedException("InflaterInputStream WriteByte not supported");
-		}
-		
-		/// <summary>
-		/// Entry point to begin an asynchronous write.  Always throws a NotSupportedException.
-		/// </summary>
-		/// <param name="buffer">The buffer to write data from</param>
-		/// <param name="offset">Offset of first byte to write</param>
-		/// <param name="count">The maximum number of bytes to write</param>
-		/// <param name="callback">The method to be called when the asynchronous write operation is completed</param>
-		/// <param name="state">A user-provided object that distinguishes this particular asynchronous write request from other requests</param>
-		/// <returns>An <see cref="System.IAsyncResult">IAsyncResult</see> that references the asynchronous write</returns>
-		/// <exception cref="NotSupportedException">Any access</exception>
-		public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
-		{
-			throw new NotSupportedException("InflaterInputStream BeginWrite not supported");
-		}
-		
-		/// <summary>
-		/// Create an InflaterInputStream with the default decompressor
-		/// and a default buffer size of 4KB.
-		/// </summary>
-		/// <param name = "baseInputStream">
-		/// The InputStream to read bytes from
-		/// </param>
-		public InflaterInputStream(Stream baseInputStream) : this(baseInputStream, new Inflater(), 4096)
-		{
-		}
-		
-		/// <summary>
-		/// Create an InflaterInputStream with the specified decompressor
-		/// and a default buffer size of 4KB.
-		/// </summary>
-		/// <param name = "baseInputStream">
-		/// The source of input data
-		/// </param>
-		/// <param name = "inf">
-		/// The decompressor used to decompress data read from baseInputStream
-		/// </param>
-		public InflaterInputStream(Stream baseInputStream, Inflater inf) : this(baseInputStream, inf, 4096)
-		{
-		}
-		
-		/// <summary>
-		/// Create an InflaterInputStream with the specified decompressor
-		/// and the specified buffer size.
-		/// </summary>
-		/// <param name = "baseInputStream">
-		/// The InputStream to read bytes from
-		/// </param>
-		/// <param name = "inflater">
-		/// The decompressor to use
-		/// </param>
-		/// <param name = "bufferSize">
-		/// Size of the buffer to use
-		/// </param>
-		public InflaterInputStream(Stream baseInputStream, Inflater inflater, int bufferSize)
-		{
-			if (baseInputStream == null) {
-				throw new ArgumentNullException("InflaterInputStream baseInputStream is null");
-			}
-			
-			if (inflater == null) {
-				throw new ArgumentNullException("InflaterInputStream Inflater is null");
-			}
-			
-			if (bufferSize <= 0) {
-				throw new ArgumentOutOfRangeException("bufferSize");
-			}
-			
-			this.baseInputStream = baseInputStream;
-			this.inf = inflater;
-			buf = new byte[bufferSize];
-			
-			if (baseInputStream.CanSeek) {
-				this.len = (int)baseInputStream.Length;
-			} else {
-				this.len = 0;
-			}
-		}
-		
-		/// <summary>
-		/// Returns 0 once the end of the stream (EOF) has been reached.
-		/// Otherwise returns 1.
-		/// </summary>
-		public virtual int Available {
-			get {
-				return inf.IsFinished ? 0 : 1;
-			}
-		}
-		
-		/// <summary>
-		/// Closes the input stream.  When <see cref="IsStreamOwner"></see>
-		/// is true the underlying stream is also closed.
-		/// </summary>
-		public override void Close()
-		{
-			if ( isStreamOwner ) {
-				baseInputStream.Close();
-			}
-		}
-
-		int readChunkSize = 0;
-
-		/// <summary>
-		/// Sets the size of chunks to read from the input stream
-		/// 0 means as larger as possible.
-		/// </summary>
-		/// <remarks>
-		/// Used to handle decryption where the length of stream is unknown.
-		/// </remarks>
-		protected int BufferReadSize {
-			get { 
-				return readChunkSize;
-			}
-			
-			set {
-				readChunkSize = value;
-			}
-		}
-
-		/// <summary>
-		/// Fill input buffer with a chunk of data.
-		/// </summary>		
-		protected void FillInputBuffer()
-		{
-			if (readChunkSize <= 0) {
-				len = baseInputStream.Read(buf, 0, buf.Length);
-			} else {
-				len = baseInputStream.Read(buf, 0, readChunkSize);
-			}
-			
-		}
-		/// <summary>
-		/// Fills the buffer with more data to decompress.
-		/// </summary>
-		/// <exception cref="SharpZipBaseException">
-		/// Stream ends early
-		/// </exception>
-		protected void Fill()
-		{
-			FillInputBuffer();
-			
-			if (keys != null) {
-				DecryptBlock(buf, 0, len);
-			}
-			
+
+    bool isStreamOwner = true;
+
+    /// <summary>
+    /// Get/set flag indicating ownership of underlying stream.
+    /// When the flag is true <see cref="Close"/> will close the underlying stream also.
+    /// </summary>
+    /// <remarks>
+    /// The default value is true.
+    /// </remarks>
+    public bool IsStreamOwner
+    {
+      get { return isStreamOwner; }
+      set { isStreamOwner = value; }
+    }
+
+    /// <summary>
+    /// Gets a value indicating whether the current stream supports reading
+    /// </summary>
+    public override bool CanRead
+    {
+      get
+      {
+        return baseInputStream.CanRead;
+      }
+    }
+
+    /// <summary>
+    /// Gets a value of false indicating seeking is not supported for this stream.
+    /// </summary>
+    public override bool CanSeek
+    {
+      get
+      {
+        return false;
+      }
+    }
+
+    /// <summary>
+    /// Gets a value of false indicating that this stream is not writeable.
+    /// </summary>
+    public override bool CanWrite
+    {
+      get
+      {
+        return false;
+      }
+    }
+
+    /// <summary>
+    /// A value representing the length of the stream in bytes.
+    /// </summary>
+    public override long Length
+    {
+      get
+      {
+        return len;
+      }
+    }
+
+    /// <summary>
+    /// The current position within the stream.
+    /// Throws a NotSupportedException when attempting to set the position
+    /// </summary>
+    /// <exception cref="NotSupportedException">Attempting to set the position</exception>
+    public override long Position
+    {
+      get
+      {
+        return baseInputStream.Position;
+      }
+      set
+      {
+        throw new NotSupportedException("InflaterInputStream Position not supported");
+      }
+    }
+
+    /// <summary>
+    /// Flushes the baseInputStream
+    /// </summary>
+    public override void Flush()
+    {
+      baseInputStream.Flush();
+    }
+
+    /// <summary>
+    /// Sets the position within the current stream
+    /// Always throws a NotSupportedException
+    /// </summary>
+    /// <exception cref="NotSupportedException">Any access</exception>
+    public override long Seek(long offset, SeekOrigin origin)
+    {
+      throw new NotSupportedException("Seek not supported");
+    }
+
+    /// <summary>
+    /// Set the length of the current stream
+    /// Always throws a NotSupportedException
+    /// </summary>
+    /// <exception cref="NotSupportedException">Any access</exception>
+    public override void SetLength(long val)
+    {
+      throw new NotSupportedException("InflaterInputStream SetLength not supported");
+    }
+
+    /// <summary>
+    /// Writes a sequence of bytes to stream and advances the current position
+    /// This method always throws a NotSupportedException
+    /// </summary>
+    /// <exception cref="NotSupportedException">Any access</exception>
+    public override void Write(byte[] array, int offset, int count)
+    {
+      throw new NotSupportedException("InflaterInputStream Write not supported");
+    }
+
+    /// <summary>
+    /// Writes one byte to the current stream and advances the current position
+    /// Always throws a NotSupportedException
+    /// </summary>
+    /// <exception cref="NotSupportedException">Any access</exception>
+    public override void WriteByte(byte val)
+    {
+      throw new NotSupportedException("InflaterInputStream WriteByte not supported");
+    }
+
+    /// <summary>
+    /// Entry point to begin an asynchronous write.  Always throws a NotSupportedException.
+    /// </summary>
+    /// <param name="buffer">The buffer to write data from</param>
+    /// <param name="offset">Offset of first byte to write</param>
+    /// <param name="count">The maximum number of bytes to write</param>
+    /// <param name="callback">The method to be called when the asynchronous write operation is completed</param>
+    /// <param name="state">A user-provided object that distinguishes this particular asynchronous write request from other requests</param>
+    /// <returns>An <see cref="System.IAsyncResult">IAsyncResult</see> that references the asynchronous write</returns>
+    /// <exception cref="NotSupportedException">Any access</exception>
+    public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
+    {
+      throw new NotSupportedException("InflaterInputStream BeginWrite not supported");
+    }
+
+    /// <summary>
+    /// Create an InflaterInputStream with the default decompressor
+    /// and a default buffer size of 4KB.
+    /// </summary>
+    /// <param name = "baseInputStream">
+    /// The InputStream to read bytes from
+    /// </param>
+    public InflaterInputStream(Stream baseInputStream)
+      : this(baseInputStream, new Inflater(), 4096)
+    {
+    }
+
+    /// <summary>
+    /// Create an InflaterInputStream with the specified decompressor
+    /// and a default buffer size of 4KB.
+    /// </summary>
+    /// <param name = "baseInputStream">
+    /// The source of input data
+    /// </param>
+    /// <param name = "inf">
+    /// The decompressor used to decompress data read from baseInputStream
+    /// </param>
+    public InflaterInputStream(Stream baseInputStream, Inflater inf)
+      : this(baseInputStream, inf, 4096)
+    {
+    }
+
+    /// <summary>
+    /// Create an InflaterInputStream with the specified decompressor
+    /// and the specified buffer size.
+    /// </summary>
+    /// <param name = "baseInputStream">
+    /// The InputStream to read bytes from
+    /// </param>
+    /// <param name = "inflater">
+    /// The decompressor to use
+    /// </param>
+    /// <param name = "bufferSize">
+    /// Size of the buffer to use
+    /// </param>
+    public InflaterInputStream(Stream baseInputStream, Inflater inflater, int bufferSize)
+    {
+      if (baseInputStream == null)
+      {
+        throw new ArgumentNullException("InflaterInputStream baseInputStream is null");
+      }
+
+      if (inflater == null)
+      {
+        throw new ArgumentNullException("InflaterInputStream Inflater is null");
+      }
+
+      if (bufferSize <= 0)
+      {
+        throw new ArgumentOutOfRangeException("bufferSize");
+      }
+
+      this.baseInputStream = baseInputStream;
+      this.inf = inflater;
+      buf = new byte[bufferSize];
+
+      if (baseInputStream.CanSeek)
+      {
+        this.len = (int)baseInputStream.Length;
+      }
+      else
+      {
+        this.len = 0;
+      }
+    }
+
+    /// <summary>
+    /// Returns 0 once the end of the stream (EOF) has been reached.
+    /// Otherwise returns 1.
+    /// </summary>
+    public virtual int Available
+    {
+      get
+      {
+        return inf.IsFinished ? 0 : 1;
+      }
+    }
+
+    /// <summary>
+    /// Closes the input stream.  When <see cref="IsStreamOwner"></see>
+    /// is true the underlying stream is also closed.
+    /// </summary>
+    public override void Close()
+    {
+      if (isStreamOwner)
+      {
+        baseInputStream.Close();
+      }
+    }
+
+    int readChunkSize = 0;
+
+    /// <summary>
+    /// Sets the size of chunks to read from the input stream
+    /// 0 means as larger as possible.
+    /// </summary>
+    /// <remarks>
+    /// Used to handle decryption where the length of stream is unknown.
+    /// </remarks>
+    protected int BufferReadSize
+    {
+      get
+      {
+        return readChunkSize;
+      }
+
+      set
+      {
+        readChunkSize = value;
+      }
+    }
+
+    /// <summary>
+    /// Fill input buffer with a chunk of data.
+    /// </summary>		
+    protected void FillInputBuffer()
+    {
+      if (readChunkSize <= 0)
+      {
+        len = baseInputStream.Read(buf, 0, buf.Length);
+      }
+      else
+      {
+        len = baseInputStream.Read(buf, 0, readChunkSize);
+      }
+
+    }
+    /// <summary>
+    /// Fills the buffer with more data to decompress.
+    /// </summary>
+    /// <exception cref="SharpZipBaseException">
+    /// Stream ends early
+    /// </exception>
+    protected void Fill()
+    {
+      FillInputBuffer();
+
+      if (keys != null)
+      {
+        DecryptBlock(buf, 0, len);
+      }
+
 #if READ_SINGLE_WHEN_DECRYPTING
 			// This solves some decryption problems but there are still some lurking.
 			// At issue is exactly where the stream and decryption should finish.
@@ -361,176 +390,197 @@ namespace PdfSharp.SharpZipLib.Zip.Compression.Streams
 			}
 #endif
 
-			if (len <= 0) {
-				throw new SharpZipBaseException("Deflated stream ends early.");
-			}
-			
-			inf.SetInput(buf, 0, len);
-		}
-		
-		/// <summary>
-		/// Reads one byte of decompressed data.
-		///
-		/// The byte is baseInputStream the lower 8 bits of the int.
-		/// </summary>
-		/// <returns>
-		/// The byte read cast to an int, or -1 on end of stream.
-		/// </returns>
-		public override int ReadByte()
-		{
-			int nread = Read(onebytebuffer, 0, 1); // read one byte
-			if (nread > 0) {
-				return onebytebuffer[0] & 0xff;
-			}
-			return -1; // ok
-		}
-		
-		/// <summary>
-		/// Decompresses data into the byte array
-		/// </summary>
-		/// <param name ="b">
-		/// The array to read and decompress data into
-		/// </param>
-		/// <param name ="off">
-		/// The offset indicating where the data should be placed
-		/// </param>
-		/// <param name ="len">
-		/// The number of bytes to decompress
-		/// </param>
-		/// <returns>The number of bytes read.  Zero signals the end of stream</returns>
-		/// <exception cref="SharpZipBaseException">
-		/// Inflater needs a dictionary
-		/// </exception>
-		public override int Read(byte[] b, int off, int len)
-		{
-			for (;;) {
-				int count;
-				try {
-					count = inf.Inflate(b, off, len);
-				} catch (Exception e) {
-					throw new SharpZipBaseException(e.ToString());
-				}
-				
-				if (count > 0) {
-					return count;
-				}
-				
-				if (inf.IsNeedingDictionary) {
-					throw new SharpZipBaseException("Need a dictionary");
-				} else if (inf.IsFinished) {
-					return 0;
-				} else if (inf.IsNeedingInput) {
-					Fill();
-				} else {
-					throw new InvalidOperationException("Don't know what to do");
-				}
-			}
-		}
-		
-		/// <summary>
-		/// Skip specified number of bytes of uncompressed data
-		/// </summary>
-		/// <param name ="n">
-		/// Number of bytes to skip
-		/// </param>
-		/// <returns>
-		/// The number of bytes skipped, zero if the end of 
-		/// stream has been reached
-		/// </returns>
-		/// <exception cref="ArgumentOutOfRangeException">
-		/// Number of bytes to skip is zero or less
-		/// </exception>
-		public long Skip(long n)
-		{
-			if (n <= 0) {
-				throw new ArgumentOutOfRangeException("n");
-			}
-			
-			// v0.80 Skip by seeking if underlying stream supports it...
-			if (baseInputStream.CanSeek) {
-				baseInputStream.Seek(n, SeekOrigin.Current);
-				return n;
-			} else {
-				int len = 2048;
-				if (n < len) {
-					len = (int) n;
-				}
-				byte[] tmp = new byte[len];
-				return (long)baseInputStream.Read(tmp, 0, tmp.Length);
-			}
-		}
-		
-		#region Encryption stuff
-		
-		// TODO  Refactor this code.  The presence of Zip specific code in this low level class is wrong
-		
-		/// <summary>
-		/// A buffer used for decrypting data.  Used to hold Zip crypto header.
-		/// </summary>
-		protected byte[] cryptbuffer = null;
-		
-		uint[] keys = null;
-		
-		/// <summary>
-		/// Decrypt a single byte
-		/// </summary>
-		/// <returns>plain text byte value</returns>
-		protected byte DecryptByte()
-		{
-			uint temp = ((keys[2] & 0xFFFF) | 2);
-			return (byte)((temp * (temp ^ 1)) >> 8);
-		}
-		
-		/// <summary>
-		/// Decrypt cipher text block, updating keys
-		/// </summary>
-		/// <param name="buf">Data to decrypt</param>
-		/// <param name="off">Offset of first byte to process</param>
-		/// <param name="len">Number of bytes to process</param>
-		protected void DecryptBlock(byte[] buf, int off, int len)
-		{
-			for (int i = off; i < off + len; ++i) {
-				buf[i] ^= DecryptByte();
-				UpdateKeys(buf[i]);
-			}
-		}
-		
-		/// <summary>
-		/// Initialise the decryption keys
-		/// </summary>
-		/// <param name="password">The password used to initialise the keys</param>
-		protected void InitializePassword(string password)
-		{
-			keys = new uint[] {
+      if (len <= 0)
+      {
+        throw new SharpZipBaseException("Deflated stream ends early.");
+      }
+
+      inf.SetInput(buf, 0, len);
+    }
+
+    /// <summary>
+    /// Reads one byte of decompressed data.
+    ///
+    /// The byte is baseInputStream the lower 8 bits of the int.
+    /// </summary>
+    /// <returns>
+    /// The byte read cast to an int, or -1 on end of stream.
+    /// </returns>
+    public override int ReadByte()
+    {
+      int nread = Read(onebytebuffer, 0, 1); // read one byte
+      if (nread > 0)
+      {
+        return onebytebuffer[0] & 0xff;
+      }
+      return -1; // ok
+    }
+
+    /// <summary>
+    /// Decompresses data into the byte array
+    /// </summary>
+    /// <param name ="b">
+    /// The array to read and decompress data into
+    /// </param>
+    /// <param name ="off">
+    /// The offset indicating where the data should be placed
+    /// </param>
+    /// <param name ="len">
+    /// The number of bytes to decompress
+    /// </param>
+    /// <returns>The number of bytes read.  Zero signals the end of stream</returns>
+    /// <exception cref="SharpZipBaseException">
+    /// Inflater needs a dictionary
+    /// </exception>
+    public override int Read(byte[] b, int off, int len)
+    {
+      for (; ; )
+      {
+        int count;
+        try
+        {
+          count = inf.Inflate(b, off, len);
+        }
+        catch (Exception e)
+        {
+          throw new SharpZipBaseException(e.ToString());
+        }
+
+        if (count > 0)
+        {
+          return count;
+        }
+
+        if (inf.IsNeedingDictionary)
+        {
+          throw new SharpZipBaseException("Need a dictionary");
+        }
+        else if (inf.IsFinished)
+        {
+          return 0;
+        }
+        else if (inf.IsNeedingInput)
+        {
+          Fill();
+        }
+        else
+        {
+          throw new InvalidOperationException("Don't know what to do");
+        }
+      }
+    }
+
+    /// <summary>
+    /// Skip specified number of bytes of uncompressed data
+    /// </summary>
+    /// <param name ="n">
+    /// Number of bytes to skip
+    /// </param>
+    /// <returns>
+    /// The number of bytes skipped, zero if the end of 
+    /// stream has been reached
+    /// </returns>
+    /// <exception cref="ArgumentOutOfRangeException">
+    /// Number of bytes to skip is zero or less
+    /// </exception>
+    public long Skip(long n)
+    {
+      if (n <= 0)
+      {
+        throw new ArgumentOutOfRangeException("n");
+      }
+
+      // v0.80 Skip by seeking if underlying stream supports it...
+      if (baseInputStream.CanSeek)
+      {
+        baseInputStream.Seek(n, SeekOrigin.Current);
+        return n;
+      }
+      else
+      {
+        int len = 2048;
+        if (n < len)
+        {
+          len = (int)n;
+        }
+        byte[] tmp = new byte[len];
+        return (long)baseInputStream.Read(tmp, 0, tmp.Length);
+      }
+    }
+
+    #region Encryption stuff
+
+    // TODO  Refactor this code.  The presence of Zip specific code in this low level class is wrong
+
+    /// <summary>
+    /// A buffer used for decrypting data.  Used to hold Zip crypto header.
+    /// </summary>
+    protected byte[] cryptbuffer = null;
+
+    uint[] keys = null;
+
+    /// <summary>
+    /// Decrypt a single byte
+    /// </summary>
+    /// <returns>plain text byte value</returns>
+    protected byte DecryptByte()
+    {
+      uint temp = ((keys[2] & 0xFFFF) | 2);
+      return (byte)((temp * (temp ^ 1)) >> 8);
+    }
+
+    /// <summary>
+    /// Decrypt cipher text block, updating keys
+    /// </summary>
+    /// <param name="buf">Data to decrypt</param>
+    /// <param name="off">Offset of first byte to process</param>
+    /// <param name="len">Number of bytes to process</param>
+    protected void DecryptBlock(byte[] buf, int off, int len)
+    {
+      for (int i = off; i < off + len; ++i)
+      {
+        buf[i] ^= DecryptByte();
+        UpdateKeys(buf[i]);
+      }
+    }
+
+    /// <summary>
+    /// Initialise the decryption keys
+    /// </summary>
+    /// <param name="password">The password used to initialise the keys</param>
+    protected void InitializePassword(string password)
+    {
+      keys = new uint[] {
 				0x12345678,
 				0x23456789,
 				0x34567890
 			};
-			for (int i = 0; i < password.Length; ++i) {
-				UpdateKeys((byte)password[i]);
-			}
-		}
-		
-		/// <summary>
-		/// Update the decryption keys
-		/// </summary>
-		/// <param name="ch">Character to update the keys with</param>
-		protected void UpdateKeys(byte ch)
-		{
-			keys[0] = Crc32.ComputeCrc32(keys[0], ch);
-			keys[1] = keys[1] + (byte)keys[0];
-			keys[1] = keys[1] * 134775813 + 1;
-			keys[2] = Crc32.ComputeCrc32(keys[2], (byte)(keys[1] >> 24));
-		}
-
-		/// <summary>
-		/// Clear any cryptographic state.
-		/// </summary>		
-		protected void StopDecrypting()
-		{
-			keys = null;
-			cryptbuffer = null;
-		}
-		#endregion
-	}
+      for (int i = 0; i < password.Length; ++i)
+      {
+        UpdateKeys((byte)password[i]);
+      }
+    }
+
+    /// <summary>
+    /// Update the decryption keys
+    /// </summary>
+    /// <param name="ch">Character to update the keys with</param>
+    protected void UpdateKeys(byte ch)
+    {
+      keys[0] = Crc32.ComputeCrc32(keys[0], ch);
+      keys[1] = keys[1] + (byte)keys[0];
+      keys[1] = keys[1] * 134775813 + 1;
+      keys[2] = Crc32.ComputeCrc32(keys[2], (byte)(keys[1] >> 24));
+    }
+
+    /// <summary>
+    /// Clear any cryptographic state.
+    /// </summary>		
+    protected void StopDecrypting()
+    {
+      keys = null;
+      cryptbuffer = null;
+    }
+    #endregion
+  }
 }
diff --git a/lib/PdfSharp/PdfSharp.SharpZipLib/Zip/Compression/Streams/OutputWindow.cs b/lib/PdfSharp/PdfSharp.SharpZipLib/Zip/Compression/Streams/OutputWindow.cs
index cb06d43..a48a744 100644
--- a/lib/PdfSharp/PdfSharp.SharpZipLib/Zip/Compression/Streams/OutputWindow.cs
+++ b/lib/PdfSharp/PdfSharp.SharpZipLib/Zip/Compression/Streams/OutputWindow.cs
@@ -38,189 +38,210 @@
 
 using System;
 
-namespace PdfSharp.SharpZipLib.Zip.Compression.Streams 
+namespace PdfSharp.SharpZipLib.Zip.Compression.Streams
 {
-	
-	/// <summary>
-	/// Contains the output from the Inflation process.
-	/// We need to have a window so that we can refer backwards into the output stream
-	/// to repeat stuff.<br/>
-	/// Author of the original java version : John Leuner
-	/// </summary>
-	internal class OutputWindow
-	{
-		private static int WINDOW_SIZE = 1 << 15;
-		private static int WINDOW_MASK = WINDOW_SIZE - 1;
-		
-		private byte[] window = new byte[WINDOW_SIZE]; //The window is 2^15 bytes
-		private int windowEnd  = 0;
-		private int windowFilled = 0;
-		
-		/// <summary>
-		/// Write a byte to this output window
-		/// </summary>
-		/// <param name="abyte">value to write</param>
-		/// <exception cref="InvalidOperationException">
-		/// if window is full
-		/// </exception>
-		public void Write(int abyte)
-		{
-			if (windowFilled++ == WINDOW_SIZE) {
-				throw new InvalidOperationException("Window full");
-			}
-			window[windowEnd++] = (byte) abyte;
-			windowEnd &= WINDOW_MASK;
-		}
-		
-		
-		private void SlowRepeat(int repStart, int len, int dist)
-		{
-			while (len-- > 0) {
-				window[windowEnd++] = window[repStart++];
-				windowEnd &= WINDOW_MASK;
-				repStart &= WINDOW_MASK;
-			}
-		}
-		
-		/// <summary>
-		/// Append a byte pattern already in the window itself
-		/// </summary>
-		/// <param name="len">length of pattern to copy</param>
-		/// <param name="dist">distance from end of window pattern occurs</param>
-		/// <exception cref="InvalidOperationException">
-		/// If the repeated data overflows the window
-		/// </exception>
-		public void Repeat(int len, int dist)
-		{
-			if ((windowFilled += len) > WINDOW_SIZE) {
-				throw new InvalidOperationException("Window full");
-			}
-			
-			int rep_start = (windowEnd - dist) & WINDOW_MASK;
-			int border = WINDOW_SIZE - len;
-			if (rep_start <= border && windowEnd < border) {
-				if (len <= dist) {
-					System.Array.Copy(window, rep_start, window, windowEnd, len);
-					windowEnd += len;
-				} else {
-					/* We have to copy manually, since the repeat pattern overlaps. */
-					while (len-- > 0) {
-						window[windowEnd++] = window[rep_start++];
-					}
-				}
-			} else {
-				SlowRepeat(rep_start, len, dist);
-			}
-		}
-		
-		/// <summary>
-		/// Copy from input manipulator to internal window
-		/// </summary>
-		/// <param name="input">source of data</param>
-		/// <param name="len">length of data to copy</param>
-		/// <returns>the number of bytes copied</returns>
-		public int CopyStored(StreamManipulator input, int len)
-		{
-			len = Math.Min(Math.Min(len, WINDOW_SIZE - windowFilled), input.AvailableBytes);
-			int copied;
-			
-			int tailLen = WINDOW_SIZE - windowEnd;
-			if (len > tailLen) {
-				copied = input.CopyBytes(window, windowEnd, tailLen);
-				if (copied == tailLen) {
-					copied += input.CopyBytes(window, 0, len - tailLen);
-				}
-			} else {
-				copied = input.CopyBytes(window, windowEnd, len);
-			}
-			
-			windowEnd = (windowEnd + copied) & WINDOW_MASK;
-			windowFilled += copied;
-			return copied;
-		}
-		
-		/// <summary>
-		/// Copy dictionary to window
-		/// </summary>
-		/// <param name="dict">source dictionary</param>
-		/// <param name="offset">offset of start in source dictionary</param>
-		/// <param name="len">length of dictionary</param>
-		/// <exception cref="InvalidOperationException">
-		/// If window isnt empty
-		/// </exception>
-		public void CopyDict(byte[] dict, int offset, int len)
-		{
-			if (windowFilled > 0) {
-				throw new InvalidOperationException();
-			}
-			
-			if (len > WINDOW_SIZE) {
-				offset += len - WINDOW_SIZE;
-				len = WINDOW_SIZE;
-			}
-			System.Array.Copy(dict, offset, window, 0, len);
-			windowEnd = len & WINDOW_MASK;
-		}
-
-		/// <summary>
-		/// Get remaining unfilled space in window
-		/// </summary>
-		/// <returns>Number of bytes left in window</returns>
-		public int GetFreeSpace()
-		{
-			return WINDOW_SIZE - windowFilled;
-		}
-		
-		/// <summary>
-		/// Get bytes available for output in window
-		/// </summary>
-		/// <returns>Number of bytes filled</returns>
-		public int GetAvailable()
-		{
-			return windowFilled;
-		}
-
-		/// <summary>
-		/// Copy contents of window to output
-		/// </summary>
-		/// <param name="output">buffer to copy to</param>
-		/// <param name="offset">offset to start at</param>
-		/// <param name="len">number of bytes to count</param>
-		/// <returns>The number of bytes copied</returns>
-		/// <exception cref="InvalidOperationException">
-		/// If a window underflow occurs
-		/// </exception>
-		public int CopyOutput(byte[] output, int offset, int len)
-		{
-			int copy_end = windowEnd;
-			if (len > windowFilled) {
-				len = windowFilled;
-			} else {
-				copy_end = (windowEnd - windowFilled + len) & WINDOW_MASK;
-			}
-			
-			int copied = len;
-			int tailLen = len - copy_end;
-			
-			if (tailLen > 0) {
-				System.Array.Copy(window, WINDOW_SIZE - tailLen, output, offset, tailLen);
-				offset += tailLen;
-				len = copy_end;
-			}
-			System.Array.Copy(window, copy_end - len, output, offset, len);
-			windowFilled -= copied;
-			if (windowFilled < 0) {
-				throw new InvalidOperationException();
-			}
-			return copied;
-		}
-
-		/// <summary>
-		/// Reset by clearing window so <see cref="GetAvailable">GetAvailable</see> returns 0
-		/// </summary>
-		public void Reset()
-		{
-			windowFilled = windowEnd = 0;
-		}
-	}
+
+  /// <summary>
+  /// Contains the output from the Inflation process.
+  /// We need to have a window so that we can refer backwards into the output stream
+  /// to repeat stuff.<br/>
+  /// Author of the original java version: John Leuner
+  /// </summary>
+  internal class OutputWindow
+  {
+    private static int WINDOW_SIZE = 1 << 15;
+    private static int WINDOW_MASK = WINDOW_SIZE - 1;
+
+    private byte[] window = new byte[WINDOW_SIZE]; //The window is 2^15 bytes
+    private int windowEnd = 0;
+    private int windowFilled = 0;
+
+    /// <summary>
+    /// Write a byte to this output window
+    /// </summary>
+    /// <param name="abyte">value to write</param>
+    /// <exception cref="InvalidOperationException">
+    /// if window is full
+    /// </exception>
+    public void Write(int abyte)
+    {
+      if (windowFilled++ == WINDOW_SIZE)
+      {
+        throw new InvalidOperationException("Window full");
+      }
+      window[windowEnd++] = (byte)abyte;
+      windowEnd &= WINDOW_MASK;
+    }
+
+
+    private void SlowRepeat(int repStart, int len, int dist)
+    {
+      while (len-- > 0)
+      {
+        window[windowEnd++] = window[repStart++];
+        windowEnd &= WINDOW_MASK;
+        repStart &= WINDOW_MASK;
+      }
+    }
+
+    /// <summary>
+    /// Append a byte pattern already in the window itself
+    /// </summary>
+    /// <param name="len">length of pattern to copy</param>
+    /// <param name="dist">distance from end of window pattern occurs</param>
+    /// <exception cref="InvalidOperationException">
+    /// If the repeated data overflows the window
+    /// </exception>
+    public void Repeat(int len, int dist)
+    {
+      if ((windowFilled += len) > WINDOW_SIZE)
+      {
+        throw new InvalidOperationException("Window full");
+      }
+
+      int rep_start = (windowEnd - dist) & WINDOW_MASK;
+      int border = WINDOW_SIZE - len;
+      if (rep_start <= border && windowEnd < border)
+      {
+        if (len <= dist)
+        {
+          System.Array.Copy(window, rep_start, window, windowEnd, len);
+          windowEnd += len;
+        }
+        else
+        {
+          /* We have to copy manually, since the repeat pattern overlaps. */
+          while (len-- > 0)
+          {
+            window[windowEnd++] = window[rep_start++];
+          }
+        }
+      }
+      else
+      {
+        SlowRepeat(rep_start, len, dist);
+      }
+    }
+
+    /// <summary>
+    /// Copy from input manipulator to internal window
+    /// </summary>
+    /// <param name="input">source of data</param>
+    /// <param name="len">length of data to copy</param>
+    /// <returns>the number of bytes copied</returns>
+    public int CopyStored(StreamManipulator input, int len)
+    {
+      len = Math.Min(Math.Min(len, WINDOW_SIZE - windowFilled), input.AvailableBytes);
+      int copied;
+
+      int tailLen = WINDOW_SIZE - windowEnd;
+      if (len > tailLen)
+      {
+        copied = input.CopyBytes(window, windowEnd, tailLen);
+        if (copied == tailLen)
+        {
+          copied += input.CopyBytes(window, 0, len - tailLen);
+        }
+      }
+      else
+      {
+        copied = input.CopyBytes(window, windowEnd, len);
+      }
+
+      windowEnd = (windowEnd + copied) & WINDOW_MASK;
+      windowFilled += copied;
+      return copied;
+    }
+
+    /// <summary>
+    /// Copy dictionary to window
+    /// </summary>
+    /// <param name="dict">source dictionary</param>
+    /// <param name="offset">offset of start in source dictionary</param>
+    /// <param name="len">length of dictionary</param>
+    /// <exception cref="InvalidOperationException">
+    /// If window isnt empty
+    /// </exception>
+    public void CopyDict(byte[] dict, int offset, int len)
+    {
+      if (windowFilled > 0)
+      {
+        throw new InvalidOperationException();
+      }
+
+      if (len > WINDOW_SIZE)
+      {
+        offset += len - WINDOW_SIZE;
+        len = WINDOW_SIZE;
+      }
+      System.Array.Copy(dict, offset, window, 0, len);
+      windowEnd = len & WINDOW_MASK;
+    }
+
+    /// <summary>
+    /// Get remaining unfilled space in window
+    /// </summary>
+    /// <returns>Number of bytes left in window</returns>
+    public int GetFreeSpace()
+    {
+      return WINDOW_SIZE - windowFilled;
+    }
+
+    /// <summary>
+    /// Get bytes available for output in window
+    /// </summary>
+    /// <returns>Number of bytes filled</returns>
+    public int GetAvailable()
+    {
+      return windowFilled;
+    }
+
+    /// <summary>
+    /// Copy contents of window to output
+    /// </summary>
+    /// <param name="output">buffer to copy to</param>
+    /// <param name="offset">offset to start at</param>
+    /// <param name="len">number of bytes to count</param>
+    /// <returns>The number of bytes copied</returns>
+    /// <exception cref="InvalidOperationException">
+    /// If a window underflow occurs
+    /// </exception>
+    public int CopyOutput(byte[] output, int offset, int len)
+    {
+      int copy_end = windowEnd;
+      if (len > windowFilled)
+      {
+        len = windowFilled;
+      }
+      else
+      {
+        copy_end = (windowEnd - windowFilled + len) & WINDOW_MASK;
+      }
+
+      int copied = len;
+      int tailLen = len - copy_end;
+
+      if (tailLen > 0)
+      {
+        System.Array.Copy(window, WINDOW_SIZE - tailLen, output, offset, tailLen);
+        offset += tailLen;
+        len = copy_end;
+      }
+      System.Array.Copy(window, copy_end - len, output, offset, len);
+      windowFilled -= copied;
+      if (windowFilled < 0)
+      {
+        throw new InvalidOperationException();
+      }
+      return copied;
+    }
+
+    /// <summary>
+    /// Reset by clearing window so <see cref="GetAvailable">GetAvailable</see> returns 0
+    /// </summary>
+    public void Reset()
+    {
+      windowFilled = windowEnd = 0;
+    }
+  }
 }
diff --git a/lib/PdfSharp/PdfSharp.SharpZipLib/Zip/Compression/Streams/StreamManipulator.cs b/lib/PdfSharp/PdfSharp.SharpZipLib/Zip/Compression/Streams/StreamManipulator.cs
index 983c173..0360652 100644
--- a/lib/PdfSharp/PdfSharp.SharpZipLib/Zip/Compression/Streams/StreamManipulator.cs
+++ b/lib/PdfSharp/PdfSharp.SharpZipLib/Zip/Compression/Streams/StreamManipulator.cs
@@ -38,233 +38,251 @@
 
 using System;
 
-namespace PdfSharp.SharpZipLib.Zip.Compression.Streams 
+namespace PdfSharp.SharpZipLib.Zip.Compression.Streams
 {
-	
-	/// <summary>
-	/// This class allows us to retrieve a specified number of bits from
-	/// the input buffer, as well as copy big byte blocks.
-	///
-	/// It uses an int buffer to store up to 31 bits for direct
-	/// manipulation.  This guarantees that we can get at least 16 bits,
-	/// but we only need at most 15, so this is all safe.
-	///
-	/// There are some optimizations in this class, for example, you must
-	/// never peek more than 8 bits more than needed, and you must first
-	/// peek bits before you may drop them.  This is not a general purpose
-	/// class but optimized for the behaviour of the Inflater.
-	///
-	/// authors of the original java version : John Leuner, Jochen Hoenicke
-	/// </summary>
-	internal class StreamManipulator
-	{
-		private byte[] window;
-		private int window_start = 0;
-		private int window_end = 0;
-		
-		private uint buffer = 0;
-		private int bits_in_buffer = 0;
-		
-		/// <summary>
-		/// Get the next n bits but don't increase input pointer.  n must be
-		/// less or equal 16 and if this call succeeds, you must drop
-		/// at least n - 8 bits in the next call.
-		/// </summary>
-		/// <returns>
-		/// the value of the bits, or -1 if not enough bits available.  */
-		/// </returns>
-		public int PeekBits(int n)
-		{
-			if (bits_in_buffer < n) {
-				if (window_start == window_end) {
-					return -1; // ok
-				}
-				buffer |= (uint)((window[window_start++] & 0xff |
-				                 (window[window_start++] & 0xff) << 8) << bits_in_buffer);
-				bits_in_buffer += 16;
-			}
-			return (int)(buffer & ((1 << n) - 1));
-		}
-		
-		/// <summary>
-		/// Drops the next n bits from the input.  You should have called PeekBits
-		/// with a bigger or equal n before, to make sure that enough bits are in
-		/// the bit buffer.
-		/// </summary>
-		public void DropBits(int n)
-		{
-			buffer >>= n;
-			bits_in_buffer -= n;
-		}
-		
-		/// <summary>
-		/// Gets the next n bits and increases input pointer.  This is equivalent
-		/// to PeekBits followed by dropBits, except for correct error handling.
-		/// </summary>
-		/// <returns>
-		/// the value of the bits, or -1 if not enough bits available.
-		/// </returns>
-		public int GetBits(int n)
-		{
-			int bits = PeekBits(n);
-			if (bits >= 0) {
-				DropBits(n);
-			}
-			return bits;
-		}
-		
-		/// <summary>
-		/// Gets the number of bits available in the bit buffer.  This must be
-		/// only called when a previous PeekBits() returned -1.
-		/// </summary>
-		/// <returns>
-		/// the number of bits available.
-		/// </returns>
-		public int AvailableBits {
-			get {
-				return bits_in_buffer;
-			}
-		}
-		
-		/// <summary>
-		/// Gets the number of bytes available.
-		/// </summary>
-		/// <returns>
-		/// The number of bytes available.
-		/// </returns>
-		public int AvailableBytes {
-			get {
-				return window_end - window_start + (bits_in_buffer >> 3);
-			}
-		}
-		
-		/// <summary>
-		/// Skips to the next byte boundary.
-		/// </summary>
-		public void SkipToByteBoundary()
-		{
-			buffer >>= (bits_in_buffer & 7);
-			bits_in_buffer &= ~7;
-		}
 
-		/// <summary>
-		/// Returns true when SetInput can be called
-		/// </summary>
-		public bool IsNeedingInput {
-			get {
-				return window_start == window_end;
-			}
-		}
-		
-		/// <summary>
-		/// Copies length bytes from input buffer to output buffer starting
-		/// at output[offset].  You have to make sure, that the buffer is
-		/// byte aligned.  If not enough bytes are available, copies fewer
-		/// bytes.
-		/// </summary>
-		/// <param name="output">
-		/// The buffer to copy bytes to.
-		/// </param>
-		/// <param name="offset">
-		/// The offset in the buffer at which copying starts
-		/// </param>
-		/// <param name="length">
-		/// The length to copy, 0 is allowed.
-		/// </param>
-		/// <returns>
-		/// The number of bytes copied, 0 if no bytes were available.
-		/// </returns>
-		/// <exception cref="ArgumentOutOfRangeException">
-		/// Length is less than zero
-		/// </exception>
-		/// <exception cref="InvalidOperationException">
-		/// Bit buffer isnt byte aligned
-		/// </exception>
-		public int CopyBytes(byte[] output, int offset, int length)
-		{
-			if (length < 0) {
-				throw new ArgumentOutOfRangeException("length");
-			}
-			if ((bits_in_buffer & 7) != 0) {
-				/* bits_in_buffer may only be 0 or a multiple of 8 */
-				throw new InvalidOperationException("Bit buffer is not byte aligned!");
-			}
-			
-			int count = 0;
-			while (bits_in_buffer > 0 && length > 0) {
-				output[offset++] = (byte) buffer;
-				buffer >>= 8;
-				bits_in_buffer -= 8;
-				length--;
-				count++;
-			}
-			
-			if (length == 0) {
-				return count;
-			}
-			
-			int avail = window_end - window_start;
-			if (length > avail) {
-				length = avail;
-			}
-			System.Array.Copy(window, window_start, output, offset, length);
-			window_start += length;
-			
-			if (((window_start - window_end) & 1) != 0) {
-				/* We always want an even number of bytes in input, see peekBits */
-				buffer = (uint)(window[window_start++] & 0xff);
-				bits_in_buffer = 8;
-			}
-			return count + length;
-		}
-		
-		/// <summary>
-		/// Constructs a default StreamManipulator with all buffers empty
-		/// </summary>
-		public StreamManipulator()
-		{
-		}
+  /// <summary>
+  /// This class allows us to retrieve a specified number of bits from
+  /// the input buffer, as well as copy big byte blocks.
+  ///
+  /// It uses an int buffer to store up to 31 bits for direct
+  /// manipulation.  This guarantees that we can get at least 16 bits,
+  /// but we only need at most 15, so this is all safe.
+  ///
+  /// There are some optimizations in this class, for example, you must
+  /// never peek more than 8 bits more than needed, and you must first
+  /// peek bits before you may drop them.  This is not a general purpose
+  /// class but optimized for the behaviour of the Inflater.
+  ///
+  /// Authors of the original java version: John Leuner, Jochen Hoenicke
+  /// </summary>
+  internal class StreamManipulator
+  {
+    private byte[] window;
+    private int window_start = 0;
+    private int window_end = 0;
 
-		
-		/// <summary>
-		/// resets state and empties internal buffers
-		/// </summary>
-		public void Reset()
-		{
-			buffer = (uint)(window_start = window_end = bits_in_buffer = 0);
-		}
+    private uint buffer = 0;
+    private int bits_in_buffer = 0;
 
-		/// <summary>
-		/// Add more input for consumption.
-		/// Only call when IsNeedingInput returns true
-		/// </summary>
-		/// <param name="buf">data to be input</param>
-		/// <param name="off">offset of first byte of input</param>
-		/// <param name="len">length of input</param>
-		public void SetInput(byte[] buf, int off, int len)
-		{
-			if (window_start < window_end) {
-				throw new InvalidOperationException("Old input was not completely processed");
-			}
-			
-			int end = off + len;
-			
-			/* We want to throw an ArrayIndexOutOfBoundsException early.  The
-			* check is very tricky: it also handles integer wrap around.
-			*/
-			if (0 > off || off > end || end > buf.Length) {
-				throw new ArgumentOutOfRangeException();
-			}
-			
-			if ((len & 1) != 0) {
-				/* We always want an even number of bytes in input, see peekBits */
-				buffer |= (uint)((buf[off++] & 0xff) << bits_in_buffer);
-				bits_in_buffer += 8;
-			}
-			
-			window = buf;
-			window_start = off;
-			window_end = end;
-		}
-	}
+    /// <summary>
+    /// Get the next n bits but don't increase input pointer.  n must be
+    /// less or equal 16 and if this call succeeds, you must drop
+    /// at least n - 8 bits in the next call.
+    /// </summary>
+    /// <returns>
+    /// the value of the bits, or -1 if not enough bits available.  */
+    /// </returns>
+    public int PeekBits(int n)
+    {
+      if (bits_in_buffer < n)
+      {
+        if (window_start == window_end)
+        {
+          return -1; // ok
+        }
+        buffer |= (uint)((window[window_start++] & 0xff |
+                         (window[window_start++] & 0xff) << 8) << bits_in_buffer);
+        bits_in_buffer += 16;
+      }
+      return (int)(buffer & ((1 << n) - 1));
+    }
+
+    /// <summary>
+    /// Drops the next n bits from the input.  You should have called PeekBits
+    /// with a bigger or equal n before, to make sure that enough bits are in
+    /// the bit buffer.
+    /// </summary>
+    public void DropBits(int n)
+    {
+      buffer >>= n;
+      bits_in_buffer -= n;
+    }
+
+    /// <summary>
+    /// Gets the next n bits and increases input pointer.  This is equivalent
+    /// to PeekBits followed by dropBits, except for correct error handling.
+    /// </summary>
+    /// <returns>
+    /// the value of the bits, or -1 if not enough bits available.
+    /// </returns>
+    public int GetBits(int n)
+    {
+      int bits = PeekBits(n);
+      if (bits >= 0)
+      {
+        DropBits(n);
+      }
+      return bits;
+    }
+
+    /// <summary>
+    /// Gets the number of bits available in the bit buffer.  This must be
+    /// only called when a previous PeekBits() returned -1.
+    /// </summary>
+    /// <returns>
+    /// the number of bits available.
+    /// </returns>
+    public int AvailableBits
+    {
+      get
+      {
+        return bits_in_buffer;
+      }
+    }
+
+    /// <summary>
+    /// Gets the number of bytes available.
+    /// </summary>
+    /// <returns>
+    /// The number of bytes available.
+    /// </returns>
+    public int AvailableBytes
+    {
+      get
+      {
+        return window_end - window_start + (bits_in_buffer >> 3);
+      }
+    }
+
+    /// <summary>
+    /// Skips to the next byte boundary.
+    /// </summary>
+    public void SkipToByteBoundary()
+    {
+      buffer >>= (bits_in_buffer & 7);
+      bits_in_buffer &= ~7;
+    }
+
+    /// <summary>
+    /// Returns true when SetInput can be called
+    /// </summary>
+    public bool IsNeedingInput
+    {
+      get
+      {
+        return window_start == window_end;
+      }
+    }
+
+    /// <summary>
+    /// Copies length bytes from input buffer to output buffer starting
+    /// at output[offset].  You have to make sure, that the buffer is
+    /// byte aligned.  If not enough bytes are available, copies fewer
+    /// bytes.
+    /// </summary>
+    /// <param name="output">
+    /// The buffer to copy bytes to.
+    /// </param>
+    /// <param name="offset">
+    /// The offset in the buffer at which copying starts
+    /// </param>
+    /// <param name="length">
+    /// The length to copy, 0 is allowed.
+    /// </param>
+    /// <returns>
+    /// The number of bytes copied, 0 if no bytes were available.
+    /// </returns>
+    /// <exception cref="ArgumentOutOfRangeException">
+    /// Length is less than zero
+    /// </exception>
+    /// <exception cref="InvalidOperationException">
+    /// Bit buffer isnt byte aligned
+    /// </exception>
+    public int CopyBytes(byte[] output, int offset, int length)
+    {
+      if (length < 0)
+      {
+        throw new ArgumentOutOfRangeException("length");
+      }
+      if ((bits_in_buffer & 7) != 0)
+      {
+        /* bits_in_buffer may only be 0 or a multiple of 8 */
+        throw new InvalidOperationException("Bit buffer is not byte aligned!");
+      }
+
+      int count = 0;
+      while (bits_in_buffer > 0 && length > 0)
+      {
+        output[offset++] = (byte)buffer;
+        buffer >>= 8;
+        bits_in_buffer -= 8;
+        length--;
+        count++;
+      }
+
+      if (length == 0)
+      {
+        return count;
+      }
+
+      int avail = window_end - window_start;
+      if (length > avail)
+      {
+        length = avail;
+      }
+      System.Array.Copy(window, window_start, output, offset, length);
+      window_start += length;
+
+      if (((window_start - window_end) & 1) != 0)
+      {
+        /* We always want an even number of bytes in input, see peekBits */
+        buffer = (uint)(window[window_start++] & 0xff);
+        bits_in_buffer = 8;
+      }
+      return count + length;
+    }
+
+    /// <summary>
+    /// Constructs a default StreamManipulator with all buffers empty
+    /// </summary>
+    public StreamManipulator()
+    {
+    }
+
+
+    /// <summary>
+    /// resets state and empties internal buffers
+    /// </summary>
+    public void Reset()
+    {
+      buffer = (uint)(window_start = window_end = bits_in_buffer = 0);
+    }
+
+    /// <summary>
+    /// Add more input for consumption.
+    /// Only call when IsNeedingInput returns true
+    /// </summary>
+    /// <param name="buf">data to be input</param>
+    /// <param name="off">offset of first byte of input</param>
+    /// <param name="len">length of input</param>
+    public void SetInput(byte[] buf, int off, int len)
+    {
+      if (window_start < window_end)
+      {
+        throw new InvalidOperationException("Old input was not completely processed");
+      }
+
+      int end = off + len;
+
+      /* We want to throw an ArrayIndexOutOfBoundsException early.  The
+      * check is very tricky: it also handles integer wrap around.
+      */
+      if (0 > off || off > end || end > buf.Length)
+      {
+        throw new ArgumentOutOfRangeException();
+      }
+
+      if ((len & 1) != 0)
+      {
+        /* We always want an even number of bytes in input, see peekBits */
+        buffer |= (uint)((buf[off++] & 0xff) << bits_in_buffer);
+        bits_in_buffer += 8;
+      }
+
+      window = buf;
+      window_start = off;
+      window_end = end;
+    }
+  }
 }
diff --git a/lib/PdfSharp/PdfSharp.Windows/enums/RenderMode.cs b/lib/PdfSharp/PdfSharp.Windows/enums/RenderMode.cs
index cd32bb9..8d17912 100644
--- a/lib/PdfSharp/PdfSharp.Windows/enums/RenderMode.cs
+++ b/lib/PdfSharp/PdfSharp.Windows/enums/RenderMode.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -27,26 +27,26 @@
 // DEALINGS IN THE SOFTWARE.
 #endregion
 
-namespace PdfSharp.Forms
+namespace PdfSharp.Windows
 {
   /// <summary>
-  /// Specifies how to reander the preview.
+  /// Specifies how to render the preview.
   /// </summary>
   public enum RenderMode
   {
     /// <summary>
-    /// Draw immediately.
+    /// Draw retained
     /// </summary>
-    Direct = 0,
+    Default = 0,
 
-    /// <summary>
-    /// Draw using a metafile
-    /// </summary>
-    Metafile = 1,
+    ///// <summary>
+    ///// Draw using a metafile
+    ///// </summary>
+    //Metafile = 1,
 
-    /// <summary>
-    /// Draw using a bitmap image.
-    /// </summary>
-    Bitmap = 2
+    ///// <summary>
+    ///// Draw using a bitmap image.
+    ///// </summary>
+    //Bitmap = 2
   }
 }
\ No newline at end of file
diff --git a/lib/PdfSharp/PdfSharp.Windows/enums/Zoom.cs b/lib/PdfSharp/PdfSharp.Windows/enums/Zoom.cs
index c56aba1..e63f2fc 100644
--- a/lib/PdfSharp/PdfSharp.Windows/enums/Zoom.cs
+++ b/lib/PdfSharp/PdfSharp.Windows/enums/Zoom.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -27,7 +27,7 @@
 // DEALINGS IN THE SOFTWARE.
 #endregion
 
-namespace PdfSharp.Forms
+namespace PdfSharp.Windows
 {
   /// <summary>
   /// Defines a zoom factor used in the preview control.
diff --git a/lib/PdfSharp/PdfSharp.csproj b/lib/PdfSharp/PdfSharp.csproj
index 7e2e2e1..b245c76 100644
--- a/lib/PdfSharp/PdfSharp.csproj
+++ b/lib/PdfSharp/PdfSharp.csproj
@@ -1,12 +1,13 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"; ToolsVersion="3.5">
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"; ToolsVersion="3.5">
   <PropertyGroup>
     <ProjectType>Local</ProjectType>
-    <ProductVersion>9.0.30428</ProductVersion>
+    <ProductVersion>9.0.30729</ProductVersion>
     <SchemaVersion>2.0</SchemaVersion>
     <ProjectGuid>{5384CE57-1F94-4D22-860D-2E9C1AC12DDF}</ProjectGuid>
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
     <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ApplicationIcon>
+    </ApplicationIcon>
     <AssemblyKeyContainerName>
     </AssemblyKeyContainerName>
     <AssemblyName>PdfSharp</AssemblyName>
@@ -18,6 +19,8 @@
     <OutputType>Library</OutputType>
     <RootNamespace>PdfSharp</RootNamespace>
     <RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
+    <StartupObject>
+    </StartupObject>
     <FileUpgradeFlags>
     </FileUpgradeFlags>
     <UpgradeBackupLocation>
@@ -39,46 +42,68 @@
     <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
     <UseApplicationTrust>false</UseApplicationTrust>
     <BootstrapperEnabled>true</BootstrapperEnabled>
-    <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <OutputPath>..\..\bin\</OutputPath>
+    <OutputPath>bin\Debug\</OutputPath>
+    <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
     <BaseAddress>285212672</BaseAddress>
+    <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
     <ConfigurationOverrideFile>
     </ConfigurationOverrideFile>
-    <DefineConstants>TRACE;GDI;UseGdiObjects</DefineConstants>
+    <DefineConstants>TRACE;DEBUG;GDI;UseGdiObjects</DefineConstants>
     <DocumentationFile>bin\Debug\PdfSharp.XML</DocumentationFile>
     <DebugSymbols>true</DebugSymbols>
     <FileAlignment>4096</FileAlignment>
-    <Optimize>true</Optimize>
+    <NoStdLib>false</NoStdLib>
+    <NoWarn>
+    </NoWarn>
+    <Optimize>false</Optimize>
     <RegisterForComInterop>false</RegisterForComInterop>
     <RemoveIntegerChecks>false</RemoveIntegerChecks>
+    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
     <WarningLevel>4</WarningLevel>
+    <LangVersion>default</LangVersion>
     <ErrorReport>prompt</ErrorReport>
     <PlatformTarget>AnyCPU</PlatformTarget>
-    <DebugType>full</DebugType>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <OutputPath>..\..\bin\</OutputPath>
+    <OutputPath>bin\Release\</OutputPath>
+    <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
     <BaseAddress>285212672</BaseAddress>
+    <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
     <ConfigurationOverrideFile>
     </ConfigurationOverrideFile>
     <DefineConstants>TRACE;GDI;UseGdiObjects</DefineConstants>
     <DocumentationFile>bin\Release\PdfSharp.XML</DocumentationFile>
+    <DebugSymbols>false</DebugSymbols>
     <FileAlignment>4096</FileAlignment>
+    <NoStdLib>false</NoStdLib>
+    <NoWarn>
+    </NoWarn>
     <Optimize>true</Optimize>
     <RegisterForComInterop>false</RegisterForComInterop>
     <RemoveIntegerChecks>false</RemoveIntegerChecks>
+    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
     <WarningLevel>4</WarningLevel>
     <PlatformTarget>AnyCPU</PlatformTarget>
-    <DebugType>full</DebugType>
-    <DebugSymbols>true</DebugSymbols>
+    <DebugType>none</DebugType>
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="System" />
-    <Reference Include="System.Data" />
-    <Reference Include="System.Drawing" />
-    <Reference Include="System.Xml" />
+    <Reference Include="System">
+      <Name>System</Name>
+    </Reference>
+    <Reference Include="System.Data">
+      <Name>System.Data</Name>
+    </Reference>
+    <Reference Include="System.Drawing">
+      <Name>System.Drawing</Name>
+    </Reference>
+    <Reference Include="System.Windows.Forms">
+      <Name>System.Windows.Forms</Name>
+    </Reference>
+    <Reference Include="System.Xml">
+      <Name>System.XML</Name>
+    </Reference>
   </ItemGroup>
   <ItemGroup>
     <Compile Include="!internal\Directives.cs" />
@@ -90,32 +115,58 @@
     <Compile Include="PdfSharp.Drawing\enums\XGraphicRenderTarget.cs" />
     <Compile Include="PdfSharp.Drawing\FontHelper.cs" />
     <Compile Include="PdfSharp.Drawing\GeometryHelper.cs" />
+    <Compile Include="PdfSharp.Drawing\ImageHelper.cs" />
+    <Compile Include="PdfSharp.Drawing\XFontStretch.cs" />
+    <Compile Include="PdfSharp.Drawing\XFontWeight.cs" />
+    <Compile Include="PdfSharp.Drawing\XFontWeights.cs" />
+    <Compile Include="PdfSharp.Drawing\XGlyphTypeface.cs" />
     <Compile Include="PdfSharp.Drawing\XGraphicsPathInternals.cs" />
     <Compile Include="PdfSharp.Drawing\XPrivateFontCollection.cs" />
     <Compile Include="PdfSharp.Drawing\XKnownColorTable.cs" />
     <Compile Include="PdfSharp.Drawing\XColorResourceManager.cs" />
     <Compile Include="PdfSharp.Drawing\XStringFormats.cs" />
-    <Compile Include="PdfSharp.Fonts.TrueType\ExternalHelper.cs" />
-    <Compile Include="PdfSharp.Fonts.TrueType\FontDescriptor.cs" />
-    <Compile Include="PdfSharp.Fonts.TrueType\IndexToLocationTable.cs">
-      <SubType>Code</SubType>
-    </Compile>
-    <Compile Include="PdfSharp.Fonts.TrueType\GlyphDataTable.cs" />
-    <Compile Include="PdfSharp.Fonts.TrueType\FontData.cs" />
-    <Compile Include="PdfSharp.Fonts.TrueType\IRefFontTable.cs" />
-    <Compile Include="PdfSharp.Fonts.TrueType\GenericFontTable.cs" />
-    <Compile Include="PdfSharp.Fonts.TrueType\TableDirectoryEntry.cs" />
-    <Compile Include="PdfSharp.Fonts.TrueType\enums\TableTagNames.cs" />
-    <Compile Include="PdfSharp.Fonts.TrueType\enums\TableTag.cs" />
-    <Compile Include="PdfSharp.Fonts.TrueType\TrueTypeFontTable.cs" />
+    <Compile Include="PdfSharp.Drawing\XTypeFace.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\enums\FontTechnology.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\ExternalHelper.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\FontDataStock.cs" />
+    <Compile Include="PdfSharp.Fonts\FontDescriptor.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\IndexToLocationTable.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="PdfSharp.Fonts.OpenType\GlyphDataTable.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\FontData.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\IRefFontTable.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\GenericFontTable.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\TableDirectoryEntry.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\enums\TableTagNames.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\enums\TableTag.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\OpenTypeFontTable.cs" />
     <Compile Include="PdfSharp.Fonts\FontWriter.cs" />
-    <Compile Include="PdfSharp.Fonts.TrueType\TrueTypeFontWriter.cs" />
+    <Compile Include="PdfSharp.Fonts.OpenType\OpenTypeFontWriter.cs" />
+    <Compile Include="PdfSharp.Forms\ColorComboBox.cs">
+      <SubType>Component</SubType>
+    </Compile>
     <Compile Include="PdfSharp.Internal\ColorHelper.cs" />
     <Compile Include="PdfSharp.Internal\DoubleUtil.cs" />
     <Compile Include="PdfSharp.Internal\TokenizerHelper.cs" />
+    <Compile Include="PdfSharp.Pdf.AcroForms\enums\PdfAcroFieldFlags.cs" />
+    <Compile Include="PdfSharp.Pdf.AcroForms\PdfAcroField.cs" />
+    <Compile Include="PdfSharp.Pdf.AcroForms\PdfAcroForm.cs" />
+    <Compile Include="PdfSharp.Pdf.AcroForms\PdfButtonField.cs" />
+    <Compile Include="PdfSharp.Pdf.AcroForms\PdfCheckBoxField.cs" />
+    <Compile Include="PdfSharp.Pdf.AcroForms\PdfChoiceField.cs" />
+    <Compile Include="PdfSharp.Pdf.AcroForms\PdfComboBoxField.cs" />
+    <Compile Include="PdfSharp.Pdf.AcroForms\PdfGenericField.cs" />
+    <Compile Include="PdfSharp.Pdf.AcroForms\PdfListBoxField.cs" />
+    <Compile Include="PdfSharp.Pdf.AcroForms\PdfPushButtonField.cs" />
+    <Compile Include="PdfSharp.Pdf.AcroForms\PdfRadioButtonField.cs" />
+    <Compile Include="PdfSharp.Pdf.AcroForms\PdfSignatureField.cs" />
+    <Compile Include="PdfSharp.Pdf.AcroForms\PdfTextField.cs" />
     <Compile Include="PdfSharp.Pdf.Advanced\IContentStream.cs" />
     <Compile Include="PdfSharp.Pdf.Advanced\PdfDictionaryWithContentStream.cs" />
     <Compile Include="PdfSharp.Pdf.Advanced\PdfGroupAttributes.cs" />
+    <Compile Include="PdfSharp.Pdf.Advanced\PdfImage.FaxEncode.cs" />
+    <Compile Include="PdfSharp.Pdf.Advanced\PdfObjectInternals.cs" />
     <Compile Include="PdfSharp.Pdf.Advanced\PdfSoftMask.cs" />
     <Compile Include="PdfSharp.Pdf.Advanced\PdfTilingPattern.cs" />
     <Compile Include="PdfSharp.Pdf.Advanced\PdfToUnicodeMap.cs" />
@@ -156,9 +207,6 @@
     <Compile Include="PdfSharp.Drawing.Pdf\XGraphicsPdfRenderer.cs">
       <SubType>Code</SubType>
     </Compile>
-    <Compile Include="PdfSharp.Drawing.Rtf\XGraphicsRtfRenderer.cs">
-      <SubType>Code</SubType>
-    </Compile>
     <Compile Include="PdfSharp.Drawing.Shapes\Shape.cs">
       <SubType>Code</SubType>
     </Compile>
@@ -307,13 +355,13 @@
     <Compile Include="PdfSharp.Drawing\XVector.cs">
       <SubType>Code</SubType>
     </Compile>
-    <Compile Include="PdfSharp.Fonts.TrueType\FontDescriptorStock.cs">
+    <Compile Include="PdfSharp.Fonts\FontDescriptorStock.cs">
       <SubType>Code</SubType>
     </Compile>
-    <Compile Include="PdfSharp.Fonts.TrueType\TrueTypeStructures.cs">
+    <Compile Include="PdfSharp.Fonts.OpenType\OpenTypeStructures.cs">
       <SubType>Code</SubType>
     </Compile>
-    <Compile Include="PdfSharp.Fonts.TrueType\TrueTypeDescriptor.cs">
+    <Compile Include="PdfSharp.Fonts.OpenType\OpenTypeDescriptor.cs">
       <SubType>Code</SubType>
     </Compile>
     <Compile Include="PdfSharp.Fonts\AdobeGlyphList20.cs">
@@ -323,25 +371,23 @@
       <SubType>Code</SubType>
     </Compile>
     <Compile Include="PdfSharp.Fonts\CMapInfo.cs" />
+    <Compile Include="PdfSharp.Forms\DeviceInfos.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="PdfSharp.Forms\enums\Zoom.cs" />
+    <Compile Include="PdfSharp.Forms\enums\RenderMode.cs" />
+    <Compile Include="PdfSharp.Forms\PagePreview.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="PdfSharp.Forms\PagePreviewCanvas.cs">
+      <SubType>Component</SubType>
+    </Compile>
     <Compile Include="PdfSharp.Internal\Calc.cs">
       <SubType>Code</SubType>
     </Compile>
     <Compile Include="PdfSharp.Internal\NativeMethods.cs">
       <SubType>Code</SubType>
     </Compile>
-    <Compile Include="PdfSharp.Pdf.AcroForms\enums\PdfAcroFieldFlags.cs" />
-    <Compile Include="PdfSharp.Pdf.AcroForms\PdfAcroField.cs" />
-    <Compile Include="PdfSharp.Pdf.AcroForms\PdfAcroForm.cs" />
-    <Compile Include="PdfSharp.Pdf.AcroForms\PdfButtonField.cs" />
-    <Compile Include="PdfSharp.Pdf.AcroForms\PdfCheckBoxField.cs" />
-    <Compile Include="PdfSharp.Pdf.AcroForms\PdfChoiseField.cs" />
-    <Compile Include="PdfSharp.Pdf.AcroForms\PdfComboBoxField.cs" />
-    <Compile Include="PdfSharp.Pdf.AcroForms\PdfGenericField.cs" />
-    <Compile Include="PdfSharp.Pdf.AcroForms\PdfListBoxField.cs" />
-    <Compile Include="PdfSharp.Pdf.AcroForms\PdfPushButtonField.cs" />
-    <Compile Include="PdfSharp.Pdf.AcroForms\PdfRadioButtonField.cs" />
-    <Compile Include="PdfSharp.Pdf.AcroForms\PdfSignatureField.cs" />
-    <Compile Include="PdfSharp.Pdf.AcroForms\PdfTextField.cs" />
     <Compile Include="PdfSharp.Pdf.Actions\enums\PdfNamedActionNames.cs" />
     <Compile Include="PdfSharp.Pdf.Actions\PdfAction.cs" />
     <Compile Include="PdfSharp.Pdf.Advanced\PdfType0Font.cs" />
@@ -470,6 +516,7 @@
     <Compile Include="PdfSharp.Pdf.IO\Chars.cs">
       <SubType>Code</SubType>
     </Compile>
+    <Compile Include="PdfSharp.Pdf.IO\enums\PasswordValidity.cs" />
     <Compile Include="PdfSharp.Pdf.IO\enums\PdfDocumentOpenMode.cs">
       <SubType>Code</SubType>
     </Compile>
@@ -713,9 +760,16 @@
     <Content Include="PdfSharp.SharpZipLib\ReadMe.txt" />
     <Content Include="Resources\Messages.de.txt" />
     <Content Include="Resources\Messages.txt" />
-    <None Include="StrongnameKey.snk" />
   </ItemGroup>
   <ItemGroup>
+    <EmbeddedResource Include="PdfSharp.Forms\PagePreview.resx">
+      <DependentUpon>PagePreview.cs</DependentUpon>
+      <SubType>Designer</SubType>
+    </EmbeddedResource>
+    <EmbeddedResource Include="PdfSharp.Forms\PagePreviewCanvas.resx">
+      <DependentUpon>PagePreviewCanvas.cs</DependentUpon>
+      <SubType>Designer</SubType>
+    </EmbeddedResource>
     <EmbeddedResource Include="Resources\Messages.de.resx">
       <SubType>Designer</SubType>
     </EmbeddedResource>
@@ -724,16 +778,30 @@
     </EmbeddedResource>
   </ItemGroup>
   <ItemGroup>
+    <None Include="StrongnameKey.snk" />
+  </ItemGroup>
+  <ItemGroup>
     <BootstrapperPackage Include="Microsoft.Net.Framework.2.0">
       <Visible>False</Visible>
+      <ProductName>.NET Framework 2.0 %28x86%29</ProductName>
+      <Install>true</Install>
     </BootstrapperPackage>
     <BootstrapperPackage Include="Microsoft.Net.Framework.3.0">
       <Visible>False</Visible>
+      <ProductName>.NET Framework 3.0 %28x86%29</ProductName>
+      <Install>false</Install>
     </BootstrapperPackage>
     <BootstrapperPackage Include="Microsoft.Net.Framework.3.5">
       <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5</ProductName>
+      <Install>false</Install>
     </BootstrapperPackage>
   </ItemGroup>
+  <ItemGroup>
+    <Folder Include="AGInternals\" />
+    <Folder Include="PdfSharp.Drawing.Wpf\" />
+    <Folder Include="Resources\images\" />
+  </ItemGroup>
   <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
   <PropertyGroup>
     <PreBuildEvent>
@@ -741,11 +809,4 @@
     <PostBuildEvent>
     </PostBuildEvent>
   </PropertyGroup>
-  <ProjectExtensions>
-    <MonoDevelop>
-      <Properties>
-        <Deployment.LinuxDeployData generatePcFile="false" />
-      </Properties>
-    </MonoDevelop>
-  </ProjectExtensions>
-</Project>
+</Project>
\ No newline at end of file
diff --git a/lib/PdfSharp/PdfSharp.csproj.resharper b/lib/PdfSharp/PdfSharp.csproj.resharper
new file mode 100644
index 0000000..16ecced
--- /dev/null
+++ b/lib/PdfSharp/PdfSharp.csproj.resharper
@@ -0,0 +1,3 @@
+<Configuration>
+  <CSharpLanguageLevel>CSharp20</CSharpLanguageLevel>
+</Configuration>
\ No newline at end of file
diff --git a/lib/PdfSharp/PdfSharp/PSSR.cs b/lib/PdfSharp/PdfSharp/PSSR.cs
index 6b8b5b0..9e3787b 100644
--- a/lib/PdfSharp/PdfSharp/PSSR.cs
+++ b/lib/PdfSharp/PdfSharp/PSSR.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -42,11 +42,11 @@ namespace PdfSharp
   /// <summary>
   /// The Pdf-Sharp-String-Resources.
   /// </summary>
-  public static class PSSR
+  static class PSSR
   {
     // How to use:
     // Create a function or property for each message text, depending on how much parameters are
-    // part of the message. For the time beginning, type plain english text in the function or property. 
+    // part of the message. For the time beginning, type plain English text in the function or property. 
     // The use of functions is save when a parameter must be changed. The compiler tells you all
     // places in your code that must be modified.
     // For localization, create a enum value for each function or property with the same name. Then
@@ -72,10 +72,7 @@ namespace PdfSharp
       try
       {
         message = PSSR.GetString(id);
-        if (message != null)
-          message = Format(message, args);
-        else
-          message = "INTERNAL ERROR: Message not found in resources.";
+        message = message != null ? Format(message, args) : "INTERNAL ERROR: Message not found in resources.";
         return message;
       }
       catch (Exception ex)
@@ -97,7 +94,7 @@ namespace PdfSharp
       }
       catch (Exception ex)
       {
-        message = String.Format("UNEXPECTED ERROR while formatting message '{0}': {1}", format, ex.ToString());
+        message = String.Format("UNEXPECTED ERROR while formatting message '{0}': {1}", format, ex);
       }
       return message;
     }
@@ -157,7 +154,12 @@ namespace PdfSharp
 
     public static string FontDataReadOnly
     {
-      get { return "Font data is read-only"; }
+      get { return "Font data is read-only."; }
+    }
+
+    public static string ErrorReadingFontData
+    {
+      get { return "Error while parsing an OpenType font."; }
     }
 
     #endregion
@@ -252,7 +254,7 @@ namespace PdfSharp
 
     public static string UnexpectedTokenInPdfFile
     {
-      get { return "Unexpected token in PDF file. The PDF file may be currupt. If it is not, please send us the file for serivce."; }
+      get { return "Unexpected token in PDF file. The PDF file may be corrupt. If it is not, please send us the file for service."; }
     }
 
     public static string InappropriateColorSpace(PdfColorMode colorMode, XColorSpace colorSpace)
@@ -330,7 +332,7 @@ namespace PdfSharp
         if (PSSR.resmngr == null)
         {
 #if true_
-          // Force the english language, even on a German PC.
+          // Force the English language, even on German Windows.
           System.Threading.Thread.CurrentThread.CurrentUICulture = System.Globalization.CultureInfo.InvariantCulture;
 #endif
           PSSR.resmngr = new ResourceManager("PdfSharp.Resources.Messages", Assembly.GetExecutingAssembly());
@@ -346,6 +348,7 @@ namespace PdfSharp
     [Conditional("DEBUG")]
     public static void TestResourceMessages()
     {
+#if !SILVERLIGHT
       string[] names = Enum.GetNames(typeof(PSMsgID));
       foreach (string name in names)
       {
@@ -353,13 +356,15 @@ namespace PdfSharp
         Debug.Assert(message != null);
         Debug.WriteLine(message);
       }
+#else
+#endif
     }
 
     static PSSR()
     {
-      //TestResourceMessages();
+      TestResourceMessages();
     }
 
     #endregion
   }
-}
+}
\ No newline at end of file
diff --git a/lib/PdfSharp/PdfSharp/PageSizeConverter.cs b/lib/PdfSharp/PdfSharp/PageSizeConverter.cs
index 63aa1a1..28d974c 100644
--- a/lib/PdfSharp/PdfSharp/PageSizeConverter.cs
+++ b/lib/PdfSharp/PdfSharp/PageSizeConverter.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -41,10 +41,8 @@ namespace PdfSharp
   /// <summary>
   /// Converter from <see cref="PageSize"/> to <see cref="XSize"/>.
   /// </summary>
-  public sealed class PageSizeConverter
+  public static class PageSizeConverter
   {
-    PageSizeConverter() { }
-
     /// <summary>
     /// Converts the specified page size enumeration to a pair of values in point.
     /// </summary>
diff --git a/lib/PdfSharp/PdfSharp/PdfSharpException.cs b/lib/PdfSharp/PdfSharp/PdfSharpException.cs
index cdccbdb..24fa8b3 100644
--- a/lib/PdfSharp/PdfSharp/PdfSharpException.cs
+++ b/lib/PdfSharp/PdfSharp/PdfSharpException.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -34,7 +34,7 @@ namespace PdfSharp
   /// <summary>
   /// Base class of all exceptions in the PDFsharp frame work.
   /// </summary>
-  public class PdfSharpException : ApplicationException
+  public class PdfSharpException : Exception
   {
     // The class is not yet used
 
diff --git a/lib/PdfSharp/PdfSharp/ProductVersionInfo.cs b/lib/PdfSharp/PdfSharp/ProductVersionInfo.cs
index b521933..0741371 100644
--- a/lib/PdfSharp/PdfSharp/ProductVersionInfo.cs
+++ b/lib/PdfSharp/PdfSharp/ProductVersionInfo.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -27,6 +27,8 @@
 // DEALINGS IN THE SOFTWARE.
 #endregion
 
+using System;
+
 namespace PdfSharp
 {
   /// <summary>
@@ -82,7 +84,7 @@ namespace PdfSharp
     /// <summary>
     /// The copyright information.
     /// </summary>
-    public const string Copyright = "Copyright © 2005-2008 empira Software GmbH.";
+    public const string Copyright = "Copyright © 2005-2009 empira Software GmbH.";
 
     /// <summary>
     /// The trademark the product.
@@ -102,12 +104,12 @@ namespace PdfSharp
     /// <summary>
     /// The minor version number of the product.
     /// </summary>
-    public const string VersionMinor = "2";
+    public const string VersionMinor = "31";
 
     /// <summary>
     /// The build number of the product.
     /// </summary>
-    public const string VersionBuild = "1269";  // Build = days since 2005-01-01  -  change this values ONLY HERE
+    public const string VersionBuild = "1789";  // Build = days since 2005-01-01  -  change this values ONLY HERE
 
     /// <summary>
     /// The patch number of the product.
@@ -118,7 +120,7 @@ namespace PdfSharp
     /// <summary>
     /// The calculated build number.
     /// </summary>
-    public static int BuildNumber = (System.DateTime.Now - new System.DateTime(2005, 1, 1)).Days;
+    public static int BuildNumber = (DateTime.Now - new DateTime(2005, 1, 1)).Days;
 #endif
 
     /// <summary>
@@ -130,12 +132,14 @@ namespace PdfSharp
 #if GDI && !WPF
     public const string Technologie = "-g";
 #endif
-#if WPF && !GDI
+#if WPF && !GDI && !SILVERLIGHT
     public const string Technologie = "-w";
 #endif
 #if WPF && GDI
     public const string Technologie = "-h";
 #endif
-
+#if SILVERLIGHT
+    public const string Technologie = "-ag";
+#endif
   }
 }
diff --git a/lib/PdfSharp/PdfSharp/VersionInfo.cs b/lib/PdfSharp/PdfSharp/VersionInfo.cs
index e6c5fee..491a397 100644
--- a/lib/PdfSharp/PdfSharp/VersionInfo.cs
+++ b/lib/PdfSharp/PdfSharp/VersionInfo.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/PdfSharp/enums/PSMsgID.cs b/lib/PdfSharp/PdfSharp/enums/PSMsgID.cs
index ea4902c..584856d 100644
--- a/lib/PdfSharp/PdfSharp/enums/PSMsgID.cs
+++ b/lib/PdfSharp/PdfSharp/enums/PSMsgID.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -29,31 +29,49 @@
 
 using System;
 
-#pragma warning disable 1591
-
 namespace PdfSharp
 {
   /// <summary>
   /// Represents IDs for error and diagnostic messages generated by PDFsharp.
   /// </summary>
-  public enum PSMsgID
+  enum PSMsgID
   {
     // ----- General Messages ---------------------------------------------------------------------
 
+    /// <summary>
+    /// PSMsgID.
+    /// </summary>
     SampleMessage1,
+
+    /// <summary>
+    /// PSMsgID.
+    /// </summary>
     SampleMessage2,
 
     // ----- XGraphics Messages -------------------------------------------------------------------
 
     // ----- PDF Messages -------------------------------------------------------------------------
 
+    /// <summary>
+    /// PSMsgID.
+    /// </summary>
     NameMustStartWithSlash,
+
+    /// <summary>
+    /// PSMsgID.
+    /// </summary>
     UserOrOwnerPasswordRequired,
 
     // ----- PdfParser Messages -------------------------------------------------------------------
 
+    /// <summary>
+    /// PSMsgID.
+    /// </summary>
     UnexpectedToken,
-    UnknownEncryption,
 
+    /// <summary>
+    /// PSMsgID.
+    /// </summary>
+    UnknownEncryption,
   }
 }
\ No newline at end of file
diff --git a/lib/PdfSharp/PdfSharp/enums/PageOrientation.cs b/lib/PdfSharp/PdfSharp/enums/PageOrientation.cs
index d1176f2..ce7b1f9 100644
--- a/lib/PdfSharp/PdfSharp/enums/PageOrientation.cs
+++ b/lib/PdfSharp/PdfSharp/enums/PageOrientation.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -30,6 +30,13 @@
 namespace PdfSharp
 {
   /// <summary>
+  /// Base namespace of PDFsharp. Most classes are implemented in nested namespaces like e. g. PdfSharp.Pdf.
+  /// </summary>
+  /// <seealso cref="PdfSharp.Pdf"></seealso>
+  [System.Runtime.CompilerServices.CompilerGenerated]
+  internal class NamespaceDoc { }
+
+  /// <summary>
   /// Specifies the orientation of a page.
   /// </summary>
   public enum PageOrientation
diff --git a/lib/PdfSharp/PdfSharp/enums/PageSize.cs b/lib/PdfSharp/PdfSharp/enums/PageSize.cs
index b4e0f66..33b4b75 100644
--- a/lib/PdfSharp/PdfSharp/enums/PageSize.cs
+++ b/lib/PdfSharp/PdfSharp/enums/PageSize.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
@@ -32,7 +32,7 @@ using System;
 namespace PdfSharp
 {
   /// <summary>
-  /// Idetifies the most popular predefined page sizes.
+  /// Identifies the most popular predefined page sizes.
   /// </summary>
   public enum PageSize
   {
@@ -45,123 +45,123 @@ namespace PdfSharp
     // see http://www.engineeringtoolbox.com/drawings-paper-sheets-sizes-25_349.html
 
     /// <summary>
-    /// Identifies a pager sheet size of 841 mm times 1189 mm or 33.11 inch times 46.81 inch.
+    /// Identifies a paper sheet size of 841 mm times 1189 mm or 33.11 inch times 46.81 inch.
     /// </summary>
     A0 = 1,
 
     /// <summary>
-    /// Identifies a pager sheet size of 594 mm times 841 mm or 23.39 inch times 33.1 inch.
+    /// Identifies a paper sheet size of 594 mm times 841 mm or 23.39 inch times 33.1 inch.
     /// </summary>
     A1 = 2,
 
     /// <summary>
-    /// Identifies a pager sheet size of 420 mm times 594 mm or 16.54 inch times 23.29 inch.
+    /// Identifies a paper sheet size of 420 mm times 594 mm or 16.54 inch times 23.29 inch.
     /// </summary>
     A2 = 3,
 
     /// <summary>
-    /// Identifies a pager sheet size of 297 mm times 420 mm or 11.69 inch times 16.54 inch.
+    /// Identifies a paper sheet size of 297 mm times 420 mm or 11.69 inch times 16.54 inch.
     /// </summary>
     A3 = 4,
 
     /// <summary>
-    /// Identifies a pager sheet size of 210 mm times 297 mm or 8.27 inch times 11.69 inch.
+    /// Identifies a paper sheet size of 210 mm times 297 mm or 8.27 inch times 11.69 inch.
     /// </summary>
     A4 = 5,
 
     /// <summary>
-    /// Identifies a pager sheet size of 148 mm times 210 mm or 5.83 inch times 8.27 inch.
+    /// Identifies a paper sheet size of 148 mm times 210 mm or 5.83 inch times 8.27 inch.
     /// </summary>
     A5 = 6,
 
     /// <summary>
-    /// Identifies a pager sheet size of 860 mm times 1220 mm.
+    /// Identifies a paper sheet size of 860 mm times 1220 mm.
     /// </summary>
     RA0 = 7,
 
     /// <summary>
-    /// Identifies a pager sheet size of 610 mm times 860 mm.
+    /// Identifies a paper sheet size of 610 mm times 860 mm.
     /// </summary>
     RA1 = 8,
 
     /// <summary>
-    /// Identifies a pager sheet size of 430 mm times 610 mm.
+    /// Identifies a paper sheet size of 430 mm times 610 mm.
     /// </summary>
     RA2 = 9,
 
     /// <summary>
-    /// Identifies a pager sheet size of 305 mm times 430 mm.
+    /// Identifies a paper sheet size of 305 mm times 430 mm.
     /// </summary>
     RA3 = 10,
 
     /// <summary>
-    /// Identifies a pager sheet size of 215 mm times 305 mm.
+    /// Identifies a paper sheet size of 215 mm times 305 mm.
     /// </summary>
     RA4 = 11,
 
     /// <summary>
-    /// Identifies a pager sheet size of 153 mm times 215 mm.
+    /// Identifies a paper sheet size of 153 mm times 215 mm.
     /// </summary>
     RA5 = 12,
 
     /// <summary>
-    /// Identifies a pager sheet size of 1000 mm times 1414 mm or 39.37 inch times 55.67 inch.
+    /// Identifies a paper sheet size of 1000 mm times 1414 mm or 39.37 inch times 55.67 inch.
     /// </summary>
     B0 = 13,
 
     /// <summary>
-    /// Identifies a pager sheet size of 707 mm times 1000 mm or 27.83 inch times 39.37 inch.
+    /// Identifies a paper sheet size of 707 mm times 1000 mm or 27.83 inch times 39.37 inch.
     /// </summary>
     B1 = 14,
 
     /// <summary>
-    /// Identifies a pager sheet size of 500 mm times 707 mm or 19.68 inch times 27.83 inch.
+    /// Identifies a paper sheet size of 500 mm times 707 mm or 19.68 inch times 27.83 inch.
     /// </summary>
     B2 = 15,
 
     /// <summary>
-    /// Identifies a pager sheet size of 353 mm times 500 mm or 13.90 inch times 19.68 inch.
+    /// Identifies a paper sheet size of 353 mm times 500 mm or 13.90 inch times 19.68 inch.
     /// </summary>
     B3 = 16,
 
     /// <summary>
-    /// Identifies a pager sheet size of 250 mm times 353 mm or 9.84 inch times 13.90 inch.
+    /// Identifies a paper sheet size of 250 mm times 353 mm or 9.84 inch times 13.90 inch.
     /// </summary>
     B4 = 17,
 
     /// <summary>
-    /// Identifies a pager sheet size of 176 mm times 250 mm or 6.93 inch times 9.84 inch.
+    /// Identifies a paper sheet size of 176 mm times 250 mm or 6.93 inch times 9.84 inch.
     /// </summary>
     B5 = 18,
 
 #if false
     /// <summary>
-    /// Identifies a pager sheet size of 917 mm times 1297 mm or 36.00 inch times 51.20 inch.
+    /// Identifies a paper sheet size of 917 mm times 1297 mm or 36.00 inch times 51.20 inch.
     /// </summary>
     C0 = 19,
 
     /// <summary>
-    /// Identifies a pager sheet size of 648 mm times 917 mm or 25.60 inch times 36.00 inch.
+    /// Identifies a paper sheet size of 648 mm times 917 mm or 25.60 inch times 36.00 inch.
     /// </summary>
     C1 = 20,
 
     /// <summary>
-    /// Identifies a pager sheet size of 458 mm times 648 mm or 18.00 inch times 25.60 inch.
+    /// Identifies a paper sheet size of 458 mm times 648 mm or 18.00 inch times 25.60 inch.
     /// </summary>
     C2 = 21,
 
     /// <summary>
-    /// Identifies a pager sheet size of 324 mm times 458 mm or 12.80 inch times 18.00 inch.
+    /// Identifies a paper sheet size of 324 mm times 458 mm or 12.80 inch times 18.00 inch.
     /// </summary>
     C3 = 22,
 
     /// <summary>
-    /// Identifies a pager sheet size of 229 mm times 324 mm or 9.00 inch times 12.80 inch.
+    /// Identifies a paper sheet size of 229 mm times 324 mm or 9.00 inch times 12.80 inch.
     /// </summary>
     C4 = 23,
 
     /// <summary>
-    /// Identifies a pager sheet size of 162 mm times 229 mm or 6.40 inch times 9.0 inch.
+    /// Identifies a paper sheet size of 162 mm times 229 mm or 6.40 inch times 9.0 inch.
     /// </summary>
     C5 = 24,
 #endif
@@ -170,107 +170,107 @@ namespace PdfSharp
     // see http://www.reference.com/browse/wiki/Paper_size
 
     /// <summary>
-    /// Identifies a pager sheet size of 10 inch times 8 inch or 254 mm times 203 mm.
+    /// Identifies a paper sheet size of 10 inch times 8 inch or 254 mm times 203 mm.
     /// </summary>
     Quarto = 100,
 
     /// <summary>
-    /// Identifies a pager sheet size of 13 inch times 8 inch or 330 mm times 203 mm.
+    /// Identifies a paper sheet size of 13 inch times 8 inch or 330 mm times 203 mm.
     /// </summary>
     Foolscap = 101,
 
     /// <summary>
-    ///  Identifies a pager sheet size of 10.5 inch times 7.25 inch or 267 mm times 184 mm.
+    ///  Identifies a paper sheet size of 10.5 inch times 7.25 inch or 267 mm times 184 mm.
     /// </summary>
     Executive = 102,
 
     /// <summary>
-    /// Identifies a pager sheet size of 10.5 inch times 8 inch 267 mm times 203 mm.
+    /// Identifies a paper sheet size of 10.5 inch times 8 inch 267 mm times 203 mm.
     /// </summary>
     GovernmentLetter = 103,
 
     /// <summary>
-    /// Identifies a pager sheet size of 11 inch times 8.5 inch 279 mm times 216 mm.
+    /// Identifies a paper sheet size of 11 inch times 8.5 inch 279 mm times 216 mm.
     /// </summary>
     Letter = 104,
 
     /// <summary>
-    /// Identifies a pager sheet size of 14 inch times 8.5 inch 356 mm times 216 mm.
+    /// Identifies a paper sheet size of 14 inch times 8.5 inch 356 mm times 216 mm.
     /// </summary>
     Legal = 105,
 
     /// <summary>
-    /// Identifies a pager sheet size of 17 inch times 11 inch or 432 mm times 279 mm.
+    /// Identifies a paper sheet size of 17 inch times 11 inch or 432 mm times 279 mm.
     /// </summary>
     Ledger = 106,
 
     /// <summary>
-    /// Identifies a pager sheet size of 17 inch times 11 inch or 432 mm times 279 mm.
+    /// Identifies a paper sheet size of 17 inch times 11 inch or 432 mm times 279 mm.
     /// </summary>
     Tabloid = 107,
 
     /// <summary>
-    /// Identifies a pager sheet size of 19.25 inch times 15.5 inch 489 mm times 394 mm.
+    /// Identifies a paper sheet size of 19.25 inch times 15.5 inch 489 mm times 394 mm.
     /// </summary>
     Post = 108,
 
     /// <summary>
-    /// 20 ×Identifies a pager sheet size of 20 inch times 15 inch or 508 mm times 381 mm.
+    /// 20 ×Identifies a paper sheet size of 20 inch times 15 inch or 508 mm times 381 mm.
     /// </summary>
     Crown = 109,
 
     /// <summary>
-    /// Identifies a pager sheet size of 21 inch times 16.5 inch 533 mm times 419 mm.
+    /// Identifies a paper sheet size of 21 inch times 16.5 inch 533 mm times 419 mm.
     /// </summary>
     LargePost = 110,
 
     /// <summary>
-    /// Identifies a pager sheet size of 22.5 inch times 17.5 inch 572 mm times 445 mm.
+    /// Identifies a paper sheet size of 22.5 inch times 17.5 inch 572 mm times 445 mm.
     /// </summary>
     Demy = 111,
 
     /// <summary>
-    /// Identifies a pager sheet size of 23 inch times 18 inch or 584 mm times 457 mm.
+    /// Identifies a paper sheet size of 23 inch times 18 inch or 584 mm times 457 mm.
     /// </summary>
     Medium = 112,
 
     /// <summary>
-    /// Identifies a pager sheet size of 25 inch times 20 inch or 635 mm times 508 mm.
+    /// Identifies a paper sheet size of 25 inch times 20 inch or 635 mm times 508 mm.
     /// </summary>
     Royal = 113,
 
     /// <summary>
-    /// Identifies a pager sheet size of 28 inch times 23 inch or 711 mm times 584 mm.
+    /// Identifies a paper sheet size of 28 inch times 23 inch or 711 mm times 584 mm.
     /// </summary>
     Elephant = 114,
 
     /// <summary>
-    /// Identifies a pager sheet size of 35 inch times 23.5 inch or 889 mm times 597 mm.
+    /// Identifies a paper sheet size of 35 inch times 23.5 inch or 889 mm times 597 mm.
     /// </summary>
     DoubleDemy = 115,
 
     /// <summary>
-    /// Identifies a pager sheet size of 45 inch times 35 inch or or × mm times 1143 × 889 mm.
+    /// Identifies a paper sheet size of 45 inch times 35 inch 1143 times 889 mm.
     /// </summary>
     QuadDemy = 116,
 
     /// <summary>
-    /// Identifies a pager sheet size of 8.5 inch times 5.5 inch or 216 mm times 396 mm.
+    /// Identifies a paper sheet size of 8.5 inch times 5.5 inch or 216 mm times 396 mm.
     /// </summary>
     STMT = 117,
 
     /// <summary>
-    /// Identifies a pager sheet size of 8.5 inch times 13 inch or 216 mm times 330 mm.
+    /// Identifies a paper sheet size of 8.5 inch times 13 inch or 216 mm times 330 mm.
     /// </summary>
     Folio = 120,
 
     /// <summary>
-    /// Identifies a pager sheet size of 5.5 inch times 8.5 inch or 396 mm times 216 mm.
+    /// Identifies a paper sheet size of 5.5 inch times 8.5 inch or 396 mm times 216 mm.
     /// </summary>
     Statement = 121,
 
     /// <summary>
-    /// Identifies a pager sheet size of 10 inch times 14 inch.
+    /// Identifies a paper sheet size of 10 inch times 14 inch.
     /// </summary>
     Size10x14 = 122,
 
diff --git a/lib/PdfSharp/Properties/AssemblyInfo.cs b/lib/PdfSharp/Properties/AssemblyInfo.cs
index 6036073..76d5316 100644
--- a/lib/PdfSharp/Properties/AssemblyInfo.cs
+++ b/lib/PdfSharp/Properties/AssemblyInfo.cs
@@ -3,7 +3,7 @@
 // Authors:
 //   Stefan Lange (mailto:Stefan Lange pdfsharp com)
 //
-// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
 //
 // http://www.pdfsharp.com
 // http://sourceforge.net/projects/pdfsharp
diff --git a/lib/PdfSharp/Resources/Messages.de.resources b/lib/PdfSharp/Resources/Messages.de.resources
index d650044..fa5ed3c 100644
Binary files a/lib/PdfSharp/Resources/Messages.de.resources and b/lib/PdfSharp/Resources/Messages.de.resources differ
diff --git a/lib/PdfSharp/Resources/Messages.resources b/lib/PdfSharp/Resources/Messages.resources
index 6f24830..3782508 100644
Binary files a/lib/PdfSharp/Resources/Messages.resources and b/lib/PdfSharp/Resources/Messages.resources differ
diff --git a/lib/PdfSharp/Resources/PdfSharp.resources.VS2005.vcproj b/lib/PdfSharp/Resources/PdfSharp.resources.VS2005.vcproj
new file mode 100644
index 0000000..8a405ed
--- /dev/null
+++ b/lib/PdfSharp/Resources/PdfSharp.resources.VS2005.vcproj
@@ -0,0 +1,114 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8,00"
+	Name="PdfSharp.Resources"
+	ProjectGUID="{B0E5A807-AB5D-4B5A-9ECD-4A08EAEB6B59}"
+	RootNamespace="PdfSharp"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="."
+			IntermediateDirectory="."
+			ConfigurationType="10"
+			DeleteExtensionsOnClean="*.resources,*.obj;*.ilk;*.pdb;*.tlb;*.tli;*.tlh;*.tmp;*.rsp;*.bat;$(TargetPath)"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+				CommandLine="resgen Messages.resources Messages.resx&#x0D;&#x0A;resgen Messages.de.resources Messages.de.resx&#x0D;&#x0A;"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="."
+			IntermediateDirectory="."
+			ConfigurationType="10"
+			DeleteExtensionsOnClean="*.resources,*.obj;*.ilk;*.pdb;*.tlb;*.tli;*.tlh;*.tmp;*.rsp;*.bat;$(TargetPath)"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+				CommandLine="resgen Messages.resources Messages.resx&#x0D;&#x0A;resgen Messages.de.resources Messages.de.resx&#x0D;&#x0A;"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<File
+			RelativePath=".\Messages.de.txt"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCustomBuildTool"
+					Description="Compiling $(InputFileName)"
+					CommandLine="resgen &quot;$(InputPath)&quot;&#x0D;&#x0A;"
+					Outputs="$(ProjectDir)$(InputName)"
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCustomBuildTool"
+					Description="Compiling $(InputFileName)"
+					CommandLine="resgen &quot;$(InputPath)&quot;&#x0D;&#x0A;"
+					Outputs="$(ProjectDir)$(InputName)"
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath=".\Messages.txt"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCustomBuildTool"
+					Description="Compiling $(InputFileName)"
+					CommandLine="resgen &quot;$(InputPath)&quot;&#x0D;&#x0A;"
+					Outputs="$(ProjectDir)$(InputName)"
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCustomBuildTool"
+					Description="Compiling $(InputFileName)"
+					CommandLine="resgen &quot;$(InputPath)&quot;&#x0D;&#x0A;"
+					Outputs="$(ProjectDir)$(InputName)"
+				/>
+			</FileConfiguration>
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]