From c3e2b817615c9c2bbaf056e5547cd3f95f8905ea Mon Sep 17 00:00:00 2001
From: Andreas Fitzek <andreas.fitzek@iaik.tugraz.at>
Date: Thu, 16 Oct 2014 13:32:35 +0200
Subject: added PDFBOX specifc library

---
 .../egiz/pdfas/lib/impl/pdfbox/PDFBOXBackend.java  |  40 +
 .../egiz/pdfas/lib/impl/pdfbox/PDFBOXObject.java   |  59 ++
 .../placeholder/PDFBoxPlaceholderExtractor.java    |  24 +
 .../placeholder/SignaturePlaceholderExtractor.java | 371 ++++++++
 .../lib/impl/pdfbox/positioning/Positioning.java   | 237 +++++
 .../pdfas/lib/impl/pdfbox/utils/PdfBoxUtils.java   |  73 ++
 .../lib/impl/signing/pdfbox/PADESPDFBOXSigner.java | 626 +++++++++++++
 .../pdfbox/PDFASPDFBOXExtractorInterface.java      |   7 +
 .../pdfbox/PDFASPDFBOXSignatureInterface.java      |  10 +
 .../impl/signing/pdfbox/PdfboxSignerWrapper.java   |  96 ++
 .../signing/pdfbox/SignatureDataExtractor.java     |  94 ++
 .../lib/impl/stamping/pdfbox/ImageObject.java      |  63 ++
 .../impl/stamping/pdfbox/PDFAsTemplateCreator.java | 170 ++++
 .../pdfbox/PDFAsVisualSignatureBuilder.java        | 994 +++++++++++++++++++++
 .../pdfbox/PDFAsVisualSignatureDesigner.java       | 450 ++++++++++
 .../pdfbox/PDFAsVisualSignatureProperties.java     |  99 ++
 .../pdfas/lib/impl/stamping/pdfbox/PDFBoxFont.java | 169 ++++
 .../lib/impl/stamping/pdfbox/PDFBoxTable.java      | 691 ++++++++++++++
 .../lib/impl/stamping/pdfbox/PdfBoxStamper.java    |  60 ++
 .../impl/stamping/pdfbox/PdfBoxVisualObject.java   |  97 ++
 .../lib/impl/stamping/pdfbox/TableDrawUtils.java   | 564 ++++++++++++
 .../lib/impl/verify/pdfbox/PDFBOXVerifier.java     | 172 ++++
 .../at/knowcenter/wag/egov/egiz/pdf/PDFPage.java   | 599 +++++++++++++
 .../knowcenter/wag/egov/egiz/pdf/PDFUtilities.java | 110 +++
 .../path/PathConstructionOperatorProcessor.java    |  84 ++
 .../path/PathPaintingOperatorProcessor.java        |  65 ++
 .../pdf/operator/path/construction/ClosePath.java  |  91 ++
 .../pdf/operator/path/construction/CurveTo.java    | 108 +++
 .../construction/CurveToReplicateFinalPoint.java   | 105 +++
 .../construction/CurveToReplicateInitialPoint.java | 107 +++
 .../pdf/operator/path/construction/LineTo.java     |  94 ++
 .../pdf/operator/path/construction/MoveTo.java     |  96 ++
 .../operator/path/painting/CloseAndStrokePath.java |  82 ++
 .../painting/CloseFillEvenOddAndStrokePath.java    |  83 ++
 .../painting/CloseFillNonZeroAndStrokePath.java    |  83 ++
 .../egiz/pdf/operator/path/painting/EndPath.java   |  91 ++
 .../path/painting/FillEvenOddAndStrokePath.java    |  95 ++
 .../path/painting/FillNonZeroAndStrokePath.java    |  95 ++
 .../path/painting/FillPathEvenOddRule.java         |  94 ++
 .../painting/FillPathNonZeroWindingNumberRule.java |  95 ++
 .../pdf/operator/path/painting/StrokePath.java     |  93 ++
 41 files changed, 7436 insertions(+)
 create mode 100644 pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox/PDFBOXBackend.java
 create mode 100644 pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox/PDFBOXObject.java
 create mode 100644 pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox/placeholder/PDFBoxPlaceholderExtractor.java
 create mode 100644 pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox/placeholder/SignaturePlaceholderExtractor.java
 create mode 100644 pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox/positioning/Positioning.java
 create mode 100644 pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox/utils/PdfBoxUtils.java
 create mode 100644 pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PADESPDFBOXSigner.java
 create mode 100644 pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PDFASPDFBOXExtractorInterface.java
 create mode 100644 pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PDFASPDFBOXSignatureInterface.java
 create mode 100644 pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PdfboxSignerWrapper.java
 create mode 100644 pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/SignatureDataExtractor.java
 create mode 100644 pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/ImageObject.java
 create mode 100644 pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsTemplateCreator.java
 create mode 100644 pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsVisualSignatureBuilder.java
 create mode 100644 pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsVisualSignatureDesigner.java
 create mode 100644 pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsVisualSignatureProperties.java
 create mode 100644 pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFBoxFont.java
 create mode 100644 pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFBoxTable.java
 create mode 100644 pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PdfBoxStamper.java
 create mode 100644 pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PdfBoxVisualObject.java
 create mode 100644 pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/TableDrawUtils.java
 create mode 100644 pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/verify/pdfbox/PDFBOXVerifier.java
 create mode 100644 pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFPage.java
 create mode 100644 pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFUtilities.java
 create mode 100644 pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/PathConstructionOperatorProcessor.java
 create mode 100644 pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/PathPaintingOperatorProcessor.java
 create mode 100644 pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/ClosePath.java
 create mode 100644 pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveTo.java
 create mode 100644 pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveToReplicateFinalPoint.java
 create mode 100644 pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveToReplicateInitialPoint.java
 create mode 100644 pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/LineTo.java
 create mode 100644 pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/MoveTo.java
 create mode 100644 pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseAndStrokePath.java
 create mode 100644 pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseFillEvenOddAndStrokePath.java
 create mode 100644 pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseFillNonZeroAndStrokePath.java
 create mode 100644 pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/EndPath.java
 create mode 100644 pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillEvenOddAndStrokePath.java
 create mode 100644 pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillNonZeroAndStrokePath.java
 create mode 100644 pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillPathEvenOddRule.java
 create mode 100644 pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillPathNonZeroWindingNumberRule.java
 create mode 100644 pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/StrokePath.java

(limited to 'pdf-as-pdfbox/src/main/java')

diff --git a/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox/PDFBOXBackend.java b/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox/PDFBOXBackend.java
new file mode 100644
index 00000000..ba1e0088
--- /dev/null
+++ b/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox/PDFBOXBackend.java
@@ -0,0 +1,40 @@
+package at.gv.egiz.pdfas.lib.impl.pdfbox;
+
+import at.gv.egiz.pdfas.lib.backend.PDFASBackend;
+import at.gv.egiz.pdfas.lib.impl.pdfbox.placeholder.PDFBoxPlaceholderExtractor;
+import at.gv.egiz.pdfas.lib.impl.placeholder.PlaceholderExtractor;
+import at.gv.egiz.pdfas.lib.impl.signing.IPdfSigner;
+import at.gv.egiz.pdfas.lib.impl.signing.pdfbox.PADESPDFBOXSigner;
+import at.gv.egiz.pdfas.lib.impl.verify.VerifyBackend;
+import at.gv.egiz.pdfas.lib.impl.verify.pdfbox.PDFBOXVerifier;
+
+public class PDFBOXBackend implements PDFASBackend {
+
+	private static final String NAME = "PDFBOX_BACKEND";
+	
+	@Override
+	public String getName() {
+		return NAME;
+	}
+
+	@Override
+	public boolean usedAsDefault() {
+		return true;
+	}
+
+	@Override
+	public IPdfSigner getPdfSigner() {
+		return new PADESPDFBOXSigner();
+	}
+
+	@Override
+	public PlaceholderExtractor getPlaceholderExtractor() {
+		return new PDFBoxPlaceholderExtractor();
+	}
+
+	@Override
+	public VerifyBackend getVerifier() {
+		return new PDFBOXVerifier();
+	}
+
+}
diff --git a/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox/PDFBOXObject.java b/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox/PDFBOXObject.java
new file mode 100644
index 00000000..f80df075
--- /dev/null
+++ b/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox/PDFBOXObject.java
@@ -0,0 +1,59 @@
+package at.gv.egiz.pdfas.lib.impl.pdfbox;
+
+import java.io.IOException;
+
+import javax.activation.DataSource;
+
+import org.apache.pdfbox.pdmodel.PDDocument;
+
+import at.gv.egiz.pdfas.lib.impl.status.OperationStatus;
+import at.gv.egiz.pdfas.lib.impl.status.PDFObject;
+
+public class PDFBOXObject extends PDFObject {
+
+	private PDDocument doc;
+	
+	public PDFBOXObject(OperationStatus operationStatus) {
+		super(operationStatus);
+	}
+
+	@Override
+	protected void finalize() throws Throwable {
+		super.finalize();
+		if(doc != null) {
+			doc.close();
+		}
+	}
+	
+	public void close() {
+		if(doc != null) {
+			try {
+				doc.close();
+				//System.gc();
+			} catch(Throwable e) {
+				// ignore!
+			}
+			doc = null;
+		}
+	}
+	
+	public void setOriginalDocument(DataSource originalDocument) throws IOException {
+		this.originalDocument = originalDocument;
+		if(doc != null) {
+			doc.close();
+		}
+		this.doc = PDDocument.load(this.originalDocument.getInputStream());
+		if(this.doc != null) {
+			this.doc.getDocument().setWarnMissingClose(false);
+		}
+	}
+	
+	public PDDocument getDocument() {
+		return this.doc;
+	}
+
+	@Override
+	public String getPDFVersion() {
+		return String.valueOf(getDocument().getDocument().getVersion());
+	}
+}
diff --git a/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox/placeholder/PDFBoxPlaceholderExtractor.java b/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox/placeholder/PDFBoxPlaceholderExtractor.java
new file mode 100644
index 00000000..18099b23
--- /dev/null
+++ b/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox/placeholder/PDFBoxPlaceholderExtractor.java
@@ -0,0 +1,24 @@
+package at.gv.egiz.pdfas.lib.impl.pdfbox.placeholder;
+
+import at.gv.egiz.pdfas.common.exceptions.PdfAsException;
+import at.gv.egiz.pdfas.lib.impl.pdfbox.PDFBOXObject;
+import at.gv.egiz.pdfas.lib.impl.placeholder.PlaceholderExtractor;
+import at.gv.egiz.pdfas.lib.impl.placeholder.SignaturePlaceholderData;
+import at.gv.egiz.pdfas.lib.impl.status.PDFObject;
+
+public class PDFBoxPlaceholderExtractor implements PlaceholderExtractor {
+
+	@Override
+	public SignaturePlaceholderData extract(PDFObject doc,
+			String placeholderId, int matchMode) throws PdfAsException {
+
+		if (doc instanceof PDFBOXObject) {
+			PDFBOXObject object = (PDFBOXObject) doc;
+			return SignaturePlaceholderExtractor.extract(object.getDocument(),
+					placeholderId, matchMode);
+		}
+
+		throw new PdfAsException("INVALID STATE");
+	}
+
+}
diff --git a/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox/placeholder/SignaturePlaceholderExtractor.java b/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox/placeholder/SignaturePlaceholderExtractor.java
new file mode 100644
index 00000000..fe1c0ee7
--- /dev/null
+++ b/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox/placeholder/SignaturePlaceholderExtractor.java
@@ -0,0 +1,371 @@
+/*******************************************************************************
+ * <copyright> Copyright 2014 by E-Government Innovation Center EGIZ, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ * 
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ * 
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ ******************************************************************************/
+/**
+ * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.gv.egiz.pdfas.lib.impl.pdfbox.placeholder;
+
+import java.awt.geom.AffineTransform;
+import java.awt.geom.NoninvertibleTransformException;
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Vector;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.pdfbox.cos.COSBase;
+import org.apache.pdfbox.cos.COSName;
+import org.apache.pdfbox.exceptions.WrappedIOException;
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.pdmodel.PDPage;
+import org.apache.pdfbox.pdmodel.graphics.xobject.PDXObject;
+import org.apache.pdfbox.pdmodel.graphics.xobject.PDXObjectImage;
+import org.apache.pdfbox.util.Matrix;
+import org.apache.pdfbox.util.PDFOperator;
+import org.apache.pdfbox.util.PDFStreamEngine;
+import org.apache.pdfbox.util.ResourceLoader;
+
+import at.gv.egiz.pdfas.common.exceptions.PDFIOException;
+import at.gv.egiz.pdfas.common.exceptions.PdfAsException;
+import at.gv.egiz.pdfas.common.exceptions.PlaceholderExtractionException;
+import at.gv.egiz.pdfas.lib.impl.placeholder.SignaturePlaceholderContext;
+import at.gv.egiz.pdfas.lib.impl.placeholder.SignaturePlaceholderData;
+import at.knowcenter.wag.egov.egiz.pdf.TablePos;
+
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.BinaryBitmap;
+import com.google.zxing.DecodeHintType;
+import com.google.zxing.LuminanceSource;
+import com.google.zxing.MultiFormatReader;
+import com.google.zxing.NotFoundException;
+import com.google.zxing.ReaderException;
+import com.google.zxing.Result;
+import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
+import com.google.zxing.common.HybridBinarizer;
+
+/**
+ * Extract all relevant information from a placeholder image.
+ *
+ * @author exthex
+ *
+ */
+public class SignaturePlaceholderExtractor extends PDFStreamEngine {
+	/**
+	 * The log.
+	 */
+	private static Log log = LogFactory
+			.getLog(SignaturePlaceholderExtractor.class);
+
+	public static final String QR_PLACEHOLDER_IDENTIFIER = "PDF-AS-POS";
+	public static final int PLACEHOLDER_MATCH_MODE_STRICT = 0;
+	public static final int PLACEHOLDER_MATCH_MODE_MODERATE = 1;
+	public static final int PLACEHOLDER_MATCH_MODE_LENIENT = 2;
+
+	private List<SignaturePlaceholderData> placeholders = new Vector<SignaturePlaceholderData>();
+	private int currentPage = 0;
+
+	private SignaturePlaceholderExtractor(String placeholderId,
+			int placeholderMatchMode) throws IOException {
+		super(ResourceLoader.loadProperties(
+				"placeholder/pdfbox-reader.properties", true));
+	}
+
+	/**
+	 * Search the document for placeholder images and possibly included
+	 * additional info.<br/>
+	 * Searches only for the first placeholder page after page from top.
+	 *
+	 * @param inputStream
+	 * @return all available info from the first found placeholder.
+	 * @throws PDFDocumentException
+	 *             if the document could not be read.
+	 * @throws PlaceholderExtractionException
+	 *             if STRICT matching mode was requested and no suitable
+	 *             placeholder could be found.
+	 */
+	public static SignaturePlaceholderData extract(PDDocument doc,
+			String placeholderId, int matchMode) throws PdfAsException {
+		SignaturePlaceholderContext.setSignaturePlaceholderData(null);
+
+		SignaturePlaceholderExtractor extractor;
+		try {
+			extractor = new SignaturePlaceholderExtractor(placeholderId,
+					matchMode);
+		} catch (IOException e2) {
+			throw new PDFIOException("error.pdf.io.04", e2);
+		}
+		List<?> pages = doc.getDocumentCatalog().getAllPages();
+		Iterator<?> iter = pages.iterator();
+		int pageNr = 0;
+		while (iter.hasNext()) {
+			pageNr++;
+			PDPage page = (PDPage) iter.next();
+			try {
+				extractor.setCurrentPage(pageNr);
+				extractor.processStream(page, page.findResources(), page
+						.getContents().getStream());
+				SignaturePlaceholderData ret = matchPlaceholderPage(
+						extractor.placeholders, placeholderId, matchMode);
+				if (ret != null) {
+					SignaturePlaceholderContext
+							.setSignaturePlaceholderData(ret);
+					return ret;
+				}
+			} catch (IOException e1) {
+				throw new PDFIOException("error.pdf.io.04", e1);
+			}
+
+		}
+		if (extractor.placeholders.size() > 0) {
+			SignaturePlaceholderData ret = matchPlaceholderDocument(
+					extractor.placeholders, placeholderId, matchMode);
+			SignaturePlaceholderContext.setSignaturePlaceholderData(ret);
+			return ret;
+		}
+		// no placeholders found, apply strict mode if set
+		if (matchMode == PLACEHOLDER_MATCH_MODE_STRICT) {
+			throw new PlaceholderExtractionException("error.pdf.stamp.09");
+		}
+
+		return null;
+	}
+
+	private static SignaturePlaceholderData matchPlaceholderDocument(
+			List<SignaturePlaceholderData> placeholders, String placeholderId,
+			int matchMode) throws PlaceholderExtractionException {
+
+		if (matchMode == PLACEHOLDER_MATCH_MODE_STRICT)
+			throw new PlaceholderExtractionException("error.pdf.stamp.09");
+
+		if (placeholders.size() == 0)
+			return null;
+
+		for (int i = 0; i < placeholders.size(); i++) {
+			SignaturePlaceholderData spd = placeholders.get(i);
+			if (spd.getId() == null)
+				return spd;
+		}
+
+		if (matchMode == PLACEHOLDER_MATCH_MODE_LENIENT)
+			return placeholders.get(0);
+
+		return null;
+	}
+
+	private static SignaturePlaceholderData matchPlaceholderPage(
+			List<SignaturePlaceholderData> placeholders, String placeholderId,
+			int matchMode) {
+		if (placeholders.size() == 0)
+			return null;
+		for (int i = 0; i < placeholders.size(); i++) {
+			SignaturePlaceholderData data = placeholders.get(i);
+			if (placeholderId != null && placeholderId.equals(data.getId()))
+				return data;
+			if (placeholderId == null && data.getId() == null)
+				return data;
+		}
+		return null;
+	}
+
+	private void setCurrentPage(int pageNr) {
+		this.currentPage = pageNr;
+	}
+
+	@Override
+	protected void processOperator(PDFOperator operator, List<COSBase> arguments)
+			throws IOException {
+		String operation = operator.getOperation();
+		if (operation.equals("Do")) {
+			COSName objectName = (COSName) arguments.get(0);
+			Map<?, ?> xobjects = getResources().getXObjects();
+			PDXObject xobject = (PDXObject) xobjects.get(objectName.getName());
+			if (xobject instanceof PDXObjectImage) {
+				try {
+					PDXObjectImage image = (PDXObjectImage) xobject;
+					SignaturePlaceholderData data = checkImage(image);
+					if (data != null) {
+						PDPage page = getCurrentPage();
+						Matrix ctm = getGraphicsState()
+								.getCurrentTransformationMatrix();
+						double rotationInRadians = (page.findRotation() * Math.PI) / 180;
+
+						AffineTransform rotation = new AffineTransform();
+						rotation.setToRotation(rotationInRadians);
+						AffineTransform rotationInverse = rotation
+								.createInverse();
+						Matrix rotationInverseMatrix = new Matrix();
+						rotationInverseMatrix
+								.setFromAffineTransform(rotationInverse);
+						Matrix rotationMatrix = new Matrix();
+						rotationMatrix.setFromAffineTransform(rotation);
+
+						Matrix unrotatedCTM = ctm
+								.multiply(rotationInverseMatrix);
+
+						float x = unrotatedCTM.getXPosition();
+						float y = unrotatedCTM.getYPosition()
+								+ unrotatedCTM.getYScale();
+						float w = unrotatedCTM.getXScale();
+
+						String posString = "p:" + currentPage + ";x:" + x
+								+ ";y:" + y + ";w:" + w;
+						try {
+							data.setTablePos(new TablePos(posString));
+							data.setPlaceholderName(objectName.getName());
+							placeholders.add(data);
+						} catch (PdfAsException e) {
+							throw new WrappedIOException(e);
+						}
+					}
+				} catch (NoninvertibleTransformException e) {
+					throw new WrappedIOException(e);
+				}
+			}
+		} else {
+			super.processOperator(operator, arguments);
+		}
+	}
+
+	/**
+	 * Checks an image if it is a placeholder for a signature.
+	 *
+	 * @param image
+	 * @return
+	 * @throws IOException
+	 */
+	private SignaturePlaceholderData checkImage(PDXObjectImage image)
+			throws IOException {
+		BufferedImage bimg = image.getRGBImage();
+		if (bimg == null) {
+			String type = image.getSuffix();
+			if (type != null) {
+				type = type.toUpperCase() + " images";
+			} else {
+				type = "Image type";
+			}
+			log.info("Unable to extract image for QRCode analysis. "
+					+ type
+					+ " not supported. Add additional JAI Image filters to your classpath. Refer to https://jai.dev.java.net. Skipping image.");
+			return null;
+		}
+		if (bimg.getHeight() < 10 || bimg.getWidth() < 10) {
+			log.debug("Image too small for QRCode. Skipping image.");
+			return null;
+		}
+
+		LuminanceSource source = new BufferedImageLuminanceSource(bimg);
+		BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
+		Result result;
+		long before = System.currentTimeMillis();
+		try {
+			Hashtable<DecodeHintType, Vector<BarcodeFormat>> hints = new Hashtable<DecodeHintType, Vector<BarcodeFormat>>();
+			Vector<BarcodeFormat> formats = new Vector<BarcodeFormat>();
+			formats.add(BarcodeFormat.QR_CODE);
+			hints.put(DecodeHintType.POSSIBLE_FORMATS, formats);
+			result = new MultiFormatReader().decode(bitmap, hints);
+
+			String text = result.getText();
+			String profile = null;
+			String type = null;
+			String sigKey = null;
+			String id = null;
+			if (text != null) {
+				if (text.startsWith(QR_PLACEHOLDER_IDENTIFIER)) {
+					String[] data = text.split(";");
+					if (data.length > 1) {
+						for (int i = 1; i < data.length; i++) {
+							String kvPair = data[i];
+							String[] kv = kvPair.split("=");
+							if (kv.length != 2) {
+								log.debug("Invalid parameter in placeholder data: "
+										+ kvPair);
+							} else {
+								if (kv[0]
+										.equalsIgnoreCase(SignaturePlaceholderData.ID_KEY)) {
+									id = kv[1];
+								} else if (kv[0]
+										.equalsIgnoreCase(SignaturePlaceholderData.PROFILE_KEY)) {
+									profile = kv[1];
+								} else if (kv[0]
+										.equalsIgnoreCase(SignaturePlaceholderData.SIG_KEY_KEY)) {
+									sigKey = kv[1];
+								} else if (kv[0]
+										.equalsIgnoreCase(SignaturePlaceholderData.TYPE_KEY)) {
+									type = kv[1];
+								}
+							}
+						}
+					}
+					return new SignaturePlaceholderData(profile, type, sigKey,
+							id);
+				} else {
+					log.warn("QR-Code found but does not start with \""
+							+ QR_PLACEHOLDER_IDENTIFIER
+							+ "\". Ignoring QR placeholder.");
+				}
+			}
+		} catch (ReaderException re) {
+			if (log.isDebugEnabled()) {
+				log.debug("Could not decode - not a placeholder. needed: "
+						+ (System.currentTimeMillis() - before));
+			}
+			if (!(re instanceof NotFoundException)) {
+				if (log.isInfoEnabled()) {
+					log.info("Failed to decode image", re);
+				}
+			}
+		} catch (ArrayIndexOutOfBoundsException e) {
+			if (log.isInfoEnabled()) {
+				log.info("Failed to decode image. Probably a zxing bug", e);
+			}
+		}
+		return null;
+	}
+
+}
diff --git a/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox/positioning/Positioning.java b/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox/positioning/Positioning.java
new file mode 100644
index 00000000..4efa2148
--- /dev/null
+++ b/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox/positioning/Positioning.java
@@ -0,0 +1,237 @@
+/*******************************************************************************
+ * <copyright> Copyright 2014 by E-Government Innovation Center EGIZ, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ * 
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ * 
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ ******************************************************************************/
+package at.gv.egiz.pdfas.lib.impl.pdfbox.positioning;
+
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.pdmodel.PDPage;
+import org.apache.pdfbox.pdmodel.common.PDRectangle;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.gv.egiz.pdfas.common.exceptions.PdfAsException;
+import at.gv.egiz.pdfas.lib.impl.pdfbox.utils.PdfBoxUtils;
+import at.gv.egiz.pdfas.lib.impl.stamping.IPDFVisualObject;
+import at.knowcenter.wag.egov.egiz.pdf.PDFUtilities;
+import at.knowcenter.wag.egov.egiz.pdf.PositioningInstruction;
+import at.knowcenter.wag.egov.egiz.pdf.TablePos;
+
+/**
+ * Created with IntelliJ IDEA. User: afitzek Date: 8/29/13 Time: 4:30 PM To
+ * change this template use File | Settings | File Templates.
+ */
+public class Positioning {
+
+	private static final Logger logger = LoggerFactory
+			.getLogger(Positioning.class);
+	
+	/**
+	 * The left/right margin.
+	 */
+	public static final float SIGNATURE_MARGIN_HORIZONTAL = 50f;
+
+	/**
+	 * The top/bottom margin.
+	 */
+	public static final float SIGNATURE_MARGIN_VERTICAL = 20f;
+
+	/**
+	 * Evalutates absolute positioning and prepares the PositioningInstruction
+	 * for placing the table.
+	 *
+	 * @param pos
+	 *            The absolute positioning parameter. If null it is sought in
+	 *            the profile definition.
+	 * @param signature_type
+	 *            The profile definition of the table to be written.
+	 * @param pdfDataSource
+	 *            The pdf.
+	 * @param pdf_table
+	 *            The pdf table to be written.
+	 * @return Returns the PositioningInformation.
+	 * @throws PdfAsException
+	 *             F.e.
+	 */
+	public static PositioningInstruction determineTablePositioning(
+			TablePos pos, String signature_type, PDDocument pdfDataSource,
+			IPDFVisualObject pdf_table, boolean legacy32) throws PdfAsException {
+		return adjustSignatureTableandCalculatePosition(pdfDataSource,
+				pdf_table, pos, legacy32);
+	}
+
+	/**
+	 * Sets the width of the table according to the layout of the document and
+	 * calculates the y position where the PDFPTable should be placed.
+	 *
+	 * @param pdfDataSource
+	 *            The PDF document.
+	 * @param pdf_table
+	 *            The PDFPTable to be placed.
+	 * @return Returns the position where the PDFPTable should be placed.
+	 * @throws PdfAsException
+	 *             F.e.
+	 */
+	public static PositioningInstruction adjustSignatureTableandCalculatePosition(
+			final PDDocument pdfDataSource, IPDFVisualObject pdf_table,
+			TablePos pos, boolean legacy32) throws PdfAsException {
+		
+		PdfBoxUtils.checkPDFPermissions(pdfDataSource);
+		// get pages of currentdocument
+
+		int doc_pages = pdfDataSource.getNumberOfPages();
+		int page = doc_pages;
+		boolean make_new_page = pos.isNewPage();
+		if (!(pos.isNewPage() || pos.isPauto())) {
+			// we should posit signaturtable on this page
+
+			page = pos.getPage();
+			// System.out.println("XXXXPAGE="+page+" doc_pages="+doc_pages);
+			if (page > doc_pages) {
+				make_new_page = true;
+				page = doc_pages;
+				// throw new PDFDocumentException(227, "Page number is to big(="
+				// + page+
+				// ") cannot be parsed.");
+			}
+		}
+		
+		PDPage pdPage = (PDPage) pdfDataSource.getDocumentCatalog()
+				.getAllPages().get(page - 1);
+		PDRectangle cropBox = pdPage.getCropBox();
+
+		// fallback to MediaBox if Cropbox not available!
+		
+		if (cropBox == null) {
+			cropBox = pdPage.findCropBox();
+		}
+
+		if (cropBox == null) {
+			cropBox = pdPage.findMediaBox();
+		}
+
+		// getPagedimensions
+		// Rectangle psize = reader.getPageSizeWithRotation(page);
+		// int page_rotation = reader.getPageRotation(page);
+
+		// Integer rotation = pdPage.getRotation();
+		// int page_rotation = rotation.intValue();
+
+		float page_width = cropBox.getWidth();
+		float page_height = cropBox.getHeight();
+
+		// now we can calculate x-position
+		float pre_pos_x = SIGNATURE_MARGIN_HORIZONTAL;
+		if (!pos.isXauto()) {
+			// we do have absolute x
+			pre_pos_x = pos.getPosX();
+		}
+		// calculate width
+		// center
+		float pre_width = page_width - 2 * pre_pos_x;
+		if (!pos.isWauto()) {
+			// we do have absolute width
+			pre_width = pos.getWidth();
+			if (pos.isXauto()) { // center x
+				pre_pos_x = (page_width - pre_width) / 2;
+			}
+		}
+		final float pos_x = pre_pos_x;
+		final float width = pre_width;
+		// Signatur table dimensions are complete
+		pdf_table.setWidth(width);
+		pdf_table.fixWidth();
+		// pdf_table.setTotalWidth(width);
+		// pdf_table.setLockedWidth(true);
+
+		final float table_height = pdf_table.getHeight();
+		// now check pos_y
+		float pos_y = pos.getPosY();
+
+		// in case an absolute y position is already given OR
+		// if the table is related to an invisible signature
+		// there is no need for further calculations
+		// (fixed adding new page in case of invisible signatures)
+		if (!pos.isYauto() || table_height == 0) {
+			// we do have y-position too --> all parameters but page ok
+			if (make_new_page) {
+				page++;
+			}
+			return new PositioningInstruction(make_new_page, page, pos_x,
+					pos_y, pos.rotation);
+		}
+		// pos_y is auto
+		if (make_new_page) {
+			// ignore footer in new page
+			page++;
+			pos_y = page_height - SIGNATURE_MARGIN_VERTICAL;
+			return new PositioningInstruction(make_new_page, page, pos_x,
+					pos_y, pos.rotation);
+		}
+		// up to here no checks have to be made if Tablesize and Pagesize are
+		// fit
+		// Now we have to getfreespace in page and reguard footerline
+		float footer_line = pos.getFooterLine();
+		
+		float pre_page_length = PDFUtilities.calculatePageLength(pdfDataSource,
+				page - 1, page_height - footer_line, /* page_rotation, */
+				legacy32);
+		
+		if (pre_page_length == Float.NEGATIVE_INFINITY) {
+			// we do have an empty page or nothing in area above footerline
+			pre_page_length = page_height;
+			// no text --> SIGNATURE_BORDER
+			pos_y = page_height - SIGNATURE_MARGIN_VERTICAL;
+			if (pos_y - footer_line <= table_height) {
+				make_new_page = true;
+				if (!pos.isPauto()) {
+					// we have to correct pagenumber
+					page = pdfDataSource.getNumberOfPages();
+				}
+				page++;
+				// no text --> SIGNATURE_BORDER
+				pos_y = page_height - SIGNATURE_MARGIN_VERTICAL;
+			}
+			return new PositioningInstruction(make_new_page, page, pos_x,
+					pos_y, pos.rotation);
+		}
+		final float page_length = pre_page_length;
+		// we do have text take SIGNATURE_MARGIN
+		pos_y = page_height - page_length - SIGNATURE_MARGIN_VERTICAL;
+		if (pos_y - footer_line <= table_height) {
+			make_new_page = true;
+			if (!pos.isPauto()) {
+				// we have to correct pagenumber in case of absolute page and
+				// not enough
+				// space
+				page = pdfDataSource.getNumberOfPages();
+			}
+			page++;
+			// no text --> SIGNATURE_BORDER
+			pos_y = page_height - SIGNATURE_MARGIN_VERTICAL;
+		}
+		return new PositioningInstruction(make_new_page, page, pos_x, pos_y,
+				pos.rotation);
+
+	}
+
+}
diff --git a/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox/utils/PdfBoxUtils.java b/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox/utils/PdfBoxUtils.java
new file mode 100644
index 00000000..01501f97
--- /dev/null
+++ b/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox/utils/PdfBoxUtils.java
@@ -0,0 +1,73 @@
+package at.gv.egiz.pdfas.lib.impl.pdfbox.utils;
+
+import org.apache.pdfbox.cos.COSArray;
+import org.apache.pdfbox.cos.COSDictionary;
+import org.apache.pdfbox.cos.COSName;
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.pdmodel.encryption.AccessPermission;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.gv.egiz.pdfas.common.exceptions.PdfAsValidationException;
+
+public class PdfBoxUtils {
+	private static final Logger logger = LoggerFactory
+			.getLogger(PdfBoxUtils.class);
+	
+	public static void checkPDFPermissions(PDDocument doc)
+			throws PdfAsValidationException {
+
+		AccessPermission accessPermission = doc.getCurrentAccessPermission();
+		if (doc.isEncrypted()) {
+			throw new PdfAsValidationException("error.pdf.sig.12", null);
+		}
+
+		if (!accessPermission.isOwnerPermission()) {
+			throw new PdfAsValidationException("error.pdf.sig.12", null);
+		}
+
+	}
+
+	public static int countSignatures(PDDocument doc, String sigName) {
+		int count = 0;
+		COSDictionary trailer = doc.getDocument().getTrailer();
+		COSDictionary root = (COSDictionary) trailer
+				.getDictionaryObject(COSName.ROOT);
+		COSDictionary acroForm = (COSDictionary) root
+				.getDictionaryObject(COSName.ACRO_FORM);
+		COSArray fields = (COSArray) acroForm
+				.getDictionaryObject(COSName.FIELDS);
+		for (int i = 0; i < fields.size(); i++) {
+			COSDictionary field = (COSDictionary) fields.getObject(i);
+			String type = field.getNameAsString("FT");
+			if ("Sig".equals(type)) {
+				String name = field.getString(COSName.T);
+				if (name != null) {
+					logger.debug("Found Sig: " + name);
+					try {
+						if (name.startsWith(sigName)) {
+							String numberString = name.replace(sigName, "");
+
+							logger.debug("Found Number: " + numberString);
+
+							int SigIDX = Integer.parseInt(numberString);
+							if (SigIDX > count) {
+								count = SigIDX;
+							}
+						}
+					} catch (Throwable e) {
+						logger.info("Found a different Signature, we do not need to count this.");
+					}
+				}
+			}
+
+		}
+
+		count++;
+
+		logger.debug("Returning sig number: " + count);
+
+		return count;
+	}
+
+}
diff --git a/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PADESPDFBOXSigner.java b/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PADESPDFBOXSigner.java
new file mode 100644
index 00000000..ee9da479
--- /dev/null
+++ b/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PADESPDFBOXSigner.java
@@ -0,0 +1,626 @@
+/*******************************************************************************
+ * <copyright> Copyright 2014 by E-Government Innovation Center EGIZ, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ * 
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ * 
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ ******************************************************************************/
+package at.gv.egiz.pdfas.lib.impl.signing.pdfbox;
+
+import iaik.x509.X509Certificate;
+
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.pdfbox.cos.COSBase;
+import org.apache.pdfbox.cos.COSDictionary;
+import org.apache.pdfbox.cos.COSName;
+import org.apache.pdfbox.cos.COSString;
+import org.apache.pdfbox.exceptions.COSVisitorException;
+import org.apache.pdfbox.exceptions.SignatureException;
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.pdmodel.PDDocumentCatalog;
+import org.apache.pdfbox.pdmodel.PDPage;
+import org.apache.pdfbox.pdmodel.PDPageNode;
+import org.apache.pdfbox.pdmodel.PDResources;
+import org.apache.pdfbox.pdmodel.graphics.color.PDOutputIntent;
+import org.apache.pdfbox.pdmodel.graphics.xobject.PDJpeg;
+import org.apache.pdfbox.pdmodel.interactive.digitalsignature.PDSignature;
+import org.apache.pdfbox.pdmodel.interactive.digitalsignature.SignatureOptions;
+import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
+import org.apache.pdfbox.pdmodel.interactive.form.PDField;
+import org.apache.pdfbox.pdmodel.interactive.form.PDSignatureField;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.gv.egiz.pdfas.common.exceptions.PDFASError;
+import at.gv.egiz.pdfas.common.exceptions.PdfAsException;
+import at.gv.egiz.pdfas.common.messages.MessageResolver;
+import at.gv.egiz.pdfas.common.settings.SignatureProfileSettings;
+import at.gv.egiz.pdfas.common.utils.StreamUtils;
+import at.gv.egiz.pdfas.common.utils.TempFileHelper;
+import at.gv.egiz.pdfas.lib.api.ByteArrayDataSource;
+import at.gv.egiz.pdfas.lib.api.IConfigurationConstants;
+import at.gv.egiz.pdfas.lib.api.sign.IPlainSigner;
+import at.gv.egiz.pdfas.lib.api.sign.SignParameter;
+import at.gv.egiz.pdfas.lib.impl.ErrorExtractor;
+import at.gv.egiz.pdfas.lib.impl.SignaturePositionImpl;
+import at.gv.egiz.pdfas.lib.impl.configuration.SignatureProfileConfiguration;
+import at.gv.egiz.pdfas.lib.impl.pdfbox.PDFBOXObject;
+import at.gv.egiz.pdfas.lib.impl.pdfbox.positioning.Positioning;
+import at.gv.egiz.pdfas.lib.impl.pdfbox.utils.PdfBoxUtils;
+import at.gv.egiz.pdfas.lib.impl.placeholder.PlaceholderFilter;
+import at.gv.egiz.pdfas.lib.impl.placeholder.SignaturePlaceholderData;
+import at.gv.egiz.pdfas.lib.impl.signing.IPdfSigner;
+import at.gv.egiz.pdfas.lib.impl.signing.PDFASSignatureExtractor;
+import at.gv.egiz.pdfas.lib.impl.signing.PDFASSignatureInterface;
+import at.gv.egiz.pdfas.lib.impl.stamping.IPDFStamper;
+import at.gv.egiz.pdfas.lib.impl.stamping.IPDFVisualObject;
+import at.gv.egiz.pdfas.lib.impl.stamping.StamperFactory;
+import at.gv.egiz.pdfas.lib.impl.stamping.TableFactory;
+import at.gv.egiz.pdfas.lib.impl.stamping.ValueResolver;
+import at.gv.egiz.pdfas.lib.impl.stamping.pdfbox.PDFAsVisualSignatureProperties;
+import at.gv.egiz.pdfas.lib.impl.stamping.pdfbox.PdfBoxVisualObject;
+import at.gv.egiz.pdfas.lib.impl.status.OperationStatus;
+import at.gv.egiz.pdfas.lib.impl.status.PDFObject;
+import at.gv.egiz.pdfas.lib.impl.status.RequestedSignature;
+import at.knowcenter.wag.egov.egiz.pdf.PositioningInstruction;
+import at.knowcenter.wag.egov.egiz.pdf.TablePos;
+import at.knowcenter.wag.egov.egiz.table.Table;
+
+public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants {
+
+	private static final Logger logger = LoggerFactory
+			.getLogger(PADESPDFBOXSigner.class);
+
+	public void signPDF(PDFObject genericPdfObject,
+			RequestedSignature requestedSignature,
+			PDFASSignatureInterface genericSigner) throws PdfAsException {
+		String fisTmpFile = null;
+
+		if (!(genericPdfObject instanceof PDFBOXObject)) {
+			// tODO:
+			throw new PdfAsException();
+		}
+
+		PDFBOXObject pdfObject = (PDFBOXObject) genericPdfObject;
+
+		if (!(genericSigner instanceof PDFASPDFBOXSignatureInterface)) {
+			// tODO:
+			throw new PdfAsException();
+		}
+
+		PDFASPDFBOXSignatureInterface signer = (PDFASPDFBOXSignatureInterface) genericSigner;
+
+		TempFileHelper helper = pdfObject.getStatus().getTempFileHelper();
+		PDDocument doc = null;
+		try {
+			fisTmpFile = helper.getStaticFilename();
+
+			// write to temporary file
+			FileOutputStream fos = new FileOutputStream(new File(fisTmpFile));
+			IOUtils.copy(pdfObject.getOriginalDocument().getInputStream(), fos);
+
+			FileInputStream fis = new FileInputStream(new File(fisTmpFile));
+
+			doc = pdfObject.getDocument();
+
+			PDSignature signature = new PDSignature();
+			signature.setFilter(COSName.getPDFName(signer.getPDFFilter())); // default
+																			// filter
+			signature
+					.setSubFilter(COSName.getPDFName(signer.getPDFSubFilter()));
+
+			SignatureProfileSettings signatureProfileSettings = TableFactory
+					.createProfile(requestedSignature.getSignatureProfileID(),
+							pdfObject.getStatus().getSettings());
+
+			ValueResolver resolver = new ValueResolver(requestedSignature,
+					pdfObject.getStatus());
+			String signerName = resolver.resolve("SIG_SUBJECT",
+					signatureProfileSettings.getValue("SIG_SUBJECT"),
+					signatureProfileSettings);
+
+			signature.setName(signerName);
+			signature.setSignDate(Calendar.getInstance());
+			String signerReason = signatureProfileSettings.getSigningReason();
+
+			if (signerReason == null) {
+				signerReason = "PAdES Signature";
+			}
+
+			signature.setReason(signerReason);
+			logger.debug("Signing reason: " + signerReason);
+
+			logger.debug("Signing @ "
+					+ signer.getSigningDate().getTime().toString());
+			// the signing date, needed for valid signature
+			// signature.setSignDate(signer.getSigningDate());
+
+			signer.setPDSignature(signature);
+			SignatureOptions options = new SignatureOptions();
+
+			// Is visible Signature
+			if (requestedSignature.isVisual()) {
+				logger.info("Creating visual siganture block");
+
+				SignatureProfileConfiguration signatureProfileConfiguration = pdfObject
+						.getStatus().getSignatureProfileConfiguration(
+								requestedSignature.getSignatureProfileID());
+
+				SignaturePlaceholderData signaturePlaceholderData = PlaceholderFilter
+						.checkPlaceholderSignature(pdfObject.getStatus(),
+								pdfObject.getStatus().getSettings());
+
+				TablePos tablePos = null;
+
+				if (signaturePlaceholderData != null) {
+					// Placeholder found!
+
+					if (signaturePlaceholderData.getProfile() != null) {
+						requestedSignature
+								.setSignatureProfileID(signaturePlaceholderData
+										.getProfile());
+					}
+
+					tablePos = signaturePlaceholderData.getTablePos();
+				}
+
+				if (tablePos == null) {
+					// ================================================================
+					// PositioningStage (visual) -> find position or use fixed
+					// position
+
+					String posString = pdfObject.getStatus().getSignParamter()
+							.getSignaturePosition();
+
+					TablePos signaturePos = null;
+
+					String signaturePosString = signatureProfileConfiguration
+							.getDefaultPositioning();
+
+					if (signaturePosString != null) {
+						logger.debug("using signature Positioning: "
+								+ signaturePos);
+						signaturePos = new TablePos(signaturePosString);
+					}
+
+					logger.debug("using Positioning: " + posString);
+
+					if (posString != null) {
+						// Merge Signature Position
+						tablePos = new TablePos(posString, signaturePos);
+					} else {
+						// Fallback to signature Position!
+						tablePos = signaturePos;
+					}
+
+					if (tablePos == null) {
+						// Last Fallback default position
+						tablePos = new TablePos();
+					}
+				}
+				boolean legacy32Position = signatureProfileConfiguration
+						.getLegacy32Positioning();
+
+				// create Table describtion
+				Table main = TableFactory.createSigTable(
+						signatureProfileSettings, MAIN, pdfObject.getStatus(),
+						requestedSignature);
+
+				IPDFStamper stamper = StamperFactory
+						.createDefaultStamper(pdfObject.getStatus()
+								.getSettings());
+
+				IPDFVisualObject visualObject = stamper.createVisualPDFObject(
+						pdfObject, main);
+
+				/*
+				 * PDDocument originalDocument = PDDocument .load(new
+				 * ByteArrayInputStream(pdfObject.getStatus()
+				 * .getPdfObject().getOriginalDocument()));
+				 */
+
+				PositioningInstruction positioningInstruction = Positioning
+						.determineTablePositioning(tablePos, "", doc,
+								visualObject, legacy32Position);
+
+				SignaturePositionImpl position = new SignaturePositionImpl();
+				position.setX(positioningInstruction.getX());
+				position.setY(positioningInstruction.getY());
+				position.setPage(positioningInstruction.getPage());
+				position.setHeight(visualObject.getHeight());
+				position.setWidth(visualObject.getWidth());
+
+				requestedSignature.setSignaturePosition(position);
+
+				PDFAsVisualSignatureProperties properties = new PDFAsVisualSignatureProperties(
+						pdfObject.getStatus().getSettings(), pdfObject,
+						(PdfBoxVisualObject) visualObject,
+						positioningInstruction);
+
+				properties.buildSignature();
+
+				/*
+				 * ByteArrayOutputStream sigbos = new ByteArrayOutputStream();
+				 * sigbos.write(StreamUtils.inputStreamToByteArray(properties
+				 * .getVisibleSignature())); sigbos.close();
+				 */
+
+				if (signaturePlaceholderData != null) {
+					// Placeholder found!
+					// replace placeholder
+					InputStream is = PADESPDFBOXSigner.class
+							.getResourceAsStream("/placeholder/empty.jpg");
+					PDJpeg img = new PDJpeg(doc, is);
+					img.getCOSObject().setNeedToBeUpdate(true);
+
+					PDDocumentCatalog root = doc.getDocumentCatalog();
+					PDPageNode rootPages = root.getPages();
+					List<PDPage> kids = new ArrayList<PDPage>();
+					rootPages.getAllKids(kids);
+					int pageNumber = positioningInstruction.getPage();
+					rootPages.getAllKids(kids);
+					PDPage page = kids.get(pageNumber);
+
+					logger.info("Placeholder name: "
+							+ signaturePlaceholderData.getPlaceholderName());
+					COSDictionary xobjectsDictionary = (COSDictionary) page
+							.findResources().getCOSDictionary()
+							.getDictionaryObject(COSName.XOBJECT);
+					xobjectsDictionary.setItem(
+							signaturePlaceholderData.getPlaceholderName(), img);
+					xobjectsDictionary.setNeedToBeUpdate(true);
+					page.findResources().getCOSObject().setNeedToBeUpdate(true);
+					logger.info("Placeholder name: "
+							+ signaturePlaceholderData.getPlaceholderName());
+				}
+
+				if (positioningInstruction.isMakeNewPage()) {
+					int last = doc.getNumberOfPages() - 1;
+					PDDocumentCatalog root = doc.getDocumentCatalog();
+					PDPageNode rootPages = root.getPages();
+					List<PDPage> kids = new ArrayList<PDPage>();
+					rootPages.getAllKids(kids);
+					PDPage lastPage = kids.get(last);
+					rootPages.getCOSObject().setNeedToBeUpdate(true);
+					PDPage p = new PDPage(lastPage.findMediaBox());
+					p.setResources(new PDResources());
+
+					doc.addPage(p);
+				}
+
+				if (signatureProfileSettings.isPDFA()) {
+					PDDocumentCatalog root = doc.getDocumentCatalog();
+					COSBase base = root.getCOSDictionary().getItem(
+							COSName.OUTPUT_INTENTS);
+					if (base == null) {
+						InputStream colorProfile = PDDocumentCatalog.class
+								.getResourceAsStream("/icm/sRGB Color Space Profile.icm");
+						try {
+							PDOutputIntent oi = new PDOutputIntent(doc,
+									colorProfile);
+							oi.setInfo("sRGB IEC61966-2.1");
+							oi.setOutputCondition("sRGB IEC61966-2.1");
+							oi.setOutputConditionIdentifier("sRGB IEC61966-2.1");
+							oi.setRegistryName("http://www.color.org");
+
+							root.addOutputIntent(oi);
+							root.getCOSObject().setNeedToBeUpdate(true);
+							logger.info("added Output Intent");
+						} catch (Throwable e) {
+							e.printStackTrace();
+							throw new PdfAsException(
+									"Failed to add Output Intent", e);
+						}
+					}
+				}
+
+				// if (signatureProfileSettings.isPDFA()) { // Check for PDF-UA
+				// PDDocumentCatalog root = doc.getDocumentCatalog();
+				// PDStructureTreeRoot treeRoot = root.getStructureTreeRoot();
+				// if (treeRoot != null) { // Handle as PDF-UA
+				// logger.info("Tree Root: {}", treeRoot.toString());
+				// PDStructureElement docElement = PDFBoxTaggingUtils
+				// .getDocumentElement(treeRoot);
+				// PDStructureElement sigBlock = new PDStructureElement(
+				// "Table", docElement);
+				// root.getCOSObject().setNeedToBeUpdate(true);
+				// docElement.getCOSObject().setNeedToBeUpdate(true);
+				// treeRoot.getCOSObject().setNeedToBeUpdate(true);
+				// sigBlock.setTitle("Signature Table");
+				// }
+				// }
+
+				options.setPreferedSignatureSize(0x1000);
+				options.setPage(positioningInstruction.getPage());
+				options.setVisualSignature(properties.getVisibleSignature());
+			}
+
+			doc.addSignature(signature, signer, options);
+
+			String sigFieldName = signatureProfileSettings.getSignFieldValue();
+
+			if (sigFieldName == null) {
+				sigFieldName = "PDF-AS Signatur";
+			}
+
+			int count = PdfBoxUtils.countSignatures(doc, sigFieldName);
+
+			sigFieldName = sigFieldName + count;
+
+			PDAcroForm acroFormm = doc.getDocumentCatalog().getAcroForm();
+			if (acroFormm != null) {
+				@SuppressWarnings("unchecked")
+				List<PDField> fields = acroFormm.getFields();
+				PDSignatureField signatureField = null;
+
+				if (fields != null) {
+					for (PDField pdField : fields) {
+						if (pdField instanceof PDSignatureField) {
+							if (((PDSignatureField) pdField).getSignature()
+									.getDictionary()
+									.equals(signature.getDictionary())) {
+								signatureField = (PDSignatureField) pdField;
+							}
+						}
+					}
+				} else {
+					logger.warn("Failed to name Signature Field! [Cannot find Field list in acroForm!]");
+				}
+
+				if (signatureField != null) {
+					signatureField.setPartialName(sigFieldName);
+				}
+			} else {
+				logger.warn("Failed to name Signature Field! [Cannot find acroForm!]");
+			}
+
+			if (requestedSignature.isVisual()) {
+
+				// if(requestedSignature.getSignaturePosition().)
+				/*
+				 * PDAcroForm acroForm = doc.getDocumentCatalog().getAcroForm();
+				 * if (acroForm != null) {
+				 * 
+				 * @SuppressWarnings("unchecked") List<PDField> fields =
+				 * acroForm.getFields(); PDSignatureField signatureField = null;
+				 * 
+				 * if (fields != null) { for (PDField pdField : fields) { if
+				 * (pdField instanceof PDSignatureField) { if
+				 * (((PDSignatureField) pdField).getSignature() .getDictionary()
+				 * .equals(signature.getDictionary())) { signatureField =
+				 * (PDSignatureField) pdField; } } } } else { logger.warn(
+				 * "Failed to apply rotation! [Cannot find Field list in acroForm!]"
+				 * ); }
+				 * 
+				 * if (signatureField != null) { if (signatureField.getWidget()
+				 * != null) { if (signatureField.getWidget()
+				 * .getAppearanceCharacteristics() == null) {
+				 * PDAppearanceCharacteristicsDictionary dict = new
+				 * PDAppearanceCharacteristicsDictionary( new COSDictionary());
+				 * signatureField.getWidget()
+				 * .setAppearanceCharacteristics(dict); }
+				 * 
+				 * if (signatureField.getWidget()
+				 * .getAppearanceCharacteristics() != null) {
+				 * signatureField.getWidget() .getAppearanceCharacteristics()
+				 * .setRotation(90); } } } else { logger.warn(
+				 * "Failed to apply rotation! [Cannot find signature Field!]");
+				 * } } else {
+				 * logger.warn("Failed to apply rotation! [Cannot find acroForm!]"
+				 * ); }
+				 */
+			}
+
+			// pdfbox patched (FIS -> IS)
+			doc.saveIncremental(fis, fos);
+			fis.close();
+			fos.flush();
+			fos.close();
+			fos = null;
+
+			fis = new FileInputStream(new File(fisTmpFile));
+
+			// write to resulting output stream
+			// ByteArrayOutputStream bos = new ByteArrayOutputStream();
+			// bos.write();
+			// bos.close();
+
+			pdfObject
+					.setSignedDocument(StreamUtils.inputStreamToByteArray(fis));
+			fis.close();
+			fis = null;
+			System.gc();
+
+			helper.deleteFile(fisTmpFile);
+
+		} catch (IOException e) {
+			logger.error(MessageResolver.resolveMessage("error.pdf.sig.01"), e);
+			throw new PdfAsException("error.pdf.sig.01", e);
+		} catch (SignatureException e) {
+			logger.error(MessageResolver.resolveMessage("error.pdf.sig.01"), e);
+			throw new PdfAsException("error.pdf.sig.01", e);
+		} catch (COSVisitorException e) {
+			logger.error(MessageResolver.resolveMessage("error.pdf.sig.01"), e);
+			throw new PdfAsException("error.pdf.sig.01", e);
+		} finally {
+			if (doc != null) {
+				try {
+					doc.close();
+				} catch (IOException e) {
+					logger.debug("Failed to close COS Doc!", e);
+					// Ignore
+				}
+			}
+			logger.debug("Signature done!");
+
+		}
+	}
+
+	@Override
+	public PDFObject buildPDFObject(OperationStatus operationStatus) {
+		return new PDFBOXObject(operationStatus);
+	}
+
+	@Override
+	public PDFASSignatureInterface buildSignaturInterface(IPlainSigner signer,
+			SignParameter parameters, RequestedSignature requestedSignature) {
+		return new PdfboxSignerWrapper(signer, parameters, requestedSignature);
+	}
+
+	@Override
+	public PDFASSignatureExtractor buildBlindSignaturInterface(
+			X509Certificate certificate, String filter, String subfilter,
+			Calendar date) {
+		return new SignatureDataExtractor(certificate, filter, subfilter, date);
+	}
+
+	@Override
+	public void checkPDFPermissions(PDFObject genericPdfObject)
+			throws PdfAsException {
+		if (!(genericPdfObject instanceof PDFBOXObject)) {
+			// tODO:
+			throw new PdfAsException();
+		}
+
+		PDFBOXObject pdfObject = (PDFBOXObject) genericPdfObject;
+		PdfBoxUtils.checkPDFPermissions(pdfObject.getDocument());
+	}
+
+	@Override
+	public byte[] rewritePlainSignature(byte[] plainSignature) {
+		String signature = new COSString(plainSignature).getHexString();
+		byte[] pdfSignature = signature.getBytes();
+		return pdfSignature;
+	}
+
+	@Override
+	public Image generateVisibleSignaturePreview(SignParameter parameter,
+			java.security.cert.X509Certificate cert, int resolution,
+			OperationStatus status, RequestedSignature requestedSignature)
+			throws PDFASError {
+		try {
+			PDFBOXObject pdfObject = (PDFBOXObject) status.getPdfObject();
+
+			PDDocument origDoc = new PDDocument();
+			origDoc.addPage(new PDPage(PDPage.PAGE_SIZE_A4));
+			ByteArrayOutputStream baos = new ByteArrayOutputStream();
+			origDoc.save(baos);
+			baos.close();
+
+			pdfObject.setOriginalDocument(new ByteArrayDataSource(baos
+					.toByteArray()));
+
+			SignatureProfileSettings signatureProfileSettings = TableFactory
+					.createProfile(requestedSignature.getSignatureProfileID(),
+							pdfObject.getStatus().getSettings());
+
+			// create Table describtion
+			Table main = TableFactory.createSigTable(signatureProfileSettings,
+					MAIN, pdfObject.getStatus(), requestedSignature);
+
+			IPDFStamper stamper = StamperFactory.createDefaultStamper(pdfObject
+					.getStatus().getSettings());
+
+			IPDFVisualObject visualObject = stamper.createVisualPDFObject(
+					pdfObject, main);
+
+			SignatureProfileConfiguration signatureProfileConfiguration = pdfObject
+					.getStatus().getSignatureProfileConfiguration(
+							requestedSignature.getSignatureProfileID());
+
+			String signaturePosString = signatureProfileConfiguration
+					.getDefaultPositioning();
+			PositioningInstruction positioningInstruction = null;
+			if (signaturePosString != null) {
+				positioningInstruction = Positioning.determineTablePositioning(
+						new TablePos(signaturePosString), "", origDoc,
+						visualObject, false);
+			} else {
+				positioningInstruction = Positioning.determineTablePositioning(
+						new TablePos(), "", origDoc, visualObject, false);
+			}
+
+			origDoc.close();
+
+			SignaturePositionImpl position = new SignaturePositionImpl();
+			position.setX(positioningInstruction.getX());
+			position.setY(positioningInstruction.getY());
+			position.setPage(positioningInstruction.getPage());
+			position.setHeight(visualObject.getHeight());
+			position.setWidth(visualObject.getWidth());
+
+			requestedSignature.setSignaturePosition(position);
+
+			PDFAsVisualSignatureProperties properties = new PDFAsVisualSignatureProperties(
+					pdfObject.getStatus().getSettings(), pdfObject,
+					(PdfBoxVisualObject) visualObject, positioningInstruction);
+
+			properties.buildSignature();
+			PDDocument visualDoc = PDDocument.load(properties
+					.getVisibleSignature());
+			// PDPageable pageable = new PDPageable(visualDoc);
+			List<PDPage> pages = new ArrayList<PDPage>();
+			visualDoc.getDocumentCatalog().getPages().getAllKids(pages);
+
+			PDPage firstPage = pages.get(0);
+
+			float stdRes = 72;
+			float targetRes = resolution;
+			float factor = targetRes / stdRes;
+
+			BufferedImage outputImage = firstPage.convertToImage(
+					BufferedImage.TYPE_4BYTE_ABGR, (int) targetRes);
+
+			BufferedImage cutOut = new BufferedImage(
+					(int) (position.getWidth() * factor),
+					(int) (position.getHeight() * factor),
+					BufferedImage.TYPE_4BYTE_ABGR);
+
+			Graphics2D graphics = (Graphics2D) cutOut.getGraphics();
+
+			graphics.drawImage(outputImage, 0, 0, cutOut.getWidth(), cutOut
+					.getHeight(), (int) (1 * factor), (int) (outputImage
+					.getHeight() - ((position.getHeight() + 1) * factor)),
+					(int) ((1 + position.getWidth()) * factor),
+					(int) (outputImage.getHeight()
+							- ((position.getHeight() + 1) * factor) + (position
+							.getHeight() * factor)), null);
+			return cutOut;
+		} catch (PdfAsException e) {
+			logger.error("PDF-AS  Exception", e);
+			throw ErrorExtractor.searchPdfAsError(e);
+		} catch (Throwable e) {
+			logger.error("Throwable  Exception", e);
+			throw ErrorExtractor.searchPdfAsError(e);
+		}
+	}
+}
diff --git a/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PDFASPDFBOXExtractorInterface.java b/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PDFASPDFBOXExtractorInterface.java
new file mode 100644
index 00000000..2a2ac4b1
--- /dev/null
+++ b/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PDFASPDFBOXExtractorInterface.java
@@ -0,0 +1,7 @@
+package at.gv.egiz.pdfas.lib.impl.signing.pdfbox;
+
+import at.gv.egiz.pdfas.lib.impl.signing.PDFASSignatureExtractor;
+
+public interface PDFASPDFBOXExtractorInterface extends PDFASSignatureExtractor, PDFASPDFBOXSignatureInterface {
+
+}
diff --git a/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PDFASPDFBOXSignatureInterface.java b/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PDFASPDFBOXSignatureInterface.java
new file mode 100644
index 00000000..54eaaf54
--- /dev/null
+++ b/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PDFASPDFBOXSignatureInterface.java
@@ -0,0 +1,10 @@
+package at.gv.egiz.pdfas.lib.impl.signing.pdfbox;
+
+import org.apache.pdfbox.pdmodel.interactive.digitalsignature.PDSignature;
+import org.apache.pdfbox.pdmodel.interactive.digitalsignature.SignatureInterface;
+
+import at.gv.egiz.pdfas.lib.impl.signing.PDFASSignatureInterface;
+
+public interface PDFASPDFBOXSignatureInterface extends PDFASSignatureInterface, SignatureInterface {
+	public void setPDSignature(PDSignature signature);
+}
diff --git a/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PdfboxSignerWrapper.java b/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PdfboxSignerWrapper.java
new file mode 100644
index 00000000..cad7536e
--- /dev/null
+++ b/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PdfboxSignerWrapper.java
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ * <copyright> Copyright 2014 by E-Government Innovation Center EGIZ, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ * 
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ * 
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ ******************************************************************************/
+package at.gv.egiz.pdfas.lib.impl.signing.pdfbox;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Calendar;
+
+import org.apache.pdfbox.exceptions.SignatureException;
+import org.apache.pdfbox.pdmodel.interactive.digitalsignature.PDSignature;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.gv.egiz.pdfas.common.exceptions.PdfAsException;
+import at.gv.egiz.pdfas.common.exceptions.PdfAsWrappedIOException;
+import at.gv.egiz.pdfas.common.utils.PDFUtils;
+import at.gv.egiz.pdfas.common.utils.StreamUtils;
+import at.gv.egiz.pdfas.lib.api.sign.IPlainSigner;
+import at.gv.egiz.pdfas.lib.api.sign.SignParameter;
+import at.gv.egiz.pdfas.lib.impl.status.RequestedSignature;
+
+public class PdfboxSignerWrapper implements PDFASPDFBOXSignatureInterface {
+
+	private static final Logger logger = LoggerFactory
+			.getLogger(PdfboxSignerWrapper.class);
+
+	private IPlainSigner signer;
+	private PDSignature signature;
+	private int[] byteRange;
+	private Calendar date;
+	private SignParameter parameters;
+	private RequestedSignature requestedSignature;
+
+	public PdfboxSignerWrapper(IPlainSigner signer, SignParameter parameters, RequestedSignature requestedSignature) {
+		this.signer = signer;
+		this.date = Calendar.getInstance();
+		this.parameters = parameters;
+		this.requestedSignature = requestedSignature;
+	}
+
+	public byte[] sign(InputStream inputStream) throws SignatureException,
+			IOException {
+		byte[] data = StreamUtils.inputStreamToByteArray(inputStream);
+		byteRange = PDFUtils.extractSignatureByteRange(data);
+		int[] byteRange2 = signature.getByteRange();
+		logger.debug("Byte Range 2: " + byteRange2);
+		try {
+			logger.debug("Signing with Pdfbox Wrapper");
+			byte[] signature = signer.sign(data, byteRange, this.parameters, this.requestedSignature);
+			return signature;
+		} catch (PdfAsException e) {
+			throw new PdfAsWrappedIOException(e);
+		}
+	}
+
+	public int[] getByteRange() {
+		return byteRange;
+	}
+
+	public String getPDFSubFilter() {
+		return this.signer.getPDFSubFilter();
+	}
+
+	public String getPDFFilter() {
+		return this.signer.getPDFFilter();
+	}
+
+	public void setPDSignature(PDSignature signature) {
+		this.signature = signature;
+	}
+
+	public Calendar getSigningDate() {
+		return this.date;
+	}
+}
diff --git a/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/SignatureDataExtractor.java b/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/SignatureDataExtractor.java
new file mode 100644
index 00000000..5e3d1085
--- /dev/null
+++ b/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/SignatureDataExtractor.java
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * <copyright> Copyright 2014 by E-Government Innovation Center EGIZ, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ * 
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ * 
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ ******************************************************************************/
+package at.gv.egiz.pdfas.lib.impl.signing.pdfbox;
+
+import iaik.x509.X509Certificate;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Calendar;
+
+import org.apache.pdfbox.exceptions.SignatureException;
+import org.apache.pdfbox.pdmodel.interactive.digitalsignature.PDSignature;
+
+import at.gv.egiz.pdfas.common.utils.StreamUtils;
+import at.gv.egiz.pdfas.lib.impl.signing.PDFASSignatureInterface;
+
+public class SignatureDataExtractor implements PDFASPDFBOXExtractorInterface {
+
+	protected X509Certificate certificate;
+	protected byte[] signatureData;
+	
+	protected String pdfSubFilter;
+	protected String pdfFilter;
+	protected PDSignature signature;
+	protected int[] byteRange;
+	protected Calendar date;
+	
+	public SignatureDataExtractor(X509Certificate certificate, 
+			String filter, String subfilter, Calendar date) {
+		this.certificate = certificate;
+		this.pdfFilter = filter;
+		this.pdfSubFilter = subfilter;
+		this.date = date;
+	}
+	
+	public X509Certificate getCertificate() {
+		return certificate;
+	}
+
+	public String getPDFSubFilter() {
+		return this.pdfSubFilter;
+	}
+
+	public String getPDFFilter() {
+		return this.pdfFilter;
+	}
+
+	public byte[] getSignatureData() {
+		return this.signatureData;
+	}
+
+	public byte[] sign(InputStream content) throws SignatureException,
+			IOException {
+		signatureData = StreamUtils.inputStreamToByteArray(content);
+		byteRange = this.signature.getByteRange();
+		return new byte[] { 0 };
+	}
+
+	public void setPDSignature(PDSignature signature) {
+		this.signature = signature;
+	}
+
+	public int[] getByteRange() {
+		return byteRange;
+	}
+
+	public Calendar getSigningDate() {
+		return this.date;
+	}
+	
+	
+	
+}
diff --git a/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/ImageObject.java b/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/ImageObject.java
new file mode 100644
index 00000000..f8ec2073
--- /dev/null
+++ b/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/ImageObject.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * <copyright> Copyright 2014 by E-Government Innovation Center EGIZ, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ * 
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ * 
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ ******************************************************************************/
+package at.gv.egiz.pdfas.lib.impl.stamping.pdfbox;
+
+import org.apache.pdfbox.pdmodel.graphics.xobject.PDXObjectImage;
+
+public class ImageObject {
+	private PDXObjectImage image;
+	private float width;
+	private float height;
+	
+	public ImageObject(PDXObjectImage image, float width, float height) {
+		this.image = image;
+		this.width = width;
+		this.height = height;
+	}
+
+	public PDXObjectImage getImage() {
+		return image;
+	}
+
+	public void setImage(PDXObjectImage image) {
+		this.image = image;
+	}
+
+	public float getWidth() {
+		return width;
+	}
+
+	public void setWidth(float width) {
+		this.width = width;
+	}
+
+	public float getHeight() {
+		return height;
+	}
+
+	public void setHeight(float height) {
+		this.height = height;
+	}
+
+}
diff --git a/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsTemplateCreator.java b/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsTemplateCreator.java
new file mode 100644
index 00000000..feacc52d
--- /dev/null
+++ b/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsTemplateCreator.java
@@ -0,0 +1,170 @@
+/*******************************************************************************
+ * <copyright> Copyright 2014 by E-Government Innovation Center EGIZ, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ * 
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ * 
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ ******************************************************************************/
+package at.gv.egiz.pdfas.lib.impl.stamping.pdfbox;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.pdfbox.exceptions.COSVisitorException;
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.pdmodel.PDPage;
+import org.apache.pdfbox.pdmodel.PDResources;
+import org.apache.pdfbox.pdmodel.common.PDRectangle;
+import org.apache.pdfbox.pdmodel.common.PDStream;
+import org.apache.pdfbox.pdmodel.graphics.xobject.PDXObjectForm;
+import org.apache.pdfbox.pdmodel.interactive.digitalsignature.visible.PDFTemplateCreator;
+import org.apache.pdfbox.pdmodel.interactive.digitalsignature.visible.PDFTemplateStructure;
+import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
+import org.apache.pdfbox.pdmodel.interactive.form.PDSignatureField;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.gv.egiz.pdfas.common.exceptions.PdfAsException;
+
+public class PDFAsTemplateCreator extends PDFTemplateCreator {
+
+	PDFAsVisualSignatureBuilder pdfBuilder;
+    private static final Logger logger = LoggerFactory.getLogger(PDFAsTemplateCreator.class);
+	
+	public PDFAsTemplateCreator(PDFAsVisualSignatureBuilder bookBuilder) {
+		super(bookBuilder);
+		this.pdfBuilder = bookBuilder;
+	}
+
+	
+	public InputStream buildPDF(PDFAsVisualSignatureDesigner properties)
+			throws IOException, PdfAsException {
+		logger.debug("pdf building has been started");
+        PDFTemplateStructure pdfStructure = pdfBuilder.getStructure();
+
+        // we create array of [Text, ImageB, ImageC, ImageI]
+        this.pdfBuilder.createProcSetArray();
+        
+        //create page
+        this.pdfBuilder.createPage(properties);
+        PDPage page = pdfStructure.getPage();
+
+        //create template
+        this.pdfBuilder.createTemplate(page);
+        PDDocument template = pdfStructure.getTemplate();
+        
+        //create /AcroForm
+        this.pdfBuilder.createAcroForm(template);
+        PDAcroForm acroForm = pdfStructure.getAcroForm();
+
+        // AcroForm contains singature fields
+        this.pdfBuilder.createSignatureField(acroForm);
+        PDSignatureField pdSignatureField = pdfStructure.getSignatureField();
+        
+        // create signature
+        this.pdfBuilder.createSignature(pdSignatureField, page, properties.getSignatureFieldName());
+       
+        // that is /AcroForm/DR entry
+        this.pdfBuilder.createAcroFormDictionary(acroForm, pdSignatureField);
+        
+        // create AffineTransform
+        this.pdfBuilder.createAffineTransform(properties.getAffineTransformParams());
+        //AffineTransform transform = pdfStructure.getAffineTransform();
+       
+        // rectangle, formatter, image. /AcroForm/DR/XObject contains that form
+        this.pdfBuilder.createSignatureRectangle(pdSignatureField, properties, properties.getRotation());
+        this.pdfBuilder.createFormaterRectangle(properties.getFormaterRectangleParams());
+        PDRectangle formater = pdfStructure.getFormaterRectangle();
+        
+        //this.pdfBuilder.createSignatureImage(template, properties.getImageStream());
+
+        // create form stream, form and  resource. 
+        this.pdfBuilder.createHolderFormStream(template);
+        PDStream holderFormStream = pdfStructure.getHolderFormStream();
+        this.pdfBuilder.createHolderFormResources();
+        PDResources holderFormResources = pdfStructure.getHolderFormResources();
+        this.pdfBuilder.createHolderForm(holderFormResources, holderFormStream, formater);
+        
+        // that is /AP entry the appearance dictionary.
+        this.pdfBuilder.createAppearanceDictionary(pdfStructure.getHolderForm(), pdSignatureField, 
+        		properties.getRotation());
+        
+        // inner formstream, form and resource (hlder form containts inner form)
+        this.pdfBuilder.createInnerFormStreamPdfAs(template);
+        this.pdfBuilder.createInnerFormResource();
+        PDResources innerFormResource = pdfStructure.getInnerFormResources();
+        this.pdfBuilder.createInnerForm(innerFormResource, pdfStructure.getInnterFormStream(), formater);
+        PDXObjectForm innerForm = pdfStructure.getInnerForm();
+       
+        // inner form must be in the holder form as we wrote
+        this.pdfBuilder.insertInnerFormToHolerResources(innerForm, holderFormResources);
+        
+        //  Image form is in this structure: /AcroForm/DR/FRM0/Resources/XObject/n0
+        //this.pdfBuilder.createImageFormStream(template);
+        //PDStream imageFormStream = pdfStructure.getImageFormStream();
+        //this.pdfBuilder.createImageFormResources();
+        //PDResources imageFormResources = pdfStructure.getImageFormResources();
+        //this.pdfBuilder.createImageForm(imageFormResources, innerFormResource, imageFormStream, formater, transform,
+        //        pdfStructure.getJpedImage());
+       
+        // now inject procSetArray
+        /*this.pdfBuilder.injectProcSetArray(innerForm, page, innerFormResource, imageFormResources, holderFormResources,
+                pdfStructure.getProcSet());*/
+        this.pdfBuilder.injectProcSetArray(innerForm, page, innerFormResource, null, holderFormResources,
+                pdfStructure.getProcSet());
+        
+
+        /*String imgFormName = pdfStructure.getImageFormName();
+        String imgName = pdfStructure.getImageName();*/
+        String innerFormName = pdfStructure.getInnerFormName();
+
+        // now create Streams of AP
+        /*this.pdfBuilder.injectAppearanceStreams(holderFormStream, imageFormStream, imageFormStream, imgFormName,
+                imgName, innerFormName, properties);*/
+        this.pdfBuilder.injectAppearanceStreams(holderFormStream, null, null, null,
+        		null, innerFormName, properties);
+        this.pdfBuilder.createVisualSignature(template);
+        this.pdfBuilder.createWidgetDictionary(pdSignatureField, holderFormResources);
+        
+        ByteArrayInputStream in = null;
+        try
+        {
+        	//COSDocument doc = pdfStructure.getVisualSignature();
+        	//doc.
+            //in = pdfStructure.getTemplateAppearanceStream();
+        	ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        	template.save(baos);
+        	baos.close();
+        	in = new ByteArrayInputStream(baos.toByteArray());
+        }
+        catch (COSVisitorException e)
+        {
+            logger.error("COSVisitorException: can't get apereance stream ", e);
+        }
+        logger.debug("stream returning started, size= " + in.available());
+        
+        // we must close the document
+        template.close();
+        
+        // return result of the stream 
+        return in;
+	}
+}
diff --git a/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsVisualSignatureBuilder.java b/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsVisualSignatureBuilder.java
new file mode 100644
index 00000000..e3ee19f6
--- /dev/null
+++ b/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsVisualSignatureBuilder.java
@@ -0,0 +1,994 @@
+/*******************************************************************************
+ * <copyright> Copyright 2014 by E-Government Innovation Center EGIZ, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ * 
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ * 
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ ******************************************************************************/
+package at.gv.egiz.pdfas.lib.impl.stamping.pdfbox;
+
+import java.awt.Color;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.imageio.ImageIO;
+
+import org.apache.pdfbox.cos.COSArray;
+import org.apache.pdfbox.cos.COSDictionary;
+import org.apache.pdfbox.cos.COSName;
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.pdmodel.PDPage;
+import org.apache.pdfbox.pdmodel.PDResources;
+import org.apache.pdfbox.pdmodel.common.PDRectangle;
+import org.apache.pdfbox.pdmodel.common.PDStream;
+import org.apache.pdfbox.pdmodel.edit.PDPageContentStream;
+import org.apache.pdfbox.pdmodel.font.PDFont;
+import org.apache.pdfbox.pdmodel.font.PDType1Font;
+import org.apache.pdfbox.pdmodel.graphics.xobject.PDJpeg;
+import org.apache.pdfbox.pdmodel.graphics.xobject.PDPixelMap;
+import org.apache.pdfbox.pdmodel.graphics.xobject.PDXObjectForm;
+import org.apache.pdfbox.pdmodel.graphics.xobject.PDXObjectImage;
+import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceDictionary;
+import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceStream;
+import org.apache.pdfbox.pdmodel.interactive.digitalsignature.PDSignature;
+import org.apache.pdfbox.pdmodel.interactive.digitalsignature.visible.PDVisibleSigBuilder;
+import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
+import org.apache.pdfbox.pdmodel.interactive.form.PDField;
+import org.apache.pdfbox.pdmodel.interactive.form.PDSignatureField;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.gv.egiz.pdfas.common.exceptions.PdfAsException;
+import at.gv.egiz.pdfas.common.settings.ISettings;
+import at.gv.egiz.pdfas.common.utils.ImageUtils;
+import at.knowcenter.wag.egov.egiz.table.Entry;
+import at.knowcenter.wag.egov.egiz.table.Style;
+
+public class PDFAsVisualSignatureBuilder extends PDVisibleSigBuilder {
+
+	private static final Logger logger = LoggerFactory
+			.getLogger(PDFAsVisualSignatureBuilder.class);
+
+	private void drawDebugLine(PDPageContentStream contentStream, float x,
+			float y, float width, float height) {
+		try {
+			contentStream.setStrokingColor(Color.RED);
+			contentStream.drawLine(x, y, x + width, y);
+			contentStream.setStrokingColor(Color.BLUE);
+			contentStream.drawLine(x, y, x, y - height);
+			contentStream.setStrokingColor(Color.GREEN);
+			contentStream.drawLine(x + width, y, x + width, y - height);
+			contentStream.setStrokingColor(Color.ORANGE);
+			contentStream.drawLine(x, y - height, x + width, y - height);
+
+			contentStream.setStrokingColor(Color.BLACK);
+		} catch (Throwable e) {
+			e.printStackTrace();
+		}
+	}
+
+	private void drawDebugPadding(PDPageContentStream contentStream, float x,
+			float y, float padding, float width, float height) {
+		try {
+			contentStream.setStrokingColor(Color.RED);
+			contentStream.drawLine(x, y, x + padding, y - padding);
+			contentStream.drawLine(x + width, y, x + width - padding, y
+					- padding);
+			contentStream.drawLine(x + width, y - height, x + width - padding,
+					y - height + padding);
+			contentStream.drawLine(x, y - height, x + padding, y - height
+					+ padding);
+			contentStream.setStrokingColor(Color.BLACK);
+		} catch (Throwable e) {
+			e.printStackTrace();
+		}
+	}
+
+	private void drawTable(PDPage page, PDPageContentStream contentStream,
+			float x, float y, float width, float height,
+			PDFBoxTable abstractTable, PDDocument doc, boolean subtable)
+			throws IOException, PdfAsException {
+
+		final int rows = abstractTable.getRowCount();
+		final int cols = abstractTable.getColCount();
+		float[] colsSizes = abstractTable.getColsRelativeWith();
+		int max_cols = abstractTable.getColCount();
+		float padding = abstractTable.getPadding();
+		float fontSize = PDFBoxFont.defaultFontSize;
+		PDFont textFont = PDFBoxFont.defaultFont;
+		if (colsSizes == null) {
+			colsSizes = new float[max_cols];
+			// set the column ratio for all columns to 1
+			for (int cols_idx = 0; cols_idx < colsSizes.length; cols_idx++) {
+				colsSizes[cols_idx] = 1;
+			}
+		}
+
+		logger.debug("Drawing Table:");
+		abstractTable.dumpTable();
+
+		if (abstractTable.getBGColor() != null) {
+			contentStream.setNonStrokingColor(abstractTable.getBGColor());
+			contentStream.fillRect(x, y, abstractTable.getWidth(),
+					abstractTable.getHeight());
+			contentStream.setNonStrokingColor(Color.BLACK);
+		}
+		float total = 0;
+
+		for (int cols_idx = 0; cols_idx < colsSizes.length; cols_idx++) {
+			total += colsSizes[cols_idx];
+		}
+
+		for (int cols_idx = 0; cols_idx < colsSizes.length; cols_idx++) {
+			colsSizes[cols_idx] = (colsSizes[cols_idx] / total)
+					* abstractTable.getWidth();
+		}
+
+		for (int cols_idx = 0; cols_idx < colsSizes.length; cols_idx++) {
+			logger.debug("Col: " + cols_idx + " : " + colsSizes[cols_idx]);
+		}
+
+		float border = abstractTable.style.getBorder();
+		contentStream.setLineWidth(border);
+
+		float tableHeight = abstractTable.getHeight();
+		float tableWidth = abstractTable.getWidth();
+		final float colWidth = tableWidth / (float) cols;
+
+		// draw if boarder > 0
+		if (border != 0) {
+
+			float nexty = y + tableHeight;
+			float lasty = nexty;
+			for (int i = 0; i < rows; i++) {
+				ArrayList<Entry> row = abstractTable.getRow(i);
+				// Draw row border!
+				logger.debug("ROW LINE: {} {} {} {}", x, nexty, x + width,
+						nexty);
+				contentStream.drawLine(x, nexty, x + width, nexty);
+				lasty = nexty;
+				if (i < abstractTable.getRowHeights().length) {
+					// nexty -= abstractTable.getRowHeights()[i] + padding * 2;
+					nexty -= abstractTable.getRowHeights()[i];
+				}
+
+				// if (subtable && i + 1 ==
+				// abstractTable.getRowHeights().length) {
+				// nexty -= padding;
+				// }
+
+				float nextx = x;
+				float ypos = y;
+				float yheight = y + abstractTable.getHeight();
+				if (subtable) {
+					// ypos -= padding;
+					yheight = y + abstractTable.getHeight();
+				}
+
+				for (int j = 0; j < row.size(); j++) {
+					Entry cell = (Entry) row.get(j);
+
+					if (subtable && j == cols) {
+						continue;
+					}
+					logger.debug("COL LINE: {} {} {} {}", nextx, ypos, nextx,
+							yheight);
+					contentStream.drawLine(nextx, lasty, nextx, nexty);
+					for (int k = 0; k < cell.getColSpan(); k++) {
+						if (k + j < colsSizes.length) {
+							nextx += (colsSizes != null) ? colsSizes[k + j]
+									: colWidth;
+						}
+					}
+				}
+				if (!subtable) {
+					contentStream.drawLine(nextx, lasty, nextx, nexty);
+				}
+			}
+
+			contentStream.drawLine(x, nexty, x + tableWidth, nexty);
+
+		}
+
+		float textx = x;
+		float texty = y + tableHeight;
+		for (int i = 0; i < abstractTable.getRowCount(); i++) {
+			ArrayList<Entry> row = abstractTable.getRow(i);
+			for (int j = 0; j < row.size(); j++) {
+				Entry cell = (Entry) row.get(j);
+
+				Style inherit_style = Style.doInherit(cell.getStyle(),
+						abstractTable.style);
+				cell.setStyle(inherit_style);
+
+				// if(subtable) {
+				drawDebugPadding(contentStream, textx, texty, padding,
+						((colsSizes != null) ? colsSizes[j] : colWidth),
+						abstractTable.getRowHeights()[i]);
+				// }
+				// if(true) {
+				// textx += (colsSizes != null) ? colsSizes[j] : colWidth;
+				// continue;
+				// }
+
+				if (cell.getType() == Entry.TYPE_CAPTION
+						|| cell.getType() == Entry.TYPE_VALUE) {
+
+					if (cell.getType() == Entry.TYPE_CAPTION) {
+						textFont = abstractTable.getFont().getFont(doc);
+						fontSize = abstractTable.getFont().getFontSize();
+					} else if (cell.getType() == Entry.TYPE_VALUE) {
+						textFont = abstractTable.getValueFont().getFont(doc);
+						fontSize = abstractTable.getValueFont().getFontSize();
+					}
+
+					String text = (String) cell.getValue();
+
+					// COSName name = COSName.getPDFName("ANDI_TAG!");
+					// contentStream.beginMarkedContentSequence(COSName.ALT,
+					// name);
+					String fontName = textFont.equals(PDType1Font.COURIER) ? "COURIER"
+							: "HELVETICA";
+
+					float fheight = textFont.getFontDescriptor().getCapHeight()
+							/ 1000 * fontSize;
+
+					String[] tlines = text.split("\n");
+					float textHeight = fontSize * tlines.length;
+
+					Style cellStyle = cell.getStyle();
+					String valign = null;
+					String halign = null;
+
+					if (cell.getType() == Entry.TYPE_CAPTION
+							&& cellStyle != null) {
+						valign = cellStyle.getVAlign();
+						halign = cellStyle.getHAlign();
+					} else if (cell.getType() == Entry.TYPE_VALUE
+							&& cellStyle != null) {
+						valign = cellStyle.getValueVAlign();
+						halign = cellStyle.getValueHAlign();
+					}
+					float ty = texty - padding;
+					float tx = textx + padding;
+					if (Style.BOTTOM.equals(valign)) {
+						float bottom_offset = abstractTable.getRowHeights()[i]
+								- textHeight;
+						ty -= bottom_offset;
+					} else if (Style.MIDDLE.equals(valign)) {
+						float bottom_offset = abstractTable.getRowHeights()[i]
+								- textHeight;
+						bottom_offset = bottom_offset / 2.0f;
+						ty -= bottom_offset;
+					}
+
+					float columnWidth = (colsSizes != null) ? colsSizes[j]
+							: colWidth;
+					float maxWidth = 0;
+					for (int k = 0; k < tlines.length; k++) {
+						float lineWidth;
+						if (textFont instanceof PDType1Font) {
+							lineWidth = textFont.getStringWidth(tlines[k])
+									/ 1000.0f * fontSize;
+						} else {
+							float fwidth = textFont
+									.getStringWidth("abcdefghijklmnopqrstuvwxyz ")
+									/ 1000.0f * fontSize;
+							fwidth = fwidth
+									/ (float) "abcdefghijklmnopqrstuvwxyz"
+											.length();
+							lineWidth = tlines[k].length() * fwidth;
+						}
+
+						if (maxWidth < lineWidth) {
+							maxWidth = lineWidth;
+						}
+					}
+
+					if (Style.CENTER.equals(halign)) {
+						float offset = columnWidth - maxWidth - 2 * padding;
+						if (offset > 0) {
+							offset = offset / 2.0f;
+							tx += offset;
+						}
+					} else if (Style.RIGHT.equals(halign)) {
+						float offset = columnWidth - maxWidth - 2 * padding;
+						if (offset > 0) {
+							tx += offset;
+						}
+					}
+
+					drawDebugLine(contentStream, tx, ty, maxWidth, textHeight);
+
+					contentStream.beginText();
+
+					if (innerFormResources.getFonts().containsValue(textFont)) {
+						String fontID = getFontID(textFont);
+						logger.debug("Using Font: " + fontID);
+						contentStream.appendRawCommands("/" + fontID + " "
+								+ fontSize + " Tf\n");
+					} else {
+						contentStream.setFont(textFont, fontSize);
+					}
+
+					logger.debug("Writing: " + tx + " : " + (ty - fheight)
+							+ " = " + text + " as " + cell.getType() + " w "
+							+ fontName);
+					contentStream.moveTextPositionByAmount(tx, (ty - fheight));
+
+					if (text.contains("\n")) {
+						String[] lines = text.split("\n");
+						contentStream.appendRawCommands(fontSize + " TL\n");
+						for (int k = 0; k < lines.length; k++) {
+							contentStream.drawString(lines[k]);
+							if (k < lines.length - 1) {
+								contentStream.appendRawCommands("T*\n");
+							}
+						}
+					} else {
+						contentStream.drawString(text);
+					}
+					contentStream.endText();
+					// contentStream.endMarkedContentSequence();
+				} else if (cell.getType() == Entry.TYPE_IMAGE) {
+					String img_ref = (String) cell.getValue();
+					if (!images.containsKey(img_ref)) {
+						logger.error("Image not prepared! : " + img_ref);
+						throw new PdfAsException("Image not prepared! : "
+								+ img_ref);
+					}
+					ImageObject image = images.get(img_ref);
+					PDXObjectImage pdImage = image.getImage();
+
+					float imgx = textx + padding;
+					float hoffset = ((colsSizes != null) ? colsSizes[j]
+							: colWidth) - image.getWidth();
+					if (cell.getStyle().getImageVAlign() != null
+							&& cell.getStyle().getImageVAlign()
+									.equals(Style.CENTER)) {
+						hoffset = hoffset / 2.0f;
+						imgx += hoffset;
+					} else if (cell.getStyle().getImageHAlign() != null
+							&& cell.getStyle().getImageHAlign()
+									.equals(Style.RIGHT)) {
+						imgx += hoffset;
+					}
+
+					float imgy = texty - padding;
+					float voffset = abstractTable.getRowHeights()[i]
+							- image.getHeight();
+					if (cell.getStyle().getImageVAlign() != null
+							&& cell.getStyle().getImageVAlign()
+									.equals(Style.MIDDLE)) {
+						voffset = voffset / 2.0f;
+						imgy -= voffset;
+					} else if (cell.getStyle().getImageVAlign() != null
+							&& cell.getStyle().getImageVAlign()
+									.equals(Style.BOTTOM)) {
+						imgy -= voffset;
+					}
+
+					drawDebugLine(contentStream, imgx, imgy, image.getWidth(),
+							image.getHeight());
+
+					logger.debug("Image: " + imgx + " : "
+							+ (imgy - image.getHeight()));
+					contentStream.drawXObject(pdImage, imgx,
+							imgy - image.getHeight(), image.getWidth(),
+							image.getHeight());
+					// contentStream.endMarkedContentSequence();
+
+				} else if (cell.getType() == Entry.TYPE_TABLE) {
+
+					float tableY = texty - abstractTable.getRowHeights()[i];
+					float tableX = textx;
+					// texty = texty - padding;
+					PDFBoxTable tbl_value = (PDFBoxTable) cell.getValue();
+
+					Style inherit_styletab = Style.doInherit(
+							abstractTable.style, cell.getStyle());
+					tbl_value.table.setStyle(inherit_styletab);
+
+					logger.debug("Table: " + tableX + " : " + tableY);
+					// logger.debug("Table height: " + );
+					TableDrawUtils.drawTable(page, contentStream, tableX,
+							tableY, (colsSizes != null) ? colsSizes[j]
+									: colWidth,
+							abstractTable.getRowHeights()[i], tbl_value, doc,
+							true, innerFormResources, images, settings);
+				}
+				textx += (colsSizes != null) ? colsSizes[j] : colWidth;
+			}
+			// if (i + 1 < abstractTable.getRowHeights().length) {
+			logger.debug("Row {} from {} - {} - {} = {}", i, texty,
+					abstractTable.getRowHeights()[i], padding * 2, texty
+							- (abstractTable.getRowHeights()[i]));
+			texty -= abstractTable.getRowHeights()[i];
+			// texty = texty - abstractTable.getRowHeights()[i + 1] - padding
+			// * 2;
+			// texty = texty - abstractTable.getRowHeights()[i] - padding
+			// * 2;
+			// }
+			textx = x;
+		}
+	}
+
+	private void drawTable2(PDPage page, PDPageContentStream contentStream,
+			float x, float y, float width, float height,
+			PDFBoxTable abstractTable, PDDocument doc, boolean subtable) {
+
+	}
+
+	private PDFAsVisualSignatureProperties properties;
+	private PDFAsVisualSignatureDesigner designer;
+	private ISettings settings;
+	private PDResources innerFormResources;
+	private Map<String, ImageObject> images = new HashMap<String, ImageObject>();
+
+	private String getFontID(PDFont font) {
+		Iterator<java.util.Map.Entry<String, PDFont>> it = innerFormResources
+				.getFonts().entrySet().iterator();
+		while (it.hasNext()) {
+			java.util.Map.Entry<String, PDFont> entry = it.next();
+			if (entry.getValue().equals(font)) {
+				return entry.getKey();
+			}
+		}
+		return "";
+	}
+
+	public PDFAsVisualSignatureBuilder(
+			PDFAsVisualSignatureProperties properties, ISettings settings,
+			PDFAsVisualSignatureDesigner designer) {
+		this.properties = properties;
+		this.settings = settings;
+		this.designer = designer;
+	}
+
+	@Override
+	public void createProcSetArray() {
+		COSArray procSetArr = new COSArray();
+		procSetArr.add(COSName.getPDFName("PDF"));
+		procSetArr.add(COSName.getPDFName("Text"));
+		procSetArr.add(COSName.getPDFName("ImageC"));
+		procSetArr.add(COSName.getPDFName("ImageB"));
+		procSetArr.add(COSName.getPDFName("ImageI"));
+		getStructure().setProcSet(procSetArr);
+		logger.debug("ProcSet array has been created");
+	}
+
+	public void createMyPage(PDFAsVisualSignatureDesigner properties) {
+		PDPage page = properties.getSignaturePage();
+		if (page == null) {
+			page = new PDPage();
+			page.setMediaBox(new PDRectangle(properties.getPageWidth(),
+					properties.getPageHeight()));
+
+		}
+		getStructure().setPage(page);
+		logger.info("PDF page has been created");
+	}
+
+	@Override
+	public void createTemplate(PDPage page) throws IOException {
+		PDDocument template = new PDDocument();
+
+		template.addPage(page);
+		getStructure().setTemplate(template);
+	}
+
+	private void readTableResources(PDFBoxTable table, PDDocument template)
+			throws PdfAsException, IOException {
+
+		float[] colsSizes = table.getColsRelativeWith();
+		int max_cols = table.getColCount();
+		float padding = table.getPadding();
+		if (colsSizes == null) {
+			colsSizes = new float[max_cols];
+			// set the column ratio for all columns to 1
+			for (int cols_idx = 0; cols_idx < colsSizes.length; cols_idx++) {
+				colsSizes[cols_idx] = 1;
+			}
+		}
+
+		logger.debug("TOTAL Width: " + table.getWidth());
+
+		float total = 0;
+
+		for (int cols_idx = 0; cols_idx < colsSizes.length; cols_idx++) {
+			total += colsSizes[cols_idx];
+		}
+
+		for (int cols_idx = 0; cols_idx < colsSizes.length; cols_idx++) {
+			colsSizes[cols_idx] = (colsSizes[cols_idx] / total)
+					* table.getWidth();
+		}
+
+		for (int cols_idx = 0; cols_idx < colsSizes.length; cols_idx++) {
+			logger.debug("Col: " + cols_idx + " : " + colsSizes[cols_idx]);
+		}
+
+		/*
+		 * if(!addedFonts.contains(table.getFont().getFont(null))) { PDFont font
+		 * = table.getFont().getFont(template); addedFonts.add(font);
+		 * innerFormResources.addFont(font); }
+		 * 
+		 * if(!addedFonts.contains(table.getValueFont().getFont(null))) { PDFont
+		 * font = table.getValueFont().getFont(template); addedFonts.add(font);
+		 * innerFormResources.addFont(font); }
+		 */
+
+		for (int i = 0; i < table.getRowCount(); i++) {
+			ArrayList<Entry> row = table.getRow(i);
+			for (int j = 0; j < row.size(); j++) {
+				Entry cell = (Entry) row.get(j);
+				if (cell.getType() == Entry.TYPE_IMAGE) {
+					String img_ref = (String) cell.getValue();
+					if (!images.containsKey(img_ref)) {
+						File img_file = new File(img_ref);
+						if (!img_file.isAbsolute()) {
+							logger.debug("Image file declaration is relative. Prepending path of resources directory.");
+							logger.debug("Image Location: "
+									+ settings.getWorkingDirectory()
+									+ File.separator + img_ref);
+							img_file = new File(settings.getWorkingDirectory()
+									+ File.separator + img_ref);
+						} else {
+							logger.debug("Image file declaration is absolute. Skipping file relocation.");
+						}
+
+						if (!img_file.exists()) {
+							logger.debug("Image file \""
+									+ img_file.getCanonicalPath()
+									+ "\" doesn't exist.");
+							throw new PdfAsException("error.pdf.stamp.04");
+						}
+
+						BufferedImage img = null;
+						try {
+							img = ImageIO.read(img_file);
+						} catch (IOException e) {
+							throw new PdfAsException("error.pdf.stamp.04", e);
+						}
+
+						float width = colsSizes[j];
+						float height = table.getRowHeights()[i] + padding * 2;
+
+						float iwidth = (int) Math.floor((double) width);
+						iwidth -= 2 * padding;
+
+						float iheight = (int) Math.floor((double) height);
+						iheight -= 2 * padding;
+
+						float origWidth = (float) img.getWidth();
+						float origHeight = (float) img.getHeight();
+
+						if (table.style != null) {
+							if (table.style.getImageScaleToFit() != null) {
+								iwidth = table.style.getImageScaleToFit()
+										.getWidth();
+								iheight = table.style.getImageScaleToFit()
+										.getHeight();
+							}
+						}
+
+						float wfactor = iwidth / origWidth;
+						float hfactor = iheight / origHeight;
+						float scaleFactor = wfactor;
+						if (hfactor < wfactor) {
+							scaleFactor = hfactor;
+						}
+
+						iwidth = (float) Math
+								.floor((double) (scaleFactor * origWidth));
+						iheight = (float) Math
+								.floor((double) (scaleFactor * origHeight));
+						
+						logger.debug("Scaling image to: " + iwidth + " x "
+								+ iheight);
+
+						if (img.getAlphaRaster() == null
+								&& img.getColorModel().hasAlpha()) {
+							img = ImageUtils.removeAlphaChannel(img);
+						}
+
+						PDXObjectImage pdImage = new PDPixelMap(template, img);
+
+						ImageObject image = new ImageObject(pdImage, iwidth,
+								iheight);
+						images.put(img_ref, image);
+						innerFormResources.addXObject(pdImage, "Im");
+					}
+				} else if (cell.getType() == Entry.TYPE_TABLE) {
+					PDFBoxTable tbl_value = (PDFBoxTable) cell.getValue();
+					readTableResources(tbl_value, template);
+				}
+			}
+		}
+	}
+
+	public void createInnerFormStreamPdfAs(PDDocument template) throws PdfAsException {
+		try {
+
+			// Hint we have to create all PDXObjectImages before creating the
+			// PDPageContentStream
+			// only PDFbox developers know why ...
+			//if (getStructure().getPage().getResources() != null) {
+			//	innerFormResources = getStructure().getPage().getResources();
+			//} else {
+				innerFormResources = new PDResources();
+				getStructure().getPage().setResources(innerFormResources);
+			//}
+			readTableResources(properties.getMainTable(), template);
+
+			PDPageContentStream stream = new PDPageContentStream(template,
+					getStructure().getPage());
+			// stream.setFont(PDType1Font.COURIER, 5);
+			TableDrawUtils.drawTable(getStructure().getPage(), stream, 1, 1,
+					designer.getWidth(), designer.getHeight(),
+					properties.getMainTable(), template, false,
+					innerFormResources, images, settings);
+			stream.close();
+			PDStream innterFormStream = getStructure().getPage().getContents();
+			getStructure().setInnterFormStream(innterFormStream);
+			logger.debug("Strean of another form (inner form - it would be inside holder form) has been created");
+
+		} catch (Throwable e) {
+			logger.error("Failed to create visual signature block", e);
+			throw new PdfAsException("Failed to create visual signature block", e);
+		}
+	}
+
+	@Override
+	public void injectProcSetArray(PDXObjectForm innerForm, PDPage page,
+			PDResources innerFormResources, PDResources imageFormResources,
+			PDResources holderFormResources, COSArray procSet) {
+		innerForm.getResources().getCOSDictionary()
+				.setItem(COSName.PROC_SET, procSet); //
+		page.getCOSDictionary().setItem(COSName.PROC_SET, procSet);
+		innerFormResources.getCOSDictionary()
+				.setItem(COSName.PROC_SET, procSet);
+		/*
+		 * imageFormResources.getCOSDictionary() .setItem(COSName.PROC_SET,
+		 * procSet);
+		 */
+		holderFormResources.getCOSDictionary().setItem(COSName.PROC_SET,
+				procSet);
+		logger.debug("inserted ProcSet to PDF");
+	}
+
+	public void injectAppearanceStreams(PDStream holderFormStream,
+			PDStream innterFormStream, PDStream imageFormStream,
+			String imageObjectName, String imageName, String innerFormName,
+			PDFAsVisualSignatureDesigner properties) throws IOException {
+
+		// 100 means that document width is 100% via the rectangle. if rectangle
+		// is 500px, images 100% is 500px.
+		// String imgFormComment = "q "+imageWidthSize+ " 0 0 50 0 0 cm /" +
+		// imageName + " Do Q\n" + builder.toString();
+		/*
+		 * String imgFormComment = "q " + 100 + " 0 0 50 0 0 cm /" + imageName +
+		 * " Do Q\n";
+		 */
+		double m00 = getStructure().getAffineTransform().getScaleX();
+		double m10 = getStructure().getAffineTransform().getShearY();
+		double m01 = getStructure().getAffineTransform().getShearX();
+		double m11 = getStructure().getAffineTransform().getScaleY();
+		double m02 = getStructure().getAffineTransform().getTranslateX();
+		double m12 = getStructure().getAffineTransform().getTranslateY();
+
+		String holderFormComment = "q " + m00 + " " + m10 + " " + m01 + " "
+				+ m11 + " " + m02 + " " + m12 + " cm /" + innerFormName
+				+ " Do Q \n";
+		
+		logger.debug("Holder Form Stream: " + holderFormComment);
+		
+		// String innerFormComment = "q 1 0 0 1 0 0 cm /" + imageObjectName +
+		// " Do Q\n";
+		String innerFormComment = getStructure().getInnterFormStream()
+				.getInputStreamAsString();
+
+		//logger.debug("Inner Form Stream: " + innerFormComment);
+
+		// appendRawCommands(getStructure().getInnterFormStream().createOutputStream(),
+		// getStructure().getInnterFormStream().getInputStreamAsString());
+
+		appendRawCommands(getStructure().getHolderFormStream()
+				.createOutputStream(), holderFormComment);
+		appendRawCommands(getStructure().getInnterFormStream()
+				.createOutputStream(), innerFormComment);
+		// appendRawCommands(getStructure().getImageFormStream().createOutputStream(),
+		// imgFormComment);
+		logger.debug("Injected apereance stream to pdf");
+
+	}
+
+	public void createPage(PDFAsVisualSignatureDesigner properties) {
+		PDPage page = new PDPage();
+		page.setMediaBox(new PDRectangle(properties.getPageWidth(), properties
+				.getPageHeight()));
+		getStructure().setPage(page);
+		logger.debug("PDF page has been created");
+	}
+
+	public void createAcroForm(PDDocument template) {
+		PDAcroForm theAcroForm = new PDAcroForm(template);
+		template.getDocumentCatalog().setAcroForm(theAcroForm);
+		getStructure().setAcroForm(theAcroForm);
+		logger.debug("Acro form page has been created");
+
+	}
+
+	public void createSignatureField(PDAcroForm acroForm) throws IOException {
+		PDSignatureField sf = new PDSignatureField(acroForm);
+		getStructure().setSignatureField(sf);
+		logger.debug("Signature field has been created");
+	}
+
+	public void createSignature(PDSignatureField pdSignatureField, PDPage page,
+			String signatureName) throws IOException {
+		PDSignature pdSignature = new PDSignature();
+		pdSignatureField.setSignature(pdSignature);
+		pdSignatureField.getWidget().setPage(page);
+		page.getAnnotations().add(pdSignatureField.getWidget());
+		pdSignature.setName(signatureName);
+		pdSignature.setByteRange(new int[] { 0, 0, 0, 0 });
+		pdSignature.setContents(new byte[4096]);
+		getStructure().setPdSignature(pdSignature);
+		logger.debug("PDSignatur has been created");
+	}
+
+	public void createAcroFormDictionary(PDAcroForm acroForm,
+			PDSignatureField signatureField) throws IOException {
+		@SuppressWarnings("unchecked")
+		List<PDField> acroFormFields = acroForm.getFields();
+		COSDictionary acroFormDict = acroForm.getDictionary();
+		acroFormDict.setDirect(true);
+		acroFormDict.setInt(COSName.SIG_FLAGS, 3);
+		acroFormFields.add(signatureField);
+		acroFormDict.setString(COSName.DA, "/sylfaen 0 Tf 0 g");
+		getStructure().setAcroFormFields(acroFormFields);
+		getStructure().setAcroFormDictionary(acroFormDict);
+		logger.debug("AcroForm dictionary has been created");
+	}
+
+	public void createSignatureRectangle(PDSignatureField signatureField,
+			PDFAsVisualSignatureDesigner properties, float degrees)
+			throws IOException {
+
+		PDRectangle rect = new PDRectangle();
+
+		Point2D upSrc = new Point2D.Float();
+		upSrc.setLocation(properties.getxAxis() + properties.getWidth(),
+				properties.getPageHeight() - properties.getyAxis());
+
+		Point2D llSrc = new Point2D.Float();
+		llSrc.setLocation(properties.getxAxis(), properties.getPageHeight()
+				- properties.getyAxis() - properties.getHeight());
+		AffineTransform transform = new AffineTransform();
+		transform.setToIdentity();
+		if (degrees % 360 != 0) {
+			transform.setToRotation(Math.toRadians(degrees), llSrc.getX(),
+					llSrc.getY());
+		}
+		Point2D upDst = new Point2D.Float();
+		transform.transform(upSrc, upDst);
+
+		Point2D llDst = new Point2D.Float();
+		transform.transform(llSrc, llDst);
+
+		rect.setUpperRightX((float) upDst.getX());
+		rect.setUpperRightY((float) upDst.getY());
+		rect.setLowerLeftY((float) llDst.getY());
+		rect.setLowerLeftX((float) llDst.getX());
+		logger.debug("rectangle of signature has been created: {}",
+				rect.toString());
+		signatureField.getWidget().setRectangle(rect);
+		getStructure().setSignatureRectangle(rect);
+		logger.debug("rectangle of signature has been created");
+	}
+
+	public void createAffineTransform(float[] params) {
+		AffineTransform transform = new AffineTransform(params[0], params[1],
+				params[2], params[3], params[4], params[5]);
+		// transform.rotate(90);
+		getStructure().setAffineTransform(transform);
+		logger.debug("Matrix has been added");
+	}
+
+	public void createSignatureImage(PDDocument template,
+			InputStream inputStream) throws IOException {
+		PDJpeg img = new PDJpeg(template, inputStream);
+		getStructure().setJpedImage(img);
+		logger.debug("Visible Signature Image has been created");
+		// pdfStructure.setTemplate(template);
+		inputStream.close();
+
+	}
+
+	public void createFormaterRectangle(float[] params) {
+
+		PDRectangle formrect = new PDRectangle();
+		float[] translated = new float[4];
+		getStructure().getAffineTransform().transform(params, 0, translated, 0,
+				2);
+
+		formrect.setUpperRightX(translated[0]);
+		formrect.setUpperRightY(translated[1]);
+		formrect.setLowerLeftX(translated[2]);
+		formrect.setLowerLeftY(translated[3]);
+
+		getStructure().setFormaterRectangle(formrect);
+		logger.debug("Formater rectangle has been created");
+
+	}
+
+	public void createHolderFormStream(PDDocument template) {
+		PDStream holderForm = new PDStream(template);
+		getStructure().setHolderFormStream(holderForm);
+		logger.debug("Holder form Stream has been created");
+	}
+
+	public void createHolderFormResources() {
+		PDResources holderFormResources = new PDResources();
+		getStructure().setHolderFormResources(holderFormResources);
+		logger.debug("Holder form resources have been created");
+
+	}
+
+	public void createHolderForm(PDResources holderFormResources,
+			PDStream holderFormStream, PDRectangle formrect) {
+
+		PDXObjectForm holderForm = new PDXObjectForm(holderFormStream);
+		holderForm.setResources(holderFormResources);
+		holderForm.setBBox(formrect);
+		holderForm.setFormType(1);
+		getStructure().setHolderForm(holderForm);
+		logger.debug("Holder form has been created");
+
+	}
+
+	public void createAppearanceDictionary(PDXObjectForm holderForml,
+			PDSignatureField signatureField, float degrees) throws IOException {
+
+		PDAppearanceDictionary appearance = new PDAppearanceDictionary();
+		appearance.getCOSObject().setDirect(true);
+
+		PDAppearanceStream appearanceStream = new PDAppearanceStream(
+				holderForml.getCOSStream());
+		AffineTransform transform = new AffineTransform();
+		transform.setToIdentity();
+		transform.rotate(Math.toRadians(degrees));
+		appearanceStream.setMatrix(transform);
+		appearance.setNormalAppearance(appearanceStream);
+		signatureField.getWidget().setAppearance(appearance);
+
+		getStructure().setAppearanceDictionary(appearance);
+		logger.debug("PDF appereance Dictionary has been created");
+
+	}
+
+	public void createInnerFormResource() {
+		getStructure().setInnerFormResources(innerFormResources);
+		logger.debug("Resources of another form (inner form - it would be inside holder form) have been created");
+	}
+
+	public void createInnerForm(PDResources innerFormResources,
+			PDStream innerFormStream, PDRectangle formrect) {
+		PDXObjectForm innerForm = new PDXObjectForm(innerFormStream);
+		innerForm.setResources(innerFormResources);
+		innerForm.setBBox(formrect);
+		innerForm.setFormType(1);
+		getStructure().setInnerForm(innerForm);
+		logger.debug("Another form (inner form - it would be inside holder form) have been created");
+
+	}
+
+	public void insertInnerFormToHolerResources(PDXObjectForm innerForm,
+			PDResources holderFormResources) {
+		String name = holderFormResources.addXObject(innerForm, "FRM");
+		getStructure().setInnerFormName(name);
+		logger.debug("Alerady inserted inner form  inside holder form");
+	}
+
+	public void createImageFormStream(PDDocument template) {
+		PDStream imageFormStream = new PDStream(template);
+		getStructure().setImageFormStream(imageFormStream);
+		logger.debug("Created image form Stream");
+	}
+
+	public void createImageFormResources() {
+		PDResources imageFormResources = new PDResources();
+		getStructure().setImageFormResources(imageFormResources);
+		logger.debug("Created image form Resources");
+	}
+
+	public void createImageForm(PDResources imageFormResources,
+			PDResources innerFormResource, PDStream imageFormStream,
+			PDRectangle formrect, AffineTransform affineTransform, PDJpeg img)
+			throws IOException {
+
+		/*
+		 * if you need text on the visible signature
+		 * 
+		 * PDFont font = PDTrueTypeFont.loadTTF(this.pdfStructure.getTemplate(),
+		 * new File("D:\\arial.ttf")); font.setFontEncoding(new
+		 * WinAnsiEncoding());
+		 * 
+		 * Map<String, PDFont> fonts = new HashMap<String, PDFont>();
+		 * fonts.put("arial", font);
+		 */
+		PDXObjectForm imageForm = new PDXObjectForm(imageFormStream);
+		imageForm.setBBox(formrect);
+		imageForm.setMatrix(affineTransform);
+		imageForm.setResources(imageFormResources);
+		imageForm.setFormType(1);
+		/*
+		 * imageForm.getResources().addFont(font);
+		 * imageForm.getResources().setFonts(fonts);
+		 */
+
+		imageFormResources.getCOSObject().setDirect(true);
+		String imageFormName = innerFormResource.addXObject(imageForm, "n");
+		String imageName = imageFormResources.addXObject(img, "img");
+		this.getStructure().setImageForm(imageForm);
+		this.getStructure().setImageFormName(imageFormName);
+		this.getStructure().setImageName(imageName);
+		logger.debug("Created image form");
+	}
+
+	public void appendRawCommands(OutputStream os, String commands)
+			throws IOException {
+		os.write(commands.getBytes("UTF-8"));
+		os.close();
+	}
+
+	public void createVisualSignature(PDDocument template) {
+		this.getStructure().setVisualSignature(template.getDocument());
+		logger.debug("Visible signature has been created");
+
+	}
+
+	public void createWidgetDictionary(PDSignatureField signatureField,
+			PDResources holderFormResources) throws IOException {
+
+		COSDictionary widgetDict = signatureField.getWidget().getDictionary();
+		widgetDict.setNeedToBeUpdate(true);
+		widgetDict.setItem(COSName.DR, holderFormResources.getCOSObject());
+
+		getStructure().setWidgetDictionary(widgetDict);
+		logger.debug("WidgetDictionary has been crated");
+	}
+
+	public void closeTemplate(PDDocument template) throws IOException {
+		template.close();
+		this.getStructure().getTemplate().close();
+	}
+
+}
diff --git a/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsVisualSignatureDesigner.java b/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsVisualSignatureDesigner.java
new file mode 100644
index 00000000..17b02d9d
--- /dev/null
+++ b/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsVisualSignatureDesigner.java
@@ -0,0 +1,450 @@
+/*******************************************************************************
+ * <copyright> Copyright 2014 by E-Government Innovation Center EGIZ, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ * 
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ * 
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ ******************************************************************************/
+package at.gv.egiz.pdfas.lib.impl.stamping.pdfbox;
+
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+
+import javax.imageio.ImageIO;
+
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.pdmodel.PDPage;
+import org.apache.pdfbox.pdmodel.common.PDRectangle;
+
+public class PDFAsVisualSignatureDesigner {
+
+//	private static final Logger logger = LoggerFactory.getLogger(PDFAsVisualSignatureDesigner.class);
+
+	private Float sigImgWidth;
+	private Float sigImgHeight;
+	private float xAxis;
+	private float yAxis;
+	private float pageHeight;
+	private float pageWidth;
+	private InputStream imgageStream;
+	private String signatureFieldName = "sig"; // default
+	private float[] formaterRectangleParams = { 0, 0, 100, 50 }; // default
+	//private float[] AffineTransformParams = { 0, 1, -1, 0, 0, 0 }; // default
+	private float[] AffineTransformParams = { 1, 0, 0, 1, 0, 0 }; // default
+	private float imageSizeInPercents;
+	private PDDocument document = null;
+	private int page = 0;
+	private boolean newpage = false;
+	PDFAsVisualSignatureProperties properties;
+
+	/**
+	 * 
+	 * @param doc
+	 *            - Already created PDDocument of your PDF document
+	 * @param imageStream
+	 * @param page
+	 * @throws IOException
+	 *             - If we can't read, flush, or can't close stream
+	 */
+	public PDFAsVisualSignatureDesigner(PDDocument doc, int page,
+			PDFAsVisualSignatureProperties properties, boolean newpage) throws IOException {
+		this.properties = properties;
+		calculatePageSize(doc, page, newpage);
+		document = doc;
+		this.page = page;
+		this.newpage = newpage;
+	}
+
+	/**
+	 * Each page of document can be different sizes.
+	 * 
+	 * @param document
+	 * @param page
+	 */
+	private void calculatePageSize(PDDocument document, int page, boolean newpage) {
+
+		if (page < 1) {
+			throw new IllegalArgumentException("First page of pdf is 1, not "
+					+ page);
+		}
+		
+		List<?> pages = document.getDocumentCatalog().getAllPages();
+		if(newpage) {
+			PDPage lastPage = (PDPage) pages.get(pages.size()-1);
+			PDRectangle mediaBox = lastPage.findMediaBox();
+			this.pageHeight(mediaBox.getHeight());
+			this.pageWidth = mediaBox.getWidth();
+		} else {
+			PDPage firstPage = (PDPage) pages.get(page - 1);
+			PDRectangle mediaBox = firstPage.findMediaBox();
+			this.pageHeight(mediaBox.getHeight());
+			this.pageWidth = mediaBox.getWidth();
+		}
+		float x = this.pageWidth;
+		float y = 0;
+		this.pageWidth = this.pageWidth + y;
+		float tPercent = (100 * y / (x + y));
+		this.imageSizeInPercents = 100 - tPercent;
+	}
+
+	/**
+	 * 
+	 * @param path
+	 *            of image location
+	 * @return image Stream
+	 * @throws IOException
+	 */
+	public PDFAsVisualSignatureDesigner signatureImage(String path)
+			throws IOException {
+		InputStream fin = new FileInputStream(path);
+		return signatureImageStream(fin);
+	}
+
+	/**
+	 * zoom signature image with some percent.
+	 * 
+	 * @param percent
+	 *            - x % increase image with x percent.
+	 * @return Visible Signature Configuration Object
+	 */
+	public PDFAsVisualSignatureDesigner zoom(float percent) {
+		sigImgHeight = sigImgHeight + (sigImgHeight * percent) / 100;
+		sigImgWidth = sigImgWidth + (sigImgWidth * percent) / 100;
+		return this;
+	}
+
+	/**
+	 * 
+	 * @param xAxis
+	 *            - x coordinate
+	 * @param yAxis
+	 *            - y coordinate
+	 * @return Visible Signature Configuration Object
+	 */
+	public PDFAsVisualSignatureDesigner coordinates(float x, float y) {
+		xAxis(x);
+		yAxis(y);
+		return this;
+	}
+
+	/**
+	 * 
+	 * @return xAxis - gets x coordinates
+	 */
+	public float getxAxis() {
+		return xAxis;
+	}
+
+	/**
+	 * 
+	 * @param xAxis
+	 *            - x coordinate
+	 * @return Visible Signature Configuration Object
+	 */
+	public PDFAsVisualSignatureDesigner xAxis(float xAxis) {
+		this.xAxis = xAxis;
+		return this;
+	}
+
+	/**
+	 * 
+	 * @return yAxis
+	 */
+	public float getyAxis() {
+		return yAxis;
+	}
+
+	/**
+	 * 
+	 * @param yAxis
+	 * @return Visible Signature Configuration Object
+	 */
+	public PDFAsVisualSignatureDesigner yAxis(float yAxis) {
+		this.yAxis = yAxis;
+		return this;
+	}
+
+	/**
+	 * 
+	 * @return signature image width
+	 */
+	public float getWidth() {
+		return this.properties.getMainTable().getWidth();
+	}
+
+	/**
+	 * 
+	 * @param sets
+	 *            signature image width
+	 * @return Visible Signature Configuration Object
+	 */
+	public PDFAsVisualSignatureDesigner width(float signatureImgWidth) {
+		this.sigImgWidth = signatureImgWidth;
+		return this;
+	}
+
+	/**
+	 * 
+	 * @return signature image height
+	 */
+	public float getHeight() {
+		return this.properties.getMainTable().getHeight();
+	}
+
+	/**
+	 * 
+	 * @param set
+	 *            signature image Height
+	 * @return Visible Signature Configuration Object
+	 */
+	public PDFAsVisualSignatureDesigner height(float signatureImgHeight) {
+		this.sigImgHeight = signatureImgHeight;
+		return this;
+	}
+
+	/**
+	 * 
+	 * @return template height
+	 */
+	protected float getTemplateHeight() {
+		return getPageHeight();
+	}
+
+	/**
+	 * 
+	 * @param templateHeight
+	 * @return Visible Signature Configuration Object
+	 */
+	private PDFAsVisualSignatureDesigner pageHeight(float templateHeight) {
+		this.pageHeight = templateHeight;
+		return this;
+	}
+
+	/**
+	 * 
+	 * @return signature field name
+	 */
+	public String getSignatureFieldName() {
+		return signatureFieldName;
+	}
+
+	/**
+	 * 
+	 * @param signatureFieldName
+	 * @return Visible Signature Configuration Object
+	 */
+	public PDFAsVisualSignatureDesigner signatureFieldName(
+			String signatureFieldName) {
+		this.signatureFieldName = signatureFieldName;
+		return this;
+	}
+
+	/**
+	 * 
+	 * @return image Stream
+	 */
+	public InputStream getImageStream() {
+		return imgageStream;
+	}
+
+	/**
+	 * 
+	 * @param imgageStream
+	 *            - stream of your visible signature image
+	 * @return Visible Signature Configuration Object
+	 * @throws IOException
+	 *             - If we can't read, flush, or close stream of image
+	 */
+	private PDFAsVisualSignatureDesigner signatureImageStream(
+			InputStream imageStream) throws IOException {
+
+		ByteArrayOutputStream baos = new ByteArrayOutputStream();
+		byte[] buffer = new byte[1024];
+		int len;
+		while ((len = imageStream.read(buffer)) > -1) {
+			baos.write(buffer, 0, len);
+		}
+		baos.flush();
+		baos.close();
+
+		byte[] byteArray = baos.toByteArray();
+		byte[] byteArraySecond = byteArray.clone();
+
+		InputStream inputForBufferedImage = new ByteArrayInputStream(byteArray);
+		InputStream revertInputStream = new ByteArrayInputStream(
+				byteArraySecond);
+
+		if (sigImgHeight == null || sigImgWidth == null) {
+			calcualteImageSize(inputForBufferedImage);
+		}
+
+		this.imgageStream = revertInputStream;
+
+		return this;
+	}
+
+	/**
+	 * calculates image width and height. sported formats: all
+	 * 
+	 * @param fis
+	 *            - input stream of image
+	 * @throws IOException
+	 *             - if can't read input stream
+	 */
+	private void calcualteImageSize(InputStream fis) throws IOException {
+
+		BufferedImage bimg = ImageIO.read(fis);
+		int width = bimg.getWidth();
+		int height = bimg.getHeight();
+
+		sigImgHeight = (float) height;
+		sigImgWidth = (float) width;
+
+	}
+
+	/**
+	 * 
+	 * @return Affine Transform parameters of for PDF Matrix
+	 */
+	public float[] getAffineTransformParams() {
+		return AffineTransformParams;
+	}
+
+	/**
+	 * 
+	 * @param affineTransformParams
+	 * @return Visible Signature Configuration Object
+	 */
+	public PDFAsVisualSignatureDesigner affineTransformParams(
+			float[] affineTransformParams) {
+		AffineTransformParams = affineTransformParams;
+		return this;
+	}
+
+	/**
+	 * 
+	 * @return formatter PDRectanle parameters
+	 */
+	public float[] getFormaterRectangleParams() {
+		return formaterRectangleParams;
+	}
+
+	/**
+	 * sets formatter PDRectangle;
+	 * 
+	 * @param formaterRectangleParams
+	 * @return Visible Signature Configuration Object
+	 */
+	public PDFAsVisualSignatureDesigner formaterRectangleParams(
+			float[] formaterRectangleParams) {
+		this.formaterRectangleParams = formaterRectangleParams;
+		return this;
+	}
+
+	/**
+	 * 
+	 * @return page width
+	 */
+	public float getPageWidth() {
+		return pageWidth;
+	}
+	
+	public PDPage getSignaturePage() {
+		if (page < 1) {
+			throw new IllegalArgumentException("First page of pdf is 1, not "
+					+ page);
+		}
+		PDPage pdPage = null;
+		List<?> pages = document.getDocumentCatalog().getAllPages();
+		if(newpage) {
+			pdPage = new PDPage();
+		} else {
+			pdPage = (PDPage) pages.get(page - 1);
+		}
+		
+		return pdPage;
+	}
+
+	/**
+	 * 
+	 * @param sets
+	 *            pageWidth
+	 * @return Visible Signature Configuration Object
+	 */
+	public PDFAsVisualSignatureDesigner pageWidth(float pageWidth) {
+		this.pageWidth = pageWidth;
+		return this;
+	}
+
+	/**
+	 * 
+	 * @return page height
+	 */
+	public float getPageHeight() {
+		return pageHeight;
+	}
+
+	/**
+	 * get image size in percents
+	 * 
+	 * @return
+	 */
+	public float getImageSizeInPercents() {
+		return imageSizeInPercents;
+	}
+
+	/**
+	 * 
+	 * @param imageSizeInPercents
+	 */
+	public void imageSizeInPercents(float imageSizeInPercents) {
+		this.imageSizeInPercents = imageSizeInPercents;
+	}
+
+	/**
+	 * returns visible signature text
+	 * 
+	 * @return
+	 */
+	public String getSignatureText() {
+		throw new UnsupportedOperationException(
+				"That method is not yet implemented");
+	}
+
+	/**
+	 * 
+	 * @param signatureText
+	 *            - adds the text on visible signature
+	 * @return
+	 */
+	public PDFAsVisualSignatureDesigner signatureText(String signatureText) {
+		throw new UnsupportedOperationException(
+				"That method is not yet implemented");
+	}
+
+	public float getRotation() {
+		return this.properties.getRotation();
+	}
+	
+}
diff --git a/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsVisualSignatureProperties.java b/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsVisualSignatureProperties.java
new file mode 100644
index 00000000..cb1dfc38
--- /dev/null
+++ b/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFAsVisualSignatureProperties.java
@@ -0,0 +1,99 @@
+/*******************************************************************************
+ * <copyright> Copyright 2014 by E-Government Innovation Center EGIZ, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ * 
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ * 
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ ******************************************************************************/
+package at.gv.egiz.pdfas.lib.impl.stamping.pdfbox;
+
+import java.io.IOException;
+
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.pdmodel.interactive.digitalsignature.visible.PDVisibleSigProperties;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.gv.egiz.pdfas.common.exceptions.PdfAsException;
+import at.gv.egiz.pdfas.common.exceptions.PdfAsWrappedIOException;
+import at.gv.egiz.pdfas.common.settings.ISettings;
+import at.gv.egiz.pdfas.lib.impl.pdfbox.PDFBOXObject;
+import at.knowcenter.wag.egov.egiz.pdf.PositioningInstruction;
+
+public class PDFAsVisualSignatureProperties extends PDVisibleSigProperties {
+
+	private static final Logger logger = LoggerFactory.getLogger(PDFAsVisualSignatureProperties.class);
+	
+	private ISettings settings;
+
+	private PDFBoxTable main;
+	
+	private PDFAsVisualSignatureDesigner designer;
+	
+	private float rotationAngle = 0;
+
+	public PDFAsVisualSignatureProperties(ISettings settings, PDFBOXObject object, 
+			PdfBoxVisualObject visObj, PositioningInstruction pos) {
+		this.settings = settings;
+		try {
+			main = visObj.getTable();
+		} catch (Throwable e) {
+			e.printStackTrace();
+		}
+		this.rotationAngle = pos.getRotation();
+		try {
+			PDDocument origDoc = object.getDocument();
+
+			designer = new PDFAsVisualSignatureDesigner(origDoc, pos.getPage(), this, pos.isMakeNewPage());
+			float posy = designer.getPageHeight() - pos.getY();
+			designer.coordinates(pos.getX(), posy);
+			float[] form_rect = new float[] {0,0, main.getWidth() + 2, main.getHeight() + 2};
+			logger.debug("AP Rect: {} {} {} {}", form_rect[0], form_rect[1], form_rect[2], form_rect[3]);
+			designer.formaterRectangleParams(form_rect);
+			//this.setPdVisibleSignature(designer);
+		} catch (Throwable e) {
+			e.printStackTrace();
+		}
+	}
+
+	@Override
+	public void buildSignature() throws IOException {
+		PDFAsVisualSignatureBuilder builder = new PDFAsVisualSignatureBuilder(this, this.settings, designer);
+		PDFAsTemplateCreator creator = new PDFAsTemplateCreator(builder);
+		try {
+			setVisibleSignature(creator.buildPDF(designer));
+		} catch (PdfAsException e) {
+			throw new PdfAsWrappedIOException(e);
+		}
+	}
+
+	public PDFBoxTable getMainTable() {
+		return main;
+	}
+	
+	
+	public float getRotation() {
+		return this.rotationAngle;
+	}
+
+	public PDFAsVisualSignatureDesigner getDesigner() {
+		return designer;
+	}
+	
+}
diff --git a/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFBoxFont.java b/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFBoxFont.java
new file mode 100644
index 00000000..8fcca9b7
--- /dev/null
+++ b/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFBoxFont.java
@@ -0,0 +1,169 @@
+/*******************************************************************************
+ * <copyright> Copyright 2014 by E-Government Innovation Center EGIZ, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ * 
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ * 
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ ******************************************************************************/
+package at.gv.egiz.pdfas.lib.impl.stamping.pdfbox;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.pdmodel.font.PDFont;
+import org.apache.pdfbox.pdmodel.font.PDTrueTypeFont;
+import org.apache.pdfbox.pdmodel.font.PDType1Font;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.gv.egiz.pdfas.common.settings.ISettings;
+
+public class PDFBoxFont {
+	
+	private static final Logger logger = LoggerFactory
+			.getLogger(PDFBoxFont.class);
+	
+	private static final String HELVETICA = "HELVETICA";
+	private static final String COURIER = "COURIER";
+	private static final String TIMES_ROMAN = "TIMES_ROMAN";
+	private static final String BOLD = "BOLD";
+	private static final String NORMAL = "NORMAL";
+	private static final String ITALIC = "ITALIC";
+	private static final String SEP = ":";
+	
+	public static PDFont defaultFont = PDType1Font.HELVETICA;
+	public static float defaultFontSize = 8;
+	
+	private static Map<String, PDFont> fontStyleMap = new HashMap<String, PDFont>();
+	
+	static {
+		fontStyleMap.put(HELVETICA+SEP+NORMAL, PDType1Font.HELVETICA);
+		fontStyleMap.put(HELVETICA+SEP+BOLD, PDType1Font.HELVETICA_BOLD);
+		
+		fontStyleMap.put(COURIER+SEP+NORMAL, PDType1Font.COURIER);
+		fontStyleMap.put(COURIER+SEP+BOLD, PDType1Font.COURIER_BOLD);
+		
+		fontStyleMap.put(TIMES_ROMAN+SEP+NORMAL, PDType1Font.TIMES_ROMAN);
+		fontStyleMap.put(TIMES_ROMAN+SEP+BOLD, PDType1Font.TIMES_BOLD);
+		fontStyleMap.put(TIMES_ROMAN+SEP+ITALIC, PDType1Font.TIMES_ITALIC);
+	}
+	
+	public static void showBuildinFonts() {
+		Iterator<String> it = fontStyleMap.keySet().iterator();
+		logger.info("Available Fonts:");
+		while(it.hasNext()) {
+			logger.info(it.next());
+		}
+	}
+	
+	PDFont font;
+	PDFont cachedfont = null;
+	float fontSize;
+	String fontDesc;
+	String ttfFontDesc;
+	PDDocument doc;
+	ISettings settings;
+	
+	private PDFont generateTTF(String fonttype, PDDocument doc) throws IOException {
+		boolean cacheNow = false;
+		if(doc == null) {
+			if(this.doc == null) {
+				this.doc = new PDDocument();
+			}
+			doc = this.doc;
+		} else {
+			cacheNow = true;
+		}
+		ttfFontDesc = fonttype;
+		String fontName = fonttype.replaceFirst("TTF:", "");
+		
+		logger.debug("Instantiating font.");
+        String fontPath = this.settings.getWorkingDirectory()  + File.separator + "fonts" + File.separator + fontName;
+        logger.debug("Instantiating \"" + fontPath + "\".");
+
+        if(cacheNow) {
+        	cachedfont = PDTrueTypeFont.loadTTF(doc, fontPath);
+        	return cachedfont;
+        } else {
+        	return PDTrueTypeFont.loadTTF(doc, fontPath);
+        }
+	}
+	
+	private PDFont generateFont(String fonttype, String fontder) throws IOException {
+		if(fonttype.startsWith("TTF:")) {
+			// Load TTF Font
+			return generateTTF(fonttype, null);
+		} else {
+			if(fontder == null) {
+				fontder = NORMAL;
+			}
+			
+			String fontDesc = fonttype + SEP + fontder;
+			PDFont font = fontStyleMap.get(fontDesc);
+			if(font == null) {
+				showBuildinFonts();
+				throw new IOException("Invalid font descriptor");
+			}
+			return font;
+		}
+	}
+	
+	private void setFont(String desc) throws IOException {
+		String[] fontArr = desc.split(",");
+		
+		if(fontArr.length == 3) {
+			font = generateFont(fontArr[0], fontArr[2]);
+			fontSize = Float.parseFloat(fontArr[1]);
+		} else if(fontArr.length == 2 && fontArr[0].startsWith("TTF:")) {
+			font = generateFont(fontArr[0], null);
+			fontSize = Float.parseFloat(fontArr[1]);
+		} else {
+			logger.warn("Using default font because: {} is not a valid font descriptor.", desc);
+			this.font = defaultFont;
+			this.fontSize = defaultFontSize;
+		}
+		
+	}
+
+	public PDFBoxFont(String fontDesc, ISettings settings) throws IOException {
+		this.settings = settings;
+		this.fontDesc = fontDesc;
+		logger.debug("Creating Font: " + fontDesc);
+		this.setFont(fontDesc);
+	}
+	
+	public PDFont getFont(PDDocument doc) throws IOException {
+		if(cachedfont != null) {
+			return cachedfont;
+		}
+		if(font instanceof PDTrueTypeFont && doc != null) {
+			return generateTTF(ttfFontDesc, doc);
+		} else {
+			return font;
+		}
+	}
+	
+	public float getFontSize() {
+		return fontSize;
+	}
+}
diff --git a/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFBoxTable.java b/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFBoxTable.java
new file mode 100644
index 00000000..e84bd498
--- /dev/null
+++ b/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PDFBoxTable.java
@@ -0,0 +1,691 @@
+/*******************************************************************************
+ * <copyright> Copyright 2014 by E-Government Innovation Center EGIZ, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ * 
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ * 
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ ******************************************************************************/
+package at.gv.egiz.pdfas.lib.impl.stamping.pdfbox;
+
+import java.awt.Color;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.fontbox.ttf.TrueTypeFont;
+import org.apache.pdfbox.pdmodel.font.PDFont;
+import org.apache.pdfbox.pdmodel.font.PDTrueTypeFont;
+import org.apache.pdfbox.pdmodel.font.PDType1Font;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.gv.egiz.pdfas.common.exceptions.PdfAsException;
+import at.gv.egiz.pdfas.common.exceptions.PdfAsWrappedIOException;
+import at.gv.egiz.pdfas.common.settings.ISettings;
+import at.gv.egiz.pdfas.common.utils.StringUtils;
+import at.knowcenter.wag.egov.egiz.table.Entry;
+import at.knowcenter.wag.egov.egiz.table.Style;
+import at.knowcenter.wag.egov.egiz.table.Table;
+
+public class PDFBoxTable {
+
+	private static final Logger logger = LoggerFactory
+			.getLogger(PDFBoxTable.class);
+
+	Table table;
+	Style style;
+	PDFBoxFont font;
+	PDFBoxFont valueFont;
+	ISettings settings;
+
+	float padding;
+	int positionX = 0;
+	int positionY = 0;
+	float tableWidth;
+	float tableHeight;
+	Color bgColor;
+
+	boolean[] addPadding;
+	float[] rowHeights;
+	float[] colWidths;
+
+	private void normalizeContent(Table abstractTable) throws PdfAsException {
+		try {
+			int rows = abstractTable.getRows().size();
+			for (int i = 0; i < rows; i++) {
+				ArrayList<Entry> row = this.table.getRows().get(i);
+				for (int j = 0; j < row.size(); j++) {
+					Entry cell = (Entry) row.get(j);
+
+					switch (cell.getType()) {
+					case Entry.TYPE_CAPTION:
+					case Entry.TYPE_VALUE:
+						String value = (String) cell.getValue();
+						cell.setValue(StringUtils
+								.convertStringToPDFFormat(value));
+						break;
+					}
+				}
+			}
+		} catch (UnsupportedEncodingException e) {
+			throw new PdfAsException("Unsupported Encoding", e);
+		}
+	}
+
+	private void initializeStyle(Table abstractTable, PDFBoxTable parent)
+			throws IOException {
+		this.table = abstractTable;
+		try {
+			normalizeContent(abstractTable);
+		} catch (PdfAsException e) {
+			throw new PdfAsWrappedIOException(e);
+		}
+
+		if (parent != null) {
+			style = Style.doInherit(abstractTable.getStyle(), parent.style);
+		} else {
+			style = abstractTable.getStyle();
+		}
+
+		if (style == null) {
+			throw new IOException("Failed to determine Table style, for table "
+					+ abstractTable.getName());
+		}
+
+		String fontString = style.getFont();
+
+		String vfontString = style.getValueFont();
+
+		if (parent != null && style == parent.style) {
+			font = parent.getFont();
+
+			valueFont = parent.getValueFont();
+		} else {
+			if (fontString == null && parent != null && parent.style != null) {
+				fontString = parent.style.getFont();
+			} else if (fontString == null) {
+				throw new IOException(
+						"Failed to determine Table font style, for table "
+								+ abstractTable.getName());
+			}
+
+			font = new PDFBoxFont(fontString, settings);
+
+			if (vfontString == null && parent != null && parent.style != null) {
+				vfontString = parent.style.getValueFont();
+			} else if (fontString == null) {
+				throw new IOException(
+						"Failed to determine value Table font style, for table "
+								+ abstractTable.getName());
+			}
+
+			valueFont = new PDFBoxFont(vfontString, settings);
+		}
+		padding = style.getPadding();
+
+		bgColor = style.getBgColor();
+	}
+
+	public PDFBoxTable(Table abstractTable, PDFBoxTable parent, float fixSize,
+			ISettings settings) throws IOException {
+		this.settings = settings;
+		initializeStyle(abstractTable, parent);
+		float[] relativSizes = abstractTable.getColsRelativeWith();
+		if (relativSizes != null) {
+			colWidths = new float[relativSizes.length];
+			float totalrel = 0;
+
+			for (int i = 0; i < relativSizes.length; i++) {
+				totalrel += relativSizes[i];
+			}
+
+			float unit = (fixSize / totalrel);
+
+			for (int i = 0; i < relativSizes.length; i++) {
+
+				colWidths[i] = unit * relativSizes[i];
+			}
+		} else {
+			colWidths = new float[abstractTable.getMaxCols()];
+			float totalrel = abstractTable.getMaxCols();
+			float unit = (fixSize / totalrel);
+			for (int i = 0; i < colWidths.length; i++) {
+
+				colWidths[i] = unit;
+			}
+		}
+		calculateHeightsBasedOnWidths();
+		
+		logger.debug("Generating Table with fixed With {} got width {}", fixSize, getWidth());
+	}
+
+	public PDFBoxTable(Table abstractTable, PDFBoxTable parent,
+			ISettings settings) throws IOException {
+		this.settings = settings;
+		initializeStyle(abstractTable, parent);
+		this.calculateWidthHeight();
+	}
+
+	private void calculateHeightsBasedOnWidths() throws IOException {
+		int rows = this.table.getRows().size();
+		rowHeights = new float[rows];
+		addPadding = new boolean[rows];
+
+		for (int i = 0; i < rows; i++) {
+			rowHeights[i] = 0;
+		}
+
+		for (int i = 0; i < rows; i++) {
+			ArrayList<Entry> row = this.table.getRows().get(i);
+			for (int j = 0; j < row.size(); j++) {
+				Entry cell = (Entry) row.get(j);
+
+				float colWidth = 0;//colWidths[j];
+
+				int colsleft = cell.getColSpan();
+
+				if (j + colsleft > colWidths.length) {
+					throw new IOException(
+							"Configuration is wrong. Cannot determine column width!");
+				}
+
+				for (int k = 0; k < colsleft; k++) {
+					colWidth = colWidth + colWidths[j + k];
+				}
+
+				float cellheight = getCellHeight(cell, colWidth);
+
+				if (rowHeights[i] < cellheight) {
+					rowHeights[i] = cellheight;
+				}
+
+				logger.debug("ROW: {} COL: {} Width: {} Height: {}", i, j,
+						colWidth, cellheight);
+
+				int span = cell.getColSpan() - 1;
+				j += span;
+			}
+		}
+
+		calcTotals();
+	}
+
+	private void calculateWidthHeight() throws IOException {
+		int cols = this.table.getMaxCols();
+		colWidths = new float[cols];
+
+		for (int i = 0; i < cols; i++) {
+			colWidths[i] = 0;
+		}
+
+		int rows = this.table.getRows().size();
+		rowHeights = new float[rows];
+
+		for (int i = 0; i < rows; i++) {
+			rowHeights[i] = 0;
+		}
+
+		for (int i = 0; i < rows; i++) {
+			ArrayList<Entry> row = this.table.getRows().get(i);
+			for (int j = 0; j < row.size(); j++) {
+				Entry cell = (Entry) row.get(j);
+				float cellWidth = getCellWidth(cell);
+
+				if (colWidths[j] < cellWidth) {
+					colWidths[j] = cellWidth;
+				}
+
+				float cellheight = getCellHeight(cell);
+
+				if (rowHeights[i] < cellheight) {
+					rowHeights[i] = cellheight;
+				}
+
+				logger.debug("ROW: {} COL: {} Width: {} Height: {}", i, j,
+						cellWidth, cellheight);
+
+				int span = cell.getColSpan() - 1;
+				j += span;
+			}
+		}
+
+		calcTotals();
+	}
+
+	private void calcTotals() {
+
+		this.tableHeight = 0;
+
+		for (int i = 0; i < rowHeights.length; i++) {
+			this.tableHeight += rowHeights[i];
+		}
+
+		// Post Process heights for inner Tables ...
+		for (int i = 0; i < rowHeights.length; i++) {
+			ArrayList<Entry> row = this.table.getRows().get(i);
+			for (int j = 0; j < row.size(); j++) {
+				Entry cell = (Entry) row.get(j);
+				if(cell.getType() == Entry.TYPE_TABLE) {
+					PDFBoxTable tbl = (PDFBoxTable)cell.getValue();
+					if(rowHeights[i] != tbl.getHeight())
+					{
+						tbl.setHeight(rowHeights[i]);
+					}
+				}
+			}
+		}
+		
+		this.tableWidth = 0;
+
+		for (int i = 0; i < colWidths.length; i++) {
+			this.tableWidth += colWidths[i];
+		}
+	}
+
+	private float getCellWidth(Entry cell) throws IOException {
+		boolean isValue = true;
+		switch (cell.getType()) {
+		case Entry.TYPE_CAPTION:
+			isValue = false;
+		case Entry.TYPE_VALUE:
+			PDFont c = null;
+			float fontSize;
+			String string = (String) cell.getValue();
+			if (isValue) {
+				c = valueFont.getFont(null);
+				fontSize = valueFont.getFontSize();
+			} else {
+				c = font.getFont(null);
+				fontSize = font.getFontSize();
+			}
+			if (string == null) {
+				string = "";
+				cell.setValue(string);
+			}
+			if (string.contains("\n")) {
+				float maxWidth = 0;
+				String[] lines = string.split("\n");
+				for (int i = 0; i < lines.length; i++) {
+					float w = c.getStringWidth(lines[i]) / 1000 * fontSize;
+					if (maxWidth < w) {
+						maxWidth = w;
+					}
+				}
+				return maxWidth;
+			} else {
+				return c.getStringWidth(string) / 1000 * fontSize;
+			}
+		case Entry.TYPE_IMAGE:
+			if (style != null && style.getImageScaleToFit() != null) {
+				return style.getImageScaleToFit().getWidth();
+			}
+			return 80.f;
+		case Entry.TYPE_TABLE:
+			PDFBoxTable pdfBoxTable = null;
+			if (cell.getValue() instanceof Table) {
+				pdfBoxTable = new PDFBoxTable((Table) cell.getValue(), this,
+						this.settings);
+				cell.setValue(pdfBoxTable);
+			} else if (cell.getValue() instanceof PDFBoxTable) {
+				pdfBoxTable = (PDFBoxTable) cell.getValue();
+			} else {
+				throw new IOException("Failed to build PDFBox Table");
+			}
+			return pdfBoxTable.getWidth();
+		default:
+			logger.warn("Invalid Cell Entry Type: " + cell.getType());
+		}
+		return 0;
+	}
+
+	private String concatLines(String[] lines) {
+		String v = "";
+		for (int i = 0; i < lines.length; i++) {
+			v += lines[i];
+			if (i + 1 < lines.length) {
+				v += "\n";
+			}
+		}
+		return v;
+	}
+
+	private String[] breakString(String value, float maxwidth, PDFont font,
+			float fontSize) throws IOException {
+		String[] words = value.split(" ");
+		List<String> lines = new ArrayList<String>();
+		String cLineValue = "";
+		for (int i = 0; i < words.length; i++) {
+			String word = words[i];
+			String[] lineBreaks = word.split("\n");
+			if (lineBreaks.length > 1) {
+				for (int j = 0; j < lineBreaks.length; j++) {
+					String subword = lineBreaks[j];
+					// if (cLine + subword.length() > maxline) {
+					if (j == 0 && word.startsWith("\n")) {
+						lines.add(cLineValue.trim());
+						cLineValue = "";
+					} else if (j != 0) {
+						lines.add(cLineValue.trim());
+						cLineValue = "";
+					}
+					// }
+					String tmpLine = cLineValue + subword;
+					float size = font.getStringWidth(tmpLine) / 1000.0f
+							* fontSize;
+					if (size > maxwidth && cLineValue.length() != 0) {
+						lines.add(cLineValue.trim());
+						cLineValue = "";
+					}
+					cLineValue += subword + " ";
+				}
+			} else {
+				String tmpLine = cLineValue + word;
+				float size = font.getStringWidth(tmpLine) / 1000.0f * fontSize;
+				if (size > maxwidth && cLineValue.length() != 0) {
+					lines.add(cLineValue.trim());
+					cLineValue = "";
+				}
+				cLineValue += word + " ";
+			}
+		}
+		lines.add(cLineValue.trim());
+		return lines.toArray(new String[0]);
+	}
+
+	private String[] breakString(String value, int maxline) {
+		String[] words = value.split(" ");
+		List<String> lines = new ArrayList<String>();
+		int cLine = 0;
+		String cLineValue = "";
+		for (int i = 0; i < words.length; i++) {
+			String word = words[i];
+			String[] lineBreaks = word.split("\n");
+			if (lineBreaks.length > 1) {
+				for (int j = 0; j < lineBreaks.length; j++) {
+					String subword = lineBreaks[j];
+					// if (cLine + subword.length() > maxline) {
+					lines.add(cLineValue.trim());
+					cLineValue = "";
+					cLine = 0;
+					// }
+					cLineValue += subword + " ";
+					cLine += subword.length();
+				}
+			} else {
+				if (cLine + word.length() > maxline && cLineValue.length() != 0) {
+					lines.add(cLineValue.trim());
+					cLineValue = "";
+					cLine = 0;
+				}
+				cLineValue += word + " ";
+				cLine += word.length();
+			}
+		}
+		lines.add(cLineValue.trim());
+		return lines.toArray(new String[0]);
+	}
+
+	// private String[] breakString(String value, PDFont f, float maxwidth)
+	// throws IOException {
+	// String[] words = value.split(" ");
+	// List<String> lines = new ArrayList<String>();
+	// int cLine = 0;
+	// String cLineValue = "";
+	// for (int i = 0; i < words.length; i++) {
+	// String word = words[i];
+	// String[] lineBreaks = word.split("\n");
+	// if (lineBreaks.length > 1) {
+	// for (int j = 0; j < lineBreaks.length; j++) {
+	// String subword = lineBreaks[j];
+	// // if (cLine + subword.length() > maxline) {
+	// lines.add(cLineValue.trim());
+	// cLineValue = "";
+	// cLine = 0;
+	// // }
+	// cLineValue += subword + " ";
+	// cLine += subword.length();
+	// }
+	// } else {
+	// if (f.getStringWidth(cLineValue + word) > maxwidth && cLineValue.length()
+	// != 0) {
+	// lines.add(cLineValue.trim());
+	// cLineValue = "";
+	// cLine = 0;
+	// }
+	// cLineValue += word + " ";
+	// cLine += word.length();
+	// }
+	// }
+	// lines.add(cLineValue.trim());
+	// return lines.toArray(new String[0]);
+	// }
+
+	private float[] getStringHeights(String[] lines, PDFont c, float fontSize) {
+		float[] heights = new float[lines.length];
+		for (int i = 0; i < lines.length; i++) {
+			float maxLineHeight = 0;
+			try {
+				byte[] linebytes = StringUtils.applyWinAnsiEncoding(lines[i]);
+				for(int j = 0; j < linebytes.length; j++) {
+					float he = c.getFontHeight(linebytes, j, 1) / 1000 * fontSize;
+					if(he > maxLineHeight) {
+						maxLineHeight = he;
+					}
+				}
+			} catch (UnsupportedEncodingException e) {
+				logger.warn("failed to determine String height", e);
+				maxLineHeight = c.getFontDescriptor().getCapHeight() / 1000 * fontSize;
+			} catch (IOException e) {
+				logger.warn("failed to determine String height", e);
+				maxLineHeight = c.getFontDescriptor().getCapHeight() / 1000 * fontSize;
+			}
+			
+			heights[i] = maxLineHeight;
+		}
+		
+		return heights;
+	}
+
+	private float getCellHeight(Entry cell, float width) throws IOException {
+		boolean isValue = true;
+		switch (cell.getType()) {
+		case Entry.TYPE_CAPTION:
+			isValue = false;
+		case Entry.TYPE_VALUE:
+			PDFont c = null;
+			float fontSize;
+			String string = (String) cell.getValue();
+			if (isValue) {
+				c = valueFont.getFont(null);
+				fontSize = valueFont.getFontSize();
+			} else {
+				c = font.getFont(null);
+				fontSize = font.getFontSize();
+			}
+
+			String[] lines = breakString(string, (width - padding * 2.0f), c,
+					fontSize);
+			cell.setValue(concatLines(lines));
+			float[] heights = getStringHeights(lines, c, fontSize);
+			return fontSize * heights.length  + padding * 2;
+		case Entry.TYPE_IMAGE:
+			if (style != null && style.getImageScaleToFit() != null) {
+				//if (style.getImageScaleToFit().getHeight() < width) {
+					return style.getImageScaleToFit().getHeight();
+				//}
+			}
+			return width;
+		case Entry.TYPE_TABLE:
+			PDFBoxTable pdfBoxTable = null;
+			if (cell.getValue() instanceof Table) {
+				pdfBoxTable = new PDFBoxTable((Table) cell.getValue(), this,
+						width, this.settings);
+				cell.setValue(pdfBoxTable);
+			} else if (cell.getValue() instanceof PDFBoxTable) {
+				// recreate here beacuse of fixed width!
+				pdfBoxTable = (PDFBoxTable) cell.getValue();
+				pdfBoxTable = new PDFBoxTable(pdfBoxTable.table, this, width,
+						this.settings);
+				cell.setValue(pdfBoxTable);
+			} else {
+				throw new IOException("Failed to build PDFBox Table");
+			}
+			return pdfBoxTable.getHeight();
+		default:
+			logger.warn("Invalid Cell Entry Type: " + cell.getType());
+		}
+		return 0;
+	}
+
+	private float getCellHeight(Entry cell) throws IOException {
+		boolean isValue = true;
+		switch (cell.getType()) {
+		case Entry.TYPE_CAPTION:
+			isValue = false;
+		case Entry.TYPE_VALUE:
+			PDFont c = null;
+			float fontSize;
+			String string = (String) cell.getValue();
+			if (isValue) {
+				c = valueFont.getFont(null);
+				fontSize = valueFont.getFontSize();
+			} else {
+				c = font.getFont(null);
+				fontSize = font.getFontSize();
+			}
+
+			if (string.contains("\n")) {
+				String[] lines = string.split("\n");
+
+				return fontSize * lines.length + padding * 2;
+			} else {
+				return fontSize + padding * 2;
+			}
+		case Entry.TYPE_IMAGE:
+			if (style != null && style.getImageScaleToFit() != null) {
+				return style.getImageScaleToFit().getHeight();
+			}
+			return 80.f;
+		case Entry.TYPE_TABLE:
+			PDFBoxTable pdfBoxTable = null;
+			if (cell.getValue() instanceof Table) {
+				pdfBoxTable = new PDFBoxTable((Table) cell.getValue(), this,
+						this.settings);
+				cell.setValue(pdfBoxTable);
+			} else if (cell.getValue() instanceof PDFBoxTable) {
+				pdfBoxTable = (PDFBoxTable) cell.getValue();
+			} else {
+				throw new IOException("Failed to build PDFBox Table");
+			}
+			return pdfBoxTable.getHeight();
+		default:
+			logger.warn("Invalid Cell Entry Type: " + cell.getType());
+		}
+		return 0;
+	}
+
+	public int getX() {
+		return this.positionX;
+	}
+
+	public int getY() {
+		return this.positionY;
+	}
+
+	public float getWidth() {
+		return tableWidth;
+	}
+
+	public float getHeight() {
+		return tableHeight;
+	}
+	
+	public void setHeight(float height) {
+		float diff = height - this.getHeight();
+		if(diff > 0) {
+			this.rowHeights[rowHeights.length - 1] += diff;
+			calcTotals();
+		} else {
+			logger.warn("Table cannot be this small!");
+		}
+	}
+
+	public float[] getRowHeights() {
+		return rowHeights;
+	}
+
+	public int getRowCount() {
+		return this.table.getRows().size();
+	}
+
+	public int getColCount() {
+		return this.table.getMaxCols();// .getColsRelativeWith().length;
+	}
+
+	public float[] getColsRelativeWith() {
+		return this.table.getColsRelativeWith();
+	}
+
+	public float getPadding() {
+		return this.padding;
+	}
+
+	public void dumpTable() {
+		logger.debug("=====================================================================");
+		logger.debug("Information about: " + this.table.getName());
+		logger.debug("\tDimensions: {} x {} (W x H)", this.tableWidth,
+				this.tableHeight);
+		logger.debug("\tPadding: {}", padding);
+		logger.debug("\t================================");
+		logger.debug("\tRow Heights:");
+		for (int i = 0; i < rowHeights.length; i++) {
+			logger.debug("\t[{}] : {}", i, this.rowHeights[i]);
+		}
+		logger.debug("\t================================");
+		logger.debug("\tCol Widths:");
+		for (int i = 0; i < colWidths.length; i++) {
+			logger.debug("\t[{}] : {}", i, this.colWidths[i]);
+		}
+		logger.debug("\t================================");
+		logger.debug("\tTable:");
+		logger.debug("\t" + this.table.toString());
+		logger.debug("=====================================================================");
+	}
+
+	public Table getOrigTable() {
+		return this.table;
+	}
+
+	public ArrayList<Entry> getRow(int i) {
+		return this.table.getRows().get(i);
+	}
+
+	public PDFBoxFont getFont() {
+		return font;
+	}
+
+	public PDFBoxFont getValueFont() {
+		return valueFont;
+	}
+
+	public Color getBGColor() {
+		return this.bgColor;
+	}
+}
diff --git a/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PdfBoxStamper.java b/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PdfBoxStamper.java
new file mode 100644
index 00000000..c60c4283
--- /dev/null
+++ b/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PdfBoxStamper.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * <copyright> Copyright 2014 by E-Government Innovation Center EGIZ, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ * 
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ * 
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ ******************************************************************************/
+package at.gv.egiz.pdfas.lib.impl.stamping.pdfbox;
+
+import java.io.IOException;
+
+import at.gv.egiz.pdfas.common.exceptions.PdfAsException;
+import at.gv.egiz.pdfas.common.settings.ISettings;
+import at.gv.egiz.pdfas.lib.impl.stamping.IPDFStamper;
+import at.gv.egiz.pdfas.lib.impl.stamping.IPDFVisualObject;
+import at.gv.egiz.pdfas.lib.impl.status.PDFObject;
+import at.knowcenter.wag.egov.egiz.pdf.PositioningInstruction;
+import at.knowcenter.wag.egov.egiz.table.Table;
+
+public class PdfBoxStamper implements IPDFStamper {
+
+//	private static final Logger logger = LoggerFactory.getLogger(PdfBoxStamper.class);
+
+//	private PDFTemplateBuilder pdfBuilder;
+
+	public PdfBoxStamper() {
+//		this.pdfBuilder = new PDVisibleSigBuilder();
+	}
+	
+	public IPDFVisualObject createVisualPDFObject(PDFObject pdf, Table table) throws IOException {
+		return new PdfBoxVisualObject(table, pdf.getStatus().getSettings());
+	}
+
+	public byte[] writeVisualObject(IPDFVisualObject visualObject,
+			PositioningInstruction positioningInstruction, byte[] pdfData,
+			String placeholderName) throws PdfAsException {
+		return null;
+	}
+
+	public void setSettings(ISettings settings) {
+		// not needed currently
+	}
+
+}
diff --git a/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PdfBoxVisualObject.java b/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PdfBoxVisualObject.java
new file mode 100644
index 00000000..c7623cf9
--- /dev/null
+++ b/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/PdfBoxVisualObject.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * <copyright> Copyright 2014 by E-Government Innovation Center EGIZ, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ * 
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ * 
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ ******************************************************************************/
+package at.gv.egiz.pdfas.lib.impl.stamping.pdfbox;
+
+import java.io.IOException;
+
+import at.gv.egiz.pdfas.common.settings.ISettings;
+import at.gv.egiz.pdfas.lib.impl.stamping.IPDFVisualObject;
+import at.knowcenter.wag.egov.egiz.table.Table;
+
+public class PdfBoxVisualObject implements IPDFVisualObject {
+
+	private Table abstractTable;
+	private PDFBoxTable table;
+	private float width;
+	private float x;
+	private float y;
+	private int page;
+	private ISettings settings;
+
+	public PdfBoxVisualObject(Table table, ISettings settings)
+			throws IOException {
+		this.abstractTable = table;
+		this.table = new PDFBoxTable(table, null, settings);
+		this.settings = settings;
+	}
+
+	public void setWidth(float width) {
+		this.width = width;
+	}
+
+	public void fixWidth() {
+		try {
+			table = new PDFBoxTable(abstractTable, null, this.width,  settings);
+		} catch (IOException e) {
+			// should not occur
+			e.printStackTrace();
+		}
+	}
+
+	public float getHeight() {
+		return table.getHeight();
+	}
+
+	public float getWidth() {
+		return table.getWidth();
+	}
+
+	public void setXPos(float x) {
+		this.x = x;
+	}
+
+	public void setYPos(float y) {
+		this.y = y;
+	}
+	
+	public float getX() {
+        return x;
+    }
+
+    public float getY() {
+        return y;
+    }
+
+	public int getPage() {
+		return page;
+	}
+
+	public void setPage(int page) {
+		this.page = page;
+	}
+
+	public PDFBoxTable getTable() {
+		return this.table;
+	}
+}
diff --git a/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/TableDrawUtils.java b/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/TableDrawUtils.java
new file mode 100644
index 00000000..88eb798a
--- /dev/null
+++ b/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox/TableDrawUtils.java
@@ -0,0 +1,564 @@
+/*******************************************************************************
+ * <copyright> Copyright 2014 by E-Government Innovation Center EGIZ, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ * 
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ * 
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ ******************************************************************************/
+package at.gv.egiz.pdfas.lib.impl.stamping.pdfbox;
+
+import java.awt.Color;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.pdmodel.PDPage;
+import org.apache.pdfbox.pdmodel.PDResources;
+import org.apache.pdfbox.pdmodel.edit.PDPageContentStream;
+import org.apache.pdfbox.pdmodel.font.PDFont;
+import org.apache.pdfbox.pdmodel.graphics.xobject.PDXObjectImage;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.gv.egiz.pdfas.common.exceptions.PdfAsException;
+import at.gv.egiz.pdfas.common.settings.ISettings;
+import at.knowcenter.wag.egov.egiz.table.Entry;
+import at.knowcenter.wag.egov.egiz.table.Style;
+
+public class TableDrawUtils {
+
+	private static final Logger logger = LoggerFactory
+			.getLogger(TableDrawUtils.class);
+
+	public static final String TABLE_DEBUG = "debug.table";
+
+	public static void drawTable(PDPage page,
+			PDPageContentStream contentStream, float x, float y, float width,
+			float height, PDFBoxTable abstractTable, PDDocument doc,
+			boolean subtable, PDResources formResources,
+			Map<String, ImageObject> images, ISettings settings)
+			throws PdfAsException {
+
+		logger.debug("Drawing Table: X {} Y {} WIDTH {} HEIGHT {} \n{}", x, y,
+				width, height, abstractTable.getOrigTable().toString());
+
+		abstractTable.getOrigTable().setWidth(width);
+
+		drawTableBackground(page, contentStream, x, y, width, height,
+				abstractTable, settings);
+
+		drawBorder(page, contentStream, x, y, width, height, abstractTable,
+				doc, subtable, settings);
+
+		drawContent(page, contentStream, x, y, width, height, abstractTable,
+				doc, subtable, formResources, images, settings);
+	}
+
+	public static void drawContent(PDPage page,
+			PDPageContentStream contentStream, float x, float y, float width,
+			float height, PDFBoxTable abstractTable, PDDocument doc,
+			boolean subtable, PDResources formResources,
+			Map<String, ImageObject> images, ISettings settings)
+			throws PdfAsException {
+
+		float contentx = x;
+		float contenty = y + height;
+		float padding = abstractTable.getPadding();
+		float[] colsSizes = getColSizes(abstractTable);
+
+		for (int i = 0; i < abstractTable.getRowCount(); i++) {
+			ArrayList<Entry> row = abstractTable.getRow(i);
+			for (int j = 0; j < row.size(); j++) {
+				Entry cell = (Entry) row.get(j);
+
+				// Cell only contains default values so table style is the primary style
+				Style inherit_style = Style.doInherit(abstractTable.style, cell.getStyle());
+				cell.setStyle(inherit_style);
+
+				float colWidth = 0;//colWidths[j];
+
+				int colsleft = cell.getColSpan();
+
+				if (j + colsleft > colsSizes.length) {
+					throw new PdfAsException(
+							"Configuration is wrong. Cannot determine column width!");
+				}
+
+				for (int k = 0; k < colsleft; k++) {
+					colWidth = colWidth + colsSizes[j + k];
+				}
+				
+				drawDebugPadding(contentStream, contentx, contenty, padding,
+						colWidth, abstractTable.getRowHeights()[i], settings);
+
+				switch (cell.getType()) {
+				case Entry.TYPE_CAPTION:
+					drawCaption(page, contentStream, contentx, contenty,
+							colWidth, abstractTable.getRowHeights()[i],
+							padding, abstractTable, doc, cell, formResources, settings);
+					break;
+				case Entry.TYPE_VALUE:
+					drawValue(page, contentStream, contentx, contenty,
+							colWidth, abstractTable.getRowHeights()[i],
+							padding, abstractTable, doc, cell, formResources, settings);
+					break;
+				case Entry.TYPE_IMAGE:
+					drawImage(page, contentStream, contentx, contenty,
+							colWidth, abstractTable.getRowHeights()[i],
+							padding, abstractTable, doc, cell, formResources,
+							images, settings);
+					break;
+				case Entry.TYPE_TABLE:
+
+					PDFBoxTable tbl_value = (PDFBoxTable) cell.getValue();
+
+					Style inherit_styletab = Style.doInherit(
+							abstractTable.style, cell.getStyle());
+					tbl_value.table.setStyle(inherit_styletab);
+
+					drawTable(page, contentStream, contentx, contenty
+							- abstractTable.getRowHeights()[i], colWidth,
+							abstractTable.getRowHeights()[i], tbl_value, doc,
+							true, formResources, images, settings);
+					break;
+				default:
+					logger.warn("Unknown Cell entry type: " + cell.getType());
+					break;
+				}
+
+				// Move content pointer
+				contentx += colWidth;
+				
+				int span = cell.getColSpan() - 1;
+				j += span;
+			}
+
+			// Move content pointer
+			contenty -= abstractTable.getRowHeights()[i];
+			contentx = x;
+		}
+	}
+
+	private static void drawString(PDPage page,
+			PDPageContentStream contentStream, float contentx, float contenty,
+			float width, float height, float padding,
+			PDFBoxTable abstractTable, PDDocument doc, Entry cell,
+			float fontSize, float textHeight, String valign, String halign,
+			String[] tlines, PDFont textFont, PDResources formResources,
+			ISettings settings) throws PdfAsException {
+		try {
+			float ty = contenty - padding;
+			float tx = contentx + padding;
+			float innerHeight = height - (2 * padding);
+			float innerWidth = width - (2 * padding);
+			if (Style.BOTTOM.equals(valign)) {
+				float bottom_offset = innerHeight - textHeight;
+				ty -= bottom_offset;
+			} else if (Style.MIDDLE.equals(valign)) {
+				float bottom_offset = innerHeight - textHeight;
+				bottom_offset = bottom_offset / 2.0f;
+				ty -= bottom_offset;
+			}
+
+			// calculate the max with of the text content
+			float maxWidth = 0;
+			for (int k = 0; k < tlines.length; k++) {
+				float lineWidth;
+				// if (textFont instanceof PDType1Font) {
+				lineWidth = textFont.getStringWidth(tlines[k]) / 1000.0f
+						* fontSize;
+				/*
+				 * } else { float fwidth = textFont
+				 * .getStringWidth("abcdefghijklmnopqrstuvwxyz ") / 1000.0f *
+				 * fontSize; fwidth = fwidth / (float)
+				 * "abcdefghijklmnopqrstuvwxyz" .length(); lineWidth =
+				 * tlines[k].length() * fwidth; }
+				 */
+				if (maxWidth < lineWidth) {
+					maxWidth = lineWidth;
+				}
+			}
+
+			if (Style.CENTER.equals(halign)) {
+				float offset = innerWidth - maxWidth;
+				if (offset > 0) {
+					offset = offset / 2.0f;
+					tx += offset;
+				}
+			} else if (Style.RIGHT.equals(halign)) {
+				float offset = innerWidth - maxWidth;
+				if (offset > 0) {
+					tx += offset;
+				}
+			}
+
+			logger.debug("Text tx {} ty {} maxWidth {} textHeight {}", tx, ty,
+					maxWidth, textHeight);
+
+			drawDebugLine(contentStream, tx, ty, maxWidth, textHeight, settings);
+
+			contentStream.beginText();
+
+			if (formResources.getFonts().containsValue(textFont)) {
+				String fontID = getFontID(textFont, formResources);
+				logger.debug("Using Font: " + fontID);
+				contentStream.appendRawCommands("/" + fontID + " " + fontSize
+						+ " Tf\n");
+			} else {
+				contentStream.setFont(textFont, fontSize);
+			}
+
+			logger.debug("Writing: " + tx + " : " + (ty - fontSize) + " as "
+					+ cell.getType());
+			contentStream.moveTextPositionByAmount(tx, (ty - fontSize));
+
+			contentStream.appendRawCommands(fontSize + " TL\n");
+			for (int k = 0; k < tlines.length; k++) {
+				contentStream.drawString(tlines[k]);
+				if (k < tlines.length - 1) {
+					contentStream.appendRawCommands("T*\n");
+				}
+			}
+
+			contentStream.endText();
+
+		} catch (IOException e) {
+			logger.error("IO Exception", e);
+			throw new PdfAsException("Error", e);
+		}
+	}
+
+	public static void drawCaption(PDPage page,
+			PDPageContentStream contentStream, float contentx, float contenty,
+			float width, float height, float padding,
+			PDFBoxTable abstractTable, PDDocument doc, Entry cell,
+			PDResources formResources, ISettings settings)
+			throws PdfAsException {
+
+		logger.debug("Drawing Caption @ X: {} Y: {}", contentx, contenty);
+
+		try {
+			float fontSize = PDFBoxFont.defaultFontSize;
+			PDFont textFont = PDFBoxFont.defaultFont;
+
+			textFont = abstractTable.getFont().getFont(doc);
+			fontSize = abstractTable.getFont().getFontSize();
+
+			// get the cell Text
+			String text = (String) cell.getValue();
+			String[] tlines = text.split("\n");
+			float textHeight = fontSize * tlines.length;
+
+			Style cellStyle = cell.getStyle();
+			String valign = cellStyle.getVAlign();
+			String halign = cellStyle.getHAlign();
+
+			drawString(page, contentStream, contentx, contenty, width, height,
+					padding, abstractTable, doc, cell, fontSize, textHeight,
+					valign, halign, tlines, textFont, formResources, settings);
+		} catch (IOException e) {
+			logger.error("IO Exception", e);
+			throw new PdfAsException("Error", e);
+		}
+	}
+
+	public static void drawValue(PDPage page,
+			PDPageContentStream contentStream, float contentx, float contenty,
+			float width, float height, float padding,
+			PDFBoxTable abstractTable, PDDocument doc, Entry cell,
+			PDResources formResources, ISettings settings)
+			throws PdfAsException {
+
+		logger.debug("Drawing Value @ X: {} Y: {}", contentx, contenty);
+
+		try {
+			float fontSize = PDFBoxFont.defaultFontSize;
+			PDFont textFont = PDFBoxFont.defaultFont;
+
+			textFont = abstractTable.getValueFont().getFont(doc);
+			fontSize = abstractTable.getValueFont().getFontSize();
+
+			// get the cell Text
+			String text = (String) cell.getValue();
+			String[] tlines = text.split("\n");
+			float textHeight = fontSize * tlines.length;
+
+			Style cellStyle = cell.getStyle();
+			String valign = cellStyle.getValueVAlign();
+			String halign = cellStyle.getValueHAlign();
+
+			drawString(page, contentStream, contentx, contenty, width, height,
+					padding, abstractTable, doc, cell, fontSize, textHeight,
+					valign, halign, tlines, textFont, formResources, settings);
+		} catch (IOException e) {
+			logger.error("IO Exception", e);
+			throw new PdfAsException("Error", e);
+		}
+	}
+
+	public static void drawImage(PDPage page,
+			PDPageContentStream contentStream, float contentx, float contenty,
+			float width, float height, float padding,
+			PDFBoxTable abstractTable, PDDocument doc, Entry cell,
+			PDResources formResources, Map<String, ImageObject> images,
+			ISettings settings) throws PdfAsException {
+		try {
+			float innerHeight = height;
+			float innerWidth = width;
+						
+			String img_ref = (String) cell.getValue();
+			if (!images.containsKey(img_ref)) {
+				logger.error("Image not prepared! : " + img_ref);
+				throw new PdfAsException("Image not prepared! : " + img_ref);
+			}
+			ImageObject image = images.get(img_ref);
+			PDXObjectImage pdImage = image.getImage();
+
+			float imgx = contentx;
+			float hoffset = innerWidth - image.getWidth();
+			if (cell.getStyle().getImageHAlign() != null
+					&& cell.getStyle().getImageHAlign().equals(Style.LEFT)) {
+				hoffset = hoffset / 2.0f;
+				imgx += hoffset;
+			} else if (cell.getStyle().getImageHAlign() != null
+					&& cell.getStyle().getImageHAlign().equals(Style.RIGHT)) {
+				imgx += hoffset;
+			} else {
+				hoffset = hoffset / 2.0f;
+				imgx += hoffset;
+			}
+
+			float imgy = contenty;
+			float voffset = innerHeight - image.getHeight();
+			if (cell.getStyle().getImageVAlign() != null
+					&& cell.getStyle().getImageVAlign().equals(Style.MIDDLE)) {
+				voffset = voffset / 2.0f;
+				imgy -= voffset;
+			} else if (cell.getStyle().getImageVAlign() != null
+					&& cell.getStyle().getImageVAlign().equals(Style.BOTTOM)) {
+				imgy -= voffset;
+			}
+
+			drawDebugLine(contentStream, imgx, imgy, image.getWidth(),
+					image.getHeight(), settings);
+
+			// logger.debug("Image: " + imgx + " : " + (imgy -
+			// image.getHeight()));
+			contentStream.drawXObject(pdImage, imgx, imgy - image.getHeight(),
+					image.getWidth(), image.getHeight());
+		} catch (IOException e) {
+			logger.error("IO Exception", e);
+			throw new PdfAsException("Error", e);
+		}
+
+	}
+
+	public static float[] getColSizes(PDFBoxTable abstractTable) {
+		float[] origcolsSizes = abstractTable.getColsRelativeWith();
+		int max_cols = abstractTable.getColCount();
+		float[] colsSizes = new float[max_cols];
+		if (origcolsSizes == null) {
+			// set the column ratio for all columns to 1
+			for (int cols_idx = 0; cols_idx < colsSizes.length; cols_idx++) {
+				colsSizes[cols_idx] = 1;
+			}
+		} else {
+			// set the column ratio for all columns to 1
+			for (int cols_idx = 0; cols_idx < colsSizes.length; cols_idx++) {
+				colsSizes[cols_idx] = origcolsSizes[cols_idx];
+			}
+		}
+
+		// adapt
+		float total = 0;
+
+		for (int cols_idx = 0; cols_idx < colsSizes.length; cols_idx++) {
+			total += colsSizes[cols_idx];
+		}
+
+		for (int cols_idx = 0; cols_idx < colsSizes.length; cols_idx++) {
+			colsSizes[cols_idx] = (colsSizes[cols_idx] / total)
+					* abstractTable.getWidth();
+		}
+
+		float sum = 0;
+
+		for (int cols_idx = 0; cols_idx < colsSizes.length; cols_idx++) {
+			sum += colsSizes[cols_idx];
+		}
+
+		logger.debug("Table Col Sizes SUM {} Table Width {}", sum,
+				abstractTable.getWidth());
+		logger.debug("Table Table Height {}", abstractTable.getHeight());
+
+		return colsSizes;
+	}
+
+	public static void drawBorder(PDPage page,
+			PDPageContentStream contentStream, float x, float y, float width,
+			float height, PDFBoxTable abstractTable, PDDocument doc,
+			boolean subtable, ISettings settings) throws PdfAsException {
+		try {
+
+			logger.debug("Drawing Table borders for "
+					+ abstractTable.getOrigTable().getName());
+
+			final int rows = abstractTable.getRowCount();
+			float border = abstractTable.style.getBorder();
+			float[] colsSizes = getColSizes(abstractTable);
+
+			if (border > 0) {
+				contentStream.setLineWidth(border);
+
+				float x_from = x;
+				float x_to = x + width;
+				float y_from = y + height;
+				float y_to = y + height;
+
+				// draw first line
+				logger.debug("ROW LINE: {} {} {} {}", x_from, y_from, x_to,
+						y_from);
+				contentStream.drawLine(x, y_from, x_to, y_from);
+
+				// Draw all row borders
+				for (int i = 0; i < rows; i++) {
+					y_from -= abstractTable.getRowHeights()[i];
+
+					// Draw row border!
+					logger.debug("ROW LINE: {} {} {} {}", x_from, y_from, x_to,
+							y_from);
+					contentStream.drawLine(x, y_from, x_to, y_from);
+
+				}
+
+				// reset y for "line feed"
+				y_from = y + height;
+				y_to = y_from - abstractTable.getRowHeights()[0];
+
+				// Draw all column borders
+				for (int i = 0; i < rows; i++) {
+					ArrayList<Entry> row = abstractTable.getRow(i);
+
+					// reset x for "line feed"
+					x_from = x;
+
+					// draw first line
+					logger.debug("COL LINE: {} {} {} {}", x_from, y_from,
+							x_from, y_to);
+
+					contentStream.drawLine(x_from, y_from, x_from, y_to);
+
+					for (int j = 0; j < row.size(); j++) {
+						Entry cell = (Entry) row.get(j);
+
+						for (int k = 0; k < cell.getColSpan(); k++) {
+							if (k + j < colsSizes.length) {
+								x_from += colsSizes[k + j];
+							}
+						}
+						logger.debug("COL LINE: {} {} {} {}", x_from, y_from,
+								x_from, y_to);
+						contentStream.drawLine(x_from, y_from, x_from, y_to);
+					}
+
+					if (i + 1 < rows) {
+						y_from = y_to;
+						y_to = y_from - abstractTable.getRowHeights()[i + 1];
+					}
+				}
+
+			}
+		} catch (Throwable e) {
+			logger.warn("drawing table borders", e);
+			throw new PdfAsException("drawing table borders", e);
+		}
+	}
+
+	public static void drawTableBackground(PDPage page,
+			PDPageContentStream contentStream, float x, float y, float width,
+			float height, PDFBoxTable abstractTable, ISettings settings)
+			throws PdfAsException {
+		try {
+			if (abstractTable.getBGColor() != null) {
+				contentStream.setNonStrokingColor(abstractTable.getBGColor());
+				contentStream.fillRect(x, y, abstractTable.getWidth(),
+						abstractTable.getHeight());
+				contentStream.setNonStrokingColor(Color.BLACK);
+			}
+		} catch (Throwable e) {
+			logger.warn("drawing table borders", e);
+			throw new PdfAsException("drawing table borders", e);
+		}
+	}
+
+	private static void drawDebugLine(PDPageContentStream contentStream,
+			float x, float y, float width, float height, ISettings settings) {
+		if ("true".equals(settings.getValue(TABLE_DEBUG))) {
+			try {
+				contentStream.setStrokingColor(Color.RED);
+				contentStream.drawLine(x, y, x + width, y);
+				contentStream.setStrokingColor(Color.BLUE);
+				contentStream.drawLine(x, y, x, y - height);
+				contentStream.setStrokingColor(Color.GREEN);
+				contentStream.drawLine(x + width, y, x + width, y - height);
+				contentStream.setStrokingColor(Color.ORANGE);
+				contentStream.drawLine(x, y - height, x + width, y - height);
+
+				contentStream.setStrokingColor(Color.BLACK);
+			} catch (Throwable e) {
+				e.printStackTrace();
+			}
+		}
+	}
+
+	private static void drawDebugPadding(PDPageContentStream contentStream,
+			float x, float y, float padding, float width, float height,
+			ISettings settings) {
+		if ("true".equals(settings.getValue(TABLE_DEBUG))) {
+			try {
+				contentStream.setStrokingColor(Color.RED);
+				contentStream.drawLine(x, y, x + padding, y - padding);
+				contentStream.drawLine(x + width, y, x + width - padding, y
+						- padding);
+				contentStream.drawLine(x + width, y - height, x + width
+						- padding, y - height + padding);
+				contentStream.drawLine(x, y - height, x + padding, y - height
+						+ padding);
+				contentStream.setStrokingColor(Color.BLACK);
+			} catch (Throwable e) {
+				e.printStackTrace();
+			}
+		}
+	}
+
+	private static String getFontID(PDFont font, PDResources resources) {
+		Iterator<java.util.Map.Entry<String, PDFont>> it = resources.getFonts()
+				.entrySet().iterator();
+		while (it.hasNext()) {
+			java.util.Map.Entry<String, PDFont> entry = it.next();
+			if (entry.getValue().equals(font)) {
+				return entry.getKey();
+			}
+		}
+		return "";
+	}
+
+}
diff --git a/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/verify/pdfbox/PDFBOXVerifier.java b/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/verify/pdfbox/PDFBOXVerifier.java
new file mode 100644
index 00000000..037dd5d8
--- /dev/null
+++ b/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/verify/pdfbox/PDFBOXVerifier.java
@@ -0,0 +1,172 @@
+package at.gv.egiz.pdfas.lib.impl.verify.pdfbox;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.pdfbox.cos.COSArray;
+import org.apache.pdfbox.cos.COSBase;
+import org.apache.pdfbox.cos.COSDictionary;
+import org.apache.pdfbox.cos.COSName;
+import org.apache.pdfbox.cos.COSString;
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.gv.egiz.pdfas.common.exceptions.PDFASError;
+import at.gv.egiz.pdfas.common.exceptions.PdfAsException;
+import at.gv.egiz.pdfas.common.settings.ISettings;
+import at.gv.egiz.pdfas.lib.api.verify.VerifyParameter;
+import at.gv.egiz.pdfas.lib.api.verify.VerifyResult;
+import at.gv.egiz.pdfas.lib.impl.ErrorExtractor;
+import at.gv.egiz.pdfas.lib.impl.verify.IVerifier;
+import at.gv.egiz.pdfas.lib.impl.verify.IVerifyFilter;
+import at.gv.egiz.pdfas.lib.impl.verify.VerifierDispatcher;
+import at.gv.egiz.pdfas.lib.impl.verify.VerifyBackend;
+
+public class PDFBOXVerifier implements VerifyBackend {
+
+	private static final Logger logger = LoggerFactory
+			.getLogger(PDFBOXVerifier.class);
+	@Override
+	public List<VerifyResult> verify(VerifyParameter parameter)
+			throws PDFASError {
+		int signatureToVerify = parameter.getWhichSignature();
+		int currentSignature = 0;
+		PDDocument doc = null;
+		try {
+			List<VerifyResult> result = new ArrayList<VerifyResult>();
+			ISettings settings = (ISettings) parameter.getConfiguration();
+			VerifierDispatcher verifier = new VerifierDispatcher(settings);
+			doc = PDDocument.load(parameter.getDataSource().getInputStream());
+
+			COSDictionary trailer = doc.getDocument().getTrailer();
+			if (trailer == null) {
+				// No signatures ...
+				return result;
+			}
+			COSDictionary root = (COSDictionary) trailer
+					.getDictionaryObject(COSName.ROOT);
+			if (root == null) {
+				// No signatures ...
+				return result;
+			}
+			COSDictionary acroForm = (COSDictionary) root
+					.getDictionaryObject(COSName.ACRO_FORM);
+			if (acroForm == null) {
+				// No signatures ...
+				return result;
+			}
+			COSArray fields = (COSArray) acroForm
+					.getDictionaryObject(COSName.FIELDS);
+			if (fields == null) {
+				// No signatures ...
+				return result;
+			}
+
+			int lastSig = -1;
+			for (int i = 0; i < fields.size(); i++) {
+				COSDictionary field = (COSDictionary) fields.getObject(i);
+				String type = field.getNameAsString("FT");
+				if ("Sig".equals(type)) {
+					lastSig = i;
+				}
+			}
+
+			byte[] inputData = IOUtils.toByteArray(parameter.getDataSource()
+					.getInputStream());
+
+			for (int i = 0; i < fields.size(); i++) {
+				COSDictionary field = (COSDictionary) fields.getObject(i);
+				String type = field.getNameAsString("FT");
+				if ("Sig".equals(type)) {
+					boolean verifyThis = true;
+
+					if (signatureToVerify >= 0) {
+						// verify only specific siganture!
+						verifyThis = signatureToVerify == currentSignature;
+					}
+
+					if (signatureToVerify == -2) {
+						verifyThis = i == lastSig;
+					}
+
+					if (verifyThis) {
+						logger.trace("Found Signature: ");
+						COSBase base = field.getDictionaryObject("V");
+						COSDictionary dict = (COSDictionary) base;
+
+						logger.debug("Signer: " + dict.getNameAsString("Name"));
+						logger.debug("SubFilter: "
+								+ dict.getNameAsString("SubFilter"));
+						logger.debug("Filter: "
+								+ dict.getNameAsString("Filter"));
+						logger.debug("Modified: " + dict.getNameAsString("M"));
+						COSArray byteRange = (COSArray) dict
+								.getDictionaryObject("ByteRange");
+
+						StringBuilder sb = new StringBuilder();
+						int[] bytes = new int[byteRange.size()];
+						for (int j = 0; j < byteRange.size(); j++) {
+							bytes[j] = byteRange.getInt(j);
+							sb.append(" " + bytes[j]);
+						}
+
+						logger.debug("ByteRange" + sb.toString());
+
+						COSString content = (COSString) dict
+								.getDictionaryObject("Contents");
+
+						ByteArrayOutputStream contentData = new ByteArrayOutputStream();
+						for (int j = 0; j < bytes.length; j = j + 2) {
+							int offset = bytes[j];
+							int length = bytes[j + 1];
+
+							contentData.write(inputData, offset, length);
+						}
+						contentData.close();
+
+						IVerifyFilter verifyFilter = verifier.getVerifier(
+								dict.getNameAsString("Filter"),
+								dict.getNameAsString("SubFilter"));
+
+						IVerifier lvlVerifier = verifier
+								.getVerifierByLevel(parameter
+										.getSignatureVerificationLevel());
+						lvlVerifier.setConfiguration(parameter
+								.getConfiguration());
+						if (verifyFilter != null) {
+							List<VerifyResult> results = verifyFilter.verify(
+									contentData.toByteArray(),
+									content.getBytes(),
+									parameter.getVerificationTime(), bytes,
+									lvlVerifier);
+							if (results != null && !results.isEmpty()) {
+								result.addAll(results);
+							}
+						}
+					}
+					currentSignature++;
+				}
+			}
+			return result;
+		} catch (IOException e) {
+			logger.error("Failed to verify document", e);
+			throw ErrorExtractor.searchPdfAsError(e);
+		} catch (PdfAsException e) {
+			logger.error("Failed to verify document", e);
+			throw ErrorExtractor.searchPdfAsError(e);
+		} finally {
+			if (doc != null) {
+				try {
+					doc.close();
+				} catch (IOException e) {
+					logger.info("Failed to close doc");
+				}
+			}
+		}
+	}
+
+}
diff --git a/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFPage.java b/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFPage.java
new file mode 100644
index 00000000..84574b41
--- /dev/null
+++ b/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFPage.java
@@ -0,0 +1,599 @@
+/*******************************************************************************
+ * <copyright> Copyright 2014 by E-Government Innovation Center EGIZ, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ * 
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ * 
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ ******************************************************************************/
+/**
+ * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ *
+ * $Id: PDFPage.java,v 1.5 2006/10/31 08:09:33 wprinz Exp $
+ */
+package at.knowcenter.wag.egov.egiz.pdf;
+
+import java.awt.Rectangle;
+import java.awt.geom.GeneralPath;
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.lang3.math.NumberUtils;
+import org.apache.pdfbox.cos.COSBase;
+import org.apache.pdfbox.cos.COSName;
+import org.apache.pdfbox.cos.COSStream;
+import org.apache.pdfbox.pdmodel.PDPage;
+import org.apache.pdfbox.pdmodel.PDResources;
+import org.apache.pdfbox.pdmodel.common.PDRectangle;
+import org.apache.pdfbox.pdmodel.common.PDStream;
+import org.apache.pdfbox.pdmodel.font.PDFont;
+import org.apache.pdfbox.pdmodel.graphics.xobject.PDXObject;
+import org.apache.pdfbox.pdmodel.graphics.xobject.PDXObjectForm;
+import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotation;
+import org.apache.pdfbox.util.Matrix;
+import org.apache.pdfbox.util.PDFOperator;
+import org.apache.pdfbox.util.PDFTextStripper;
+import org.apache.pdfbox.util.TextPosition;
+import org.apache.pdfbox.util.operator.OperatorProcessor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.construction.ClosePath;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.construction.CurveTo;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.construction.CurveToReplicateFinalPoint;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.construction.CurveToReplicateInitialPoint;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.construction.LineTo;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.construction.MoveTo;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.painting.CloseAndStrokePath;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.painting.CloseFillEvenOddAndStrokePath;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.painting.CloseFillNonZeroAndStrokePath;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.painting.EndPath;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.painting.FillEvenOddAndStrokePath;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.painting.FillNonZeroAndStrokePath;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.painting.FillPathEvenOddRule;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.painting.FillPathNonZeroWindingNumberRule;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.painting.StrokePath;
+
+/**
+ * PDFPage is an inner class that is used to calculate the page length of a PDF
+ * Document page. It extends the PDFTextStripper class and implement one
+ * interested method: {@link at.knowcenter.wag.egov.egiz.pdf.PDFPage#showCharacter(TextPosition)}<br>
+ * This method is called when processing the FileStream. By calling the method
+ * {@link org.apache.pdfbox.util.PDFStreamEngine#processStream(org.apache.pdfbox.pdmodel.PDPage, org.apache.pdfbox.pdmodel.PDResources, org.pdfbox.cos.COSStream)}
+ * the implemented method showCharacter is called.
+ * 
+ * @author wlackner
+ * @see PDFTextStripper
+ */
+public class PDFPage extends PDFTextStripper {
+	/**
+	 * The logger definition.
+	 */
+    private static final Logger logger = LoggerFactory.getLogger(PDFPage.class);
+
+	/**
+	 * The maximum (lowest) y position of a character.
+	 */
+	protected float max_character_ypos = Float.NEGATIVE_INFINITY;
+
+	/**
+	 * The maximum (lowest y position of an image.
+	 */
+	protected float max_image_ypos = Float.NEGATIVE_INFINITY;
+
+	/**
+	 * The effective page height.
+	 */
+	protected float effectivePageHeight;
+
+	/**
+	 * The path currently being constructed.
+	 */
+	private GeneralPath currentPath = new GeneralPath();
+
+	/**
+	 * The lowest position of a drawn path (originating from top).
+	 */
+	private float maxPathRelatedYPositionFromTop = Float.NEGATIVE_INFINITY;
+
+	/**
+	 * Constructor.
+	 * 
+	 * @param effectivePageHeight
+	 *            The height of the page to be evaluated. PDF elements outside
+	 *            this height will not be considered.
+	 * 
+	 * @throws java.io.IOException
+	 */
+	public PDFPage(float effectivePageHeight, boolean legacy32) throws IOException {
+		super();
+
+		this.effectivePageHeight = effectivePageHeight;
+
+		OperatorProcessor newInvoke = new MyInvoke(this);
+		newInvoke.setContext(this);
+        this.registerOperatorProcessor("Do", newInvoke);
+        
+		if (!legacy32) {
+			registerCustomPathOperators();
+		}
+	}
+
+	/**
+	 * Registers operators responsible for path construction and painting in
+	 * order to fix auto positioning on pages with path elements.
+	 * 
+	 * @author Datentechnik Innovation GmbH
+	 */
+	private void registerCustomPathOperators() {
+
+		// *** path construction
+
+        this.registerOperatorProcessor("m", new MoveTo(this));
+        this.registerOperatorProcessor("l", new LineTo(this));
+        this.registerOperatorProcessor("c", new CurveTo(this));
+        this.registerOperatorProcessor("y", new CurveToReplicateFinalPoint(this));
+        this.registerOperatorProcessor("v", new CurveToReplicateInitialPoint(this));
+        this.registerOperatorProcessor("h", new ClosePath(this));
+
+		// *** path painting
+
+		// "S": stroke path
+        this.registerOperatorProcessor("S", new StrokePath(this));
+        this.registerOperatorProcessor("s", new CloseAndStrokePath(this));
+        this.registerOperatorProcessor("f", new FillPathNonZeroWindingNumberRule(this));
+        this.registerOperatorProcessor("F", new FillPathNonZeroWindingNumberRule(this));
+        this.registerOperatorProcessor("f*", new FillPathEvenOddRule(this));
+        this.registerOperatorProcessor("b", new CloseFillNonZeroAndStrokePath(this));
+        this.registerOperatorProcessor("B", new FillNonZeroAndStrokePath(this));
+        this.registerOperatorProcessor("b*", new CloseFillEvenOddAndStrokePath(this));
+        this.registerOperatorProcessor("B*", new FillEvenOddAndStrokePath(this));
+        this.registerOperatorProcessor("n", new EndPath(this));
+
+		// Note: The graphic context
+		// (org.pdfbox.pdmodel.graphics.PDGraphicsState) of the underlying
+		// pdfbox library does
+		// not yet support clipping. This prevents feasible usage of clipping
+		// operators (W, W*).
+		// operators.put("W", new ...(this));
+		// operators.put("W*", new ...(this));
+
+	}
+
+	/**
+	 * Returns the path currently being constructed.
+	 * 
+	 * @return The path currently being constructed.
+	 */
+	public GeneralPath getCurrentPath() {
+		return currentPath;
+	}
+
+	/**
+	 * Sets the current path.
+	 * 
+	 * @param currentPath
+	 *            The new current path.
+	 */
+	public void setCurrentPath(GeneralPath currentPath) {
+		this.currentPath = currentPath;
+	}
+
+	/**
+	 * Registers a rectangle that bounds the path currently being drawn.
+	 * 
+	 * @param bounds
+	 *            A rectangle depicting the bounds (coordinates originating from
+	 *            bottom left).
+	 * @author Datentechnik Innovation GmbH
+	 */
+	public void registerPathBounds(Rectangle bounds) {
+		if (!bounds.isEmpty()) {
+			logger.debug("Registering path bounds: " + bounds);
+
+			// vertical start of rectangle (counting from top of page)
+			float upperBoundYPositionFromTop;
+
+			// vertical end of rectangle (counting from top of page)
+			// this depicts the current end of path-related page content
+			float lowerBoundYPositionFromTop;
+
+			PDRectangle boundaryBox = this.getCurrentPage().findMediaBox();
+			float pageHeight;
+
+			switch (this.getCurrentPage().findRotation()) {
+			case 90: // CW
+				pageHeight = boundaryBox.getWidth();
+				upperBoundYPositionFromTop = (float) bounds.getMinX();
+				lowerBoundYPositionFromTop = (float) bounds.getMaxX();
+				break;
+			case 180:
+				pageHeight = boundaryBox.getHeight();
+				upperBoundYPositionFromTop = (float) bounds.getMinY();
+				lowerBoundYPositionFromTop = (float) bounds.getMaxY();
+				break;
+			case 270: // CCW
+				pageHeight = boundaryBox.getWidth();
+				upperBoundYPositionFromTop = pageHeight
+						- (float) bounds.getMaxX();
+				lowerBoundYPositionFromTop = pageHeight
+						- (float) bounds.getMinX();
+				break;
+			default:
+				pageHeight = boundaryBox.getHeight();
+				upperBoundYPositionFromTop = pageHeight
+						- (float) bounds.getMaxY();
+				lowerBoundYPositionFromTop = pageHeight
+						- (float) bounds.getMinY();
+				break;
+			}
+
+			// new maximum ?
+			if (lowerBoundYPositionFromTop > maxPathRelatedYPositionFromTop) {
+				// Is the rectangle (at least partly) located above the footer
+				// line?
+				// (effective page height := page height - footer line)
+				if (upperBoundYPositionFromTop <= effectivePageHeight) {
+					// yes: update current end of path-related page content
+					maxPathRelatedYPositionFromTop = lowerBoundYPositionFromTop;
+					logger.trace("New max path related y position (from top): "
+							+ maxPathRelatedYPositionFromTop);
+				} else {
+					// no: rectangle is fully located below the footer line ->
+					// ignore
+					logger.trace("Ignoring path bound below the footer line.");
+				}
+			}
+		}
+	}
+
+	protected void processOperator(PDFOperator operator, List<COSBase> arguments)
+			throws IOException {
+		logger.trace("operator = " + operator);
+		super.processOperator(operator, arguments);
+	}
+
+	@Override
+	protected void processTextPosition(TextPosition text) {
+		showCharacter(text);
+	}
+	
+	// exthex
+	/**
+	 * A method provided as an event interface to allow a subclass to perform
+	 * some specific functionality when a character needs to be displayed. This
+	 * method is used to calculate the latest position of a text in the page.
+	 * Sorry for this missinterpretation of the method, but it is the only way
+	 * to do this (provided by PDFBox)!!!
+	 * 
+	 * @param text
+	 *            the character to be displayed -> calculate there y position.
+	 */
+	protected void showCharacter(TextPosition text) {
+		float current_y = text.getY();
+		final String character = text.getCharacter();
+
+		int pageRotation = this.getCurrentPage().findRotation();
+		// logger_.debug("PageRotation = " + pageRotation);
+		if (pageRotation == 0) {
+			current_y = text.getY();
+		}
+		if (pageRotation == 90) {
+			current_y = text.getX();
+		}
+		if (pageRotation == 180) {
+			float page_height = this.getCurrentPage().findMediaBox().getHeight();
+			current_y = page_height - text.getY();
+		}
+		if (pageRotation == 270) {
+			float page_height = this.getCurrentPage().findMediaBox().getHeight();
+			current_y = page_height - text.getX();
+		}
+
+		if (current_y > this.effectivePageHeight) {
+			// logger_.debug("character is below footer_line. footer_line = " +
+			// this.footer_line + ", text.character=" + character + ", y=" +
+			// current_y);
+			return;
+		}
+
+		// store ypos of the char if it is not empty
+		if (!at.gv.egiz.pdfas.common.utils.StringUtils.whiteSpaceTrim(character).isEmpty() && 
+				current_y > this.max_character_ypos) {
+			this.max_character_ypos = current_y;
+		}
+
+	}
+
+	// use this funtion getting an unsorted text output
+	// public void showString(byte[] string) {
+	// logger_.debug(new String(string));
+	// }
+
+	/**
+	 * Returns the calculated page length.
+	 * 
+	 * @return the max page length value
+	 */
+	public float getMaxPageLength() {
+		if (logger.isDebugEnabled()) {
+			logger.debug("Determining page content length: text="
+					+ max_character_ypos + ", image=" + max_image_ypos
+					+ ", path=" + maxPathRelatedYPositionFromTop);
+		}
+		return NumberUtils.max(max_character_ypos, max_image_ypos,
+                maxPathRelatedYPositionFromTop);
+	}
+
+	@Override
+	public Map<String, PDFont> getFonts() {
+		
+		COSBase fontObj = null;
+		
+		if(getCurrentPage().getResources() != null && 
+				getCurrentPage().getResources().getCOSDictionary() != null &&
+				getCurrentPage().getResources().getCOSDictionary().getDictionaryObject(COSName.FONT) != null) {
+			fontObj = getCurrentPage().getResources().getCOSDictionary().getDictionaryObject(COSName.FONT);
+		}
+		Map<String, PDFont> fontMap = getCurrentPage().findResources().getFonts();
+		
+		if(fontObj != null) {
+			getCurrentPage().getResources().getCOSDictionary().setItem(COSName.FONT, fontObj);
+		}
+		
+		return fontMap;
+	}
+	
+	public class MyInvoke extends OperatorProcessor {
+
+        private PDFPage mypage;
+
+        public MyInvoke(PDFPage page) {
+            this.mypage = page;
+        }
+
+		public void process(PDFOperator operator, List<COSBase> arguments)
+				throws IOException {
+			COSName name = (COSName) arguments.get(0);
+
+			// PDResources res = context.getResources();
+
+			Map<String, PDXObject> xobjects = context.getXObjects();
+			PDXObject xobject = xobjects.get(name.getName());
+
+			PDStream stream = xobject.getPDStream();
+			COSStream cos_stream = stream.getStream();
+
+			COSName subtype = (COSName) cos_stream
+					.getDictionaryObject(COSName.SUBTYPE);
+			if (subtype.equals(COSName.IMAGE)) {
+				logger.debug("XObject Image");
+
+				Matrix ctm = context.getGraphicsState()
+						.getCurrentTransformationMatrix();
+                logger.debug("ctm = " + ctm);
+
+				Pos[] coordinates = new Pos[] { new Pos(0, 0, 1),
+						new Pos(1, 0, 1), new Pos(0, 1, 1), new Pos(1, 1, 1) };
+
+				Pos[] transformed_coordinates = transtormCoordinates(
+						coordinates, ctm);
+
+				/**********************************************************
+				 * pdf-as fix: calculating min and max point of an image to look
+				 * where the signature should be placed fix solves problems with
+				 * footer and images and placement of the signature in an image
+				 * only pdf document
+				 **********************************************************/
+
+				float actual_lowest_point = Float.NaN;
+				float actual_starting_point = Float.NaN;
+
+				int pageRotation = this.mypage.getCurrentPage().findRotation();
+				logger.debug("PageRotation = " + pageRotation);
+				if (pageRotation == 0) {
+					float min_y = findMinY(transformed_coordinates);
+                    logger.debug("min_y = " + min_y);
+					float page_height = this.mypage.getCurrentPage().findMediaBox().getHeight();
+                    logger.debug("page_height = " + page_height);
+
+					actual_lowest_point = page_height - min_y;
+					actual_starting_point = page_height
+							- findMaxY(transformed_coordinates);
+				}
+				if (pageRotation == 90) {
+					float max_x = findMaxX(transformed_coordinates);
+                    logger.debug("max_x = " + max_x);
+					float page_width = this.mypage.getCurrentPage().findMediaBox().getWidth();
+                    logger.debug("page_width = " + page_width);
+
+					actual_lowest_point = max_x;
+					actual_starting_point = findMinX(transformed_coordinates);
+				}
+				if (pageRotation == 180) {
+					float min_y = findMinY(transformed_coordinates);
+                    logger.debug("min_y = " + min_y);
+					float page_height = this.mypage.getCurrentPage().findMediaBox().getHeight();
+					actual_lowest_point = page_height
+							- findMaxY(transformed_coordinates);
+					actual_starting_point = page_height - min_y;
+				}
+				if (pageRotation == 270) {
+					float min_x = findMinX(transformed_coordinates);
+                    logger.debug("min_x = " + min_x);
+
+					float page_width = this.mypage.getCurrentPage().findMediaBox().getWidth();
+                    logger.debug("page_width = " + page_width);
+
+					actual_lowest_point = page_width - min_x;
+					actual_starting_point = page_width
+							- findMaxX(transformed_coordinates);
+				}
+
+                logger.debug("actual_lowest_point = " + actual_lowest_point);
+
+				if (actual_lowest_point > PDFPage.this.effectivePageHeight
+						&& actual_starting_point > PDFPage.this.effectivePageHeight) {
+                    logger.debug("image is below footer_line");
+					return;
+				}
+
+				if (actual_lowest_point > PDFPage.this.max_image_ypos) {
+					PDFPage.this.max_image_ypos = actual_lowest_point;
+				}
+
+				return;
+			}
+
+			if (xobject instanceof PDXObjectForm) {
+				PDXObjectForm form = (PDXObjectForm) xobject;
+				COSStream invoke = (COSStream) form.getCOSObject();
+				PDResources pdResources = form.getResources();
+				PDPage page = context.getCurrentPage();
+				if (pdResources == null) {
+					pdResources = page.findResources();
+				}
+
+				getContext().processSubStream(page, pdResources, invoke);
+			}
+		}
+	}
+
+	public static Pos[] transtormCoordinates(Pos[] coordinates, Matrix m) {
+		Pos[] transformed = new Pos[coordinates.length];
+		for (int i = 0; i < coordinates.length; i++) {
+			transformed[i] = transtormCoordinate(coordinates[i], m);
+		}
+		return transformed;
+	}
+
+	public static Pos transtormCoordinate(Pos pos, Matrix m) {
+		Pos transformed = new Pos();
+		transformed.x = pos.x * m.getValue(0, 0) + pos.y * m.getValue(1, 0)
+				+ pos.z * m.getValue(2, 0);
+		transformed.y = pos.x * m.getValue(0, 1) + pos.y * m.getValue(1, 1)
+				+ pos.z * m.getValue(2, 1);
+		transformed.z = pos.x * m.getValue(0, 2) + pos.y * m.getValue(1, 2)
+				+ pos.z * m.getValue(2, 2);
+
+        logger.debug(" transformed " + pos + " --> " + transformed);
+		return transformed;
+	}
+
+	public static float findMinY(Pos[] coordinates) {
+		float min = Float.POSITIVE_INFINITY;
+		for (int i = 0; i < coordinates.length; i++) {
+			if (coordinates[i].y < min) {
+				min = coordinates[i].y;
+			}
+		}
+		return min;
+	}
+
+	public static float findMaxY(Pos[] coordinates) {
+		float max = 0;
+		for (int i = 0; i < coordinates.length; i++) {
+			if (coordinates[i].y > max) {
+				max = coordinates[i].y;
+			}
+		}
+		return max;
+	}
+
+	public static float findMaxX(Pos[] coordinates) {
+		float max = Float.NEGATIVE_INFINITY;
+		for (int i = 0; i < coordinates.length; i++) {
+			if (coordinates[i].x > max) {
+				max = coordinates[i].x;
+			}
+		}
+		return max;
+	}
+
+	public static float findMinX(Pos[] coordinates) {
+		float min = Float.POSITIVE_INFINITY;
+		for (int i = 0; i < coordinates.length; i++) {
+			if (coordinates[i].x < min) {
+				min = coordinates[i].x;
+			}
+		}
+		return min;
+	}
+
+	public void processAnnotation(PDAnnotation anno) {
+		float current_y = anno.getRectangle().getLowerLeftY();
+		PDPage page = anno.getPage();
+		
+		if(page == null) {
+			page = getCurrentPage();
+		}
+		
+		if(page == null) {
+			logger.warn("Annotation without page! The position might not be correct!");
+			return;
+		}
+		
+		int pageRotation = page.findRotation();
+		// logger_.debug("PageRotation = " + pageRotation);
+		if (pageRotation == 0) {
+			float page_height = page.findMediaBox().getHeight();
+			current_y = page_height - anno.getRectangle().getLowerLeftY();
+		}
+		if (pageRotation == 90) {
+			current_y = anno.getRectangle().getLowerLeftX();
+		}
+		if (pageRotation == 180) {
+			current_y = anno.getRectangle().getUpperRightY();
+		}
+		if (pageRotation == 270) {
+			float page_height = page.findMediaBox().getHeight();
+			current_y = page_height - anno.getRectangle().getUpperRightX();
+		}
+
+		if (current_y > this.effectivePageHeight) {
+			return;
+		}
+
+		// store ypos of the char if it is not empty
+		if (current_y > this.max_character_ypos) {
+			this.max_character_ypos = current_y;
+		}
+	}
+	
+}
diff --git a/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFUtilities.java b/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFUtilities.java
new file mode 100644
index 00000000..808efbe4
--- /dev/null
+++ b/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFUtilities.java
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * <copyright> Copyright 2014 by E-Government Innovation Center EGIZ, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ * 
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ * 
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ ******************************************************************************/
+/**
+ * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ *
+ * $Id: PDFUtilities.java,v 1.3 2006/10/31 08:09:33 wprinz Exp $
+ */
+package at.knowcenter.wag.egov.egiz.pdf;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.pdfbox.cos.COSStream;
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.pdmodel.PDPage;
+import org.apache.pdfbox.pdmodel.PDResources;
+import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotation;
+
+import at.gv.egiz.pdfas.common.exceptions.PDFIOException;
+
+/**
+ * Contains useful helpers for accessing PDF documents.
+ *
+ * @author wprinz
+ * @author mruhmer
+ */
+public abstract class PDFUtilities {
+	public static float calculatePageLength(PDDocument document, int page,
+			float effectivePageHeight, /* int pagerotation, */boolean legacy32)
+			throws PDFIOException {
+		// int last_page_id = document.getNumberOfPages();
+		List<?> allPages = document.getDocumentCatalog().getAllPages();
+		PDPage pdpage = (PDPage) allPages.get(page);
+		// pdpage.setRotation(pagerotation);
+		return calculatePageLength(pdpage, effectivePageHeight, legacy32);
+	}
+
+	public static float calculatePageLength(PDPage page,
+			float effectivePageHeight, boolean legacy32) throws PDFIOException {
+		try {
+			PDFPage my_page = new PDFPage(effectivePageHeight, legacy32);
+			PDResources resources = page.findResources();
+			if (page.getContents() != null) {
+				COSStream stream = page.getContents().getStream();
+				// List<PDThreadBead> articles = page.getThreadBeads();
+				// my_page.processMyPage(page);
+				my_page.processStream(page, resources, stream);
+			}
+			if (!legacy32) {
+				if (page.getAnnotations() != null) {
+					Iterator<PDAnnotation> annotationsIt = page
+							.getAnnotations().iterator();
+
+					while (annotationsIt.hasNext()) {
+						PDAnnotation annotation = annotationsIt.next();
+						if (!annotation.isInvisible()) {
+							my_page.processAnnotation(annotation);
+						}
+					}
+				}
+			}
+			return my_page.getMaxPageLength();
+		} catch (IOException e) {
+			throw new PDFIOException("error.pdf.stamp.11", e);
+		}
+	}
+
+}
diff --git a/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/PathConstructionOperatorProcessor.java b/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/PathConstructionOperatorProcessor.java
new file mode 100644
index 00000000..2e16c117
--- /dev/null
+++ b/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/PathConstructionOperatorProcessor.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * <copyright> Copyright 2014 by E-Government Innovation Center EGIZ, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ * 
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ * 
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ ******************************************************************************/
+/**
+ * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.knowcenter.wag.egov.egiz.pdf.operator.path;
+
+import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
+import org.apache.pdfbox.util.operator.OperatorProcessor;
+
+import java.awt.geom.Point2D;
+
+/**
+ * Provides functions for path construction operators.
+ *
+ * @see "PDF 1.7 specification, Section 8.5.2 'Path Construction Operators'"
+ * @author Datentechnik Innovation GmbH
+ *
+ */
+public abstract class PathConstructionOperatorProcessor extends OperatorProcessor {
+
+	public PathConstructionOperatorProcessor(PDFPage context) {
+		setContext(context);
+	}
+
+	/**
+	 * Transforms the given point from user space coordinates to device space coordinates based on the current
+	 * transition matrix.
+	 *
+	 * @param x
+	 *            The x axis value of the user space coordinates.
+	 * @param y
+	 *            The y axis value of the user space coordinates.
+	 * @return The transformed point.
+	 */
+	public Point2D transform(double x, double y) {
+		double[] position = { x, y };
+		context.getGraphicsState().getCurrentTransformationMatrix().createAffineTransform()
+				.transform(position, 0, position, 0, 1);
+		return new Point2D.Double(position[0], position[1]);
+	}
+
+}
diff --git a/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/PathPaintingOperatorProcessor.java b/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/PathPaintingOperatorProcessor.java
new file mode 100644
index 00000000..bc34d562
--- /dev/null
+++ b/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/PathPaintingOperatorProcessor.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * <copyright> Copyright 2014 by E-Government Innovation Center EGIZ, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ * 
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ * 
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ ******************************************************************************/
+/**
+ * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.knowcenter.wag.egov.egiz.pdf.operator.path;
+
+import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
+import org.apache.pdfbox.util.operator.OperatorProcessor;
+
+/**
+ * Provides functions for path painting operators.
+ *
+ * @see "PDF 1.7 specification, Section 8.5.2 'Path Construction Operators'"
+ * @author Datentechnik Innovation GmbH
+ *
+ */
+public abstract class PathPaintingOperatorProcessor extends OperatorProcessor {
+
+	public PathPaintingOperatorProcessor(PDFPage context) {
+		setContext(context);
+	}
+
+}
diff --git a/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/ClosePath.java b/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/ClosePath.java
new file mode 100644
index 00000000..8bb76fb5
--- /dev/null
+++ b/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/ClosePath.java
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * <copyright> Copyright 2014 by E-Government Innovation Center EGIZ, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ * 
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ * 
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ ******************************************************************************/
+/**
+ * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.knowcenter.wag.egov.egiz.pdf.operator.path.construction;
+
+import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathConstructionOperatorProcessor;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.pdfbox.cos.COSBase;
+import org.apache.pdfbox.util.PDFOperator;
+
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * Close the current subpath by appending a straight line segment from the current point to the starting point of the
+ * subpath. If the current subpath is already closed, h shall donothing. This operator terminates the current subpath.
+ * Appending another segment to the current path shall begin a new subpath, even if the new segment begins at the
+ * endpoint reached by the h operation.
+ *
+ * @see "PDF 1.7 specification, Section 8.5.2 'Path Construction Operators'"
+ * @author PdfBox, modified by Datentechnik Innovation GmbH
+ */
+public class ClosePath extends PathConstructionOperatorProcessor {
+
+	private Log log = LogFactory.getLog(getClass());
+
+	public ClosePath(PDFPage context) {
+		super(context);
+	}
+
+	@Override
+	public void process(PDFOperator operator, List<COSBase> operands) throws IOException {
+		try {
+			PDFPage pdfPage = (PDFPage) context;
+
+			pdfPage.getCurrentPath().closePath();
+
+			if (log.isTraceEnabled()) {
+				log.trace("Closing current path.");
+			}
+		} catch (Exception e) {
+			log.warn("Error processing operator 'h'.", e);
+		}
+	}
+
+}
diff --git a/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveTo.java b/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveTo.java
new file mode 100644
index 00000000..0eb10a52
--- /dev/null
+++ b/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveTo.java
@@ -0,0 +1,108 @@
+/*******************************************************************************
+ * <copyright> Copyright 2014 by E-Government Innovation Center EGIZ, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ * 
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ * 
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ ******************************************************************************/
+/**
+ * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.knowcenter.wag.egov.egiz.pdf.operator.path.construction;
+
+import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathConstructionOperatorProcessor;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.pdfbox.cos.COSBase;
+import org.apache.pdfbox.cos.COSNumber;
+import org.apache.pdfbox.util.PDFOperator;
+
+import java.awt.geom.Point2D;
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * Append a cubic Bezier curve to the current path. The curve shall extend from the current point to the point (x3, y3),
+ * using (x1, y1) and (x2, y2) as the Bezier control points (see 8.5.2.2, "Cubic Bezier Curves"). The new current point
+ * shall be (x3, y3).
+ *
+ * @see "PDF 1.7 specification, Section 8.5.2 'Path Construction Operators'"
+ * @author PdfBox, modified by Datentechnik Innovation GmbH
+ */
+public class CurveTo extends PathConstructionOperatorProcessor {
+
+	private Log log = LogFactory.getLog(getClass());
+
+	public CurveTo(PDFPage context) {
+		super(context);
+	}
+
+	@Override
+	public void process(PDFOperator operator, List<COSBase> operands) throws IOException {
+		try {
+			PDFPage pdfPage = (PDFPage) context;
+
+			COSNumber x1 = (COSNumber) operands.get(0);
+			COSNumber y1 = (COSNumber) operands.get(1);
+			COSNumber x2 = (COSNumber) operands.get(2);
+			COSNumber y2 = (COSNumber) operands.get(3);
+			COSNumber x3 = (COSNumber) operands.get(4);
+			COSNumber y3 = (COSNumber) operands.get(5);
+
+			Point2D p1 = transform(x1.doubleValue(), y1.doubleValue());
+			Point2D p2 = transform(x2.doubleValue(), y2.doubleValue());
+			Point2D p3 = transform(x3.doubleValue(), y3.doubleValue());
+
+			pdfPage.getCurrentPath().curveTo(
+					(float) p1.getX(), (float) p1.getY(),
+					(float) p2.getX(), (float) p2.getY(),
+					(float) p3.getX(), (float) p3.getY()
+			);
+
+			if (log.isTraceEnabled()) {
+				log.trace("Appending cubic Bezier curve with x1:" + p1.getX() + ",y1:" + p1.getY() + ", x2:"
+						+ p2.getX() + ",y2:" + p2.getY() + ", x3:" + p3.getX() + ",y3:" + p3.getY());
+			}
+		} catch (Exception e) {
+			log.warn("Error processing operator 'c'.", e);
+		}
+	}
+
+}
diff --git a/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveToReplicateFinalPoint.java b/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveToReplicateFinalPoint.java
new file mode 100644
index 00000000..1020842e
--- /dev/null
+++ b/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveToReplicateFinalPoint.java
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * <copyright> Copyright 2014 by E-Government Innovation Center EGIZ, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ * 
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ * 
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ ******************************************************************************/
+/**
+ * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.knowcenter.wag.egov.egiz.pdf.operator.path.construction;
+
+import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathConstructionOperatorProcessor;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.pdfbox.cos.COSBase;
+import org.apache.pdfbox.cos.COSNumber;
+import org.apache.pdfbox.util.PDFOperator;
+
+import java.awt.geom.Point2D;
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * Append a cubic Bezier curve to the current path. The curve shall extend from the current point to the point (x3, y3),
+ * using (x1, y1) and (x3, y3) as the Bezier control points (see 8.5.2.2, "Cubic Bezier Curves"). The new current point
+ * shall be (x3, y3).
+ *
+ * @see "PDF 1.7 specification, Section 8.5.2 'Path Construction Operators'"
+ * @author PdfBox, modified by Datentechnik Innovation GmbH
+ */
+public class CurveToReplicateFinalPoint extends PathConstructionOperatorProcessor {
+
+	private Log log = LogFactory.getLog(getClass());
+
+	public CurveToReplicateFinalPoint(PDFPage context) {
+		super(context);
+	}
+
+	@Override
+	public void process(PDFOperator operator, List<COSBase> operands) throws IOException {
+		try {
+			PDFPage pdfPage = (PDFPage) context;
+
+			COSNumber x1 = (COSNumber) operands.get(0);
+			COSNumber y1 = (COSNumber) operands.get(1);
+			COSNumber x3 = (COSNumber) operands.get(2);
+			COSNumber y3 = (COSNumber) operands.get(3);
+
+			Point2D p1 = transform(x1.doubleValue(), y1.doubleValue());
+			Point2D p3 = transform(x3.doubleValue(), y3.doubleValue());
+
+			pdfPage.getCurrentPath().curveTo(
+					(float) p1.getX(), (float) p1.getY(),
+					(float) p3.getX(), (float) p3.getY(),
+					(float) p3.getX(), (float) p3.getY()
+			);
+
+			if (log.isTraceEnabled()) {
+				log.trace("Appending cubic Bezier curve with x1:" + p1.getX() + ",y1:" + p1.getY() + ", x3:"
+						+ p3.getX() + ",y3:" + p3.getY());
+			}
+		} catch (Exception e) {
+			log.warn("Error processing operator 'y'.", e);
+		}
+	}
+
+}
diff --git a/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveToReplicateInitialPoint.java b/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveToReplicateInitialPoint.java
new file mode 100644
index 00000000..42a52033
--- /dev/null
+++ b/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/CurveToReplicateInitialPoint.java
@@ -0,0 +1,107 @@
+/*******************************************************************************
+ * <copyright> Copyright 2014 by E-Government Innovation Center EGIZ, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ * 
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ * 
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ ******************************************************************************/
+/**
+ * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.knowcenter.wag.egov.egiz.pdf.operator.path.construction;
+
+import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathConstructionOperatorProcessor;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.pdfbox.cos.COSBase;
+import org.apache.pdfbox.cos.COSNumber;
+import org.apache.pdfbox.util.PDFOperator;
+
+import java.awt.geom.Point2D;
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * Append a cubic Bezier curve to the current path. The curve shall extend from the current point to the point (x3, y3),
+ * using the current point and (x2, y2) as the Bezier control points (see 8.5.2.2, "Cubic Bezier Curves"). The new
+ * current point shall be (x3, y3).
+ *
+ * @see "PDF 1.7 specification, Section 8.5.2 'Path Construction Operators'"
+ * @author PdfBox, modified by Datentechnik Innovation GmbH
+ */
+public class CurveToReplicateInitialPoint extends PathConstructionOperatorProcessor {
+
+	private Log log = LogFactory.getLog(getClass());
+
+	public CurveToReplicateInitialPoint(PDFPage context) {
+		super(context);
+	}
+
+	@Override
+	public void process(PDFOperator operator, List<COSBase> operands) throws IOException {
+		try {
+			PDFPage pdfPage = (PDFPage) context;
+
+			COSNumber x2 = (COSNumber) operands.get(0);
+			COSNumber y2 = (COSNumber) operands.get(1);
+			COSNumber x3 = (COSNumber) operands.get(2);
+			COSNumber y3 = (COSNumber) operands.get(3);
+
+	        Point2D currentPoint = pdfPage.getCurrentPath().getCurrentPoint();
+			Point2D p2 = transform(x2.doubleValue(), y2.doubleValue());
+			Point2D p3 = transform(x3.doubleValue(), y3.doubleValue());
+
+			pdfPage.getCurrentPath().curveTo(
+					(float)currentPoint.getX(), (float)currentPoint.getY(),
+					(float) p2.getX(), (float) p2.getY(),
+					(float) p3.getX(), (float) p3.getY()
+			);
+
+			if (log.isTraceEnabled()) {
+				log.trace("Appending cubic Bezier curve with x2:" + p2.getX() + ",y2:" + p2.getY() + ", x3:"
+						+ p3.getX() + ",y3:" + p3.getY() + ", using current point x:" + currentPoint.getX() + ",y:"
+						+ currentPoint.getY());
+			}
+		} catch (Exception e) {
+			log.warn("Error processing operator 'v'.", e);
+		}
+	}
+
+}
diff --git a/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/LineTo.java b/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/LineTo.java
new file mode 100644
index 00000000..a47d3fe6
--- /dev/null
+++ b/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/LineTo.java
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * <copyright> Copyright 2014 by E-Government Innovation Center EGIZ, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ * 
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ * 
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ ******************************************************************************/
+/**
+ * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.knowcenter.wag.egov.egiz.pdf.operator.path.construction;
+
+import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathConstructionOperatorProcessor;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.pdfbox.cos.COSBase;
+import org.apache.pdfbox.cos.COSNumber;
+import org.apache.pdfbox.util.PDFOperator;
+
+import java.awt.geom.Point2D;
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * Append a straight line segment from the current point to the point (x, y). The new current point shall be (x, y).
+ *
+ * @see "PDF 1.7 specification, Section 8.5.2 'Path Construction Operators'"
+ * @author PdfBox, modified by Datentechnik Innovation GmbH
+ */
+public class LineTo extends PathConstructionOperatorProcessor {
+
+	private Log log = LogFactory.getLog(getClass());
+
+	public LineTo(PDFPage context) {
+		super(context);
+	}
+
+	@Override
+	public void process(PDFOperator operator, List<COSBase> operands) throws IOException {
+		try {
+			PDFPage pdfPage = (PDFPage) context;
+
+			COSNumber x = (COSNumber) operands.get(0);
+			COSNumber y = (COSNumber) operands.get(1);
+			Point2D p = transform(x.doubleValue(), y.doubleValue());
+
+			pdfPage.getCurrentPath().lineTo((float) p.getX(), (float) p.getY());
+
+			if (log.isTraceEnabled()) {
+				log.trace("Adding line to x:" + p.getX() + ",y:" + p.getY());
+			}
+		} catch (Exception e) {
+			log.warn("Error processing operator 'l'.", e);
+		}
+	}
+
+}
diff --git a/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/MoveTo.java b/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/MoveTo.java
new file mode 100644
index 00000000..49d92761
--- /dev/null
+++ b/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/construction/MoveTo.java
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ * <copyright> Copyright 2014 by E-Government Innovation Center EGIZ, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ * 
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ * 
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ ******************************************************************************/
+/**
+ * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.knowcenter.wag.egov.egiz.pdf.operator.path.construction;
+
+import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathConstructionOperatorProcessor;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.pdfbox.cos.COSBase;
+import org.apache.pdfbox.cos.COSNumber;
+import org.apache.pdfbox.util.PDFOperator;
+
+import java.awt.geom.Point2D;
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * Begin a new subpath by moving the current point to coordinates (x, y), omitting any connecting line segment. If the
+ * previous path construction operator in the current path was also m, the new m overrides it; no vestige of the
+ * previous m operation remains in the path.
+ *
+ * @see "PDF 1.7 specification, Section 8.5.2 'Path Construction Operators'"
+ * @author PdfBox, modified by Datentechnik Innovation GmbH
+ */
+public class MoveTo extends PathConstructionOperatorProcessor {
+
+	private Log log = LogFactory.getLog(getClass());
+
+	public MoveTo(PDFPage context) {
+		super(context);
+	}
+
+	@Override
+	public void process(PDFOperator operator, List<COSBase> operands) throws IOException {
+		try {
+			PDFPage pdfPage = (PDFPage) context;
+
+			COSNumber x = (COSNumber) operands.get(0);
+			COSNumber y = (COSNumber) operands.get(1);
+			Point2D p = transform(x.doubleValue(), y.doubleValue());
+
+			pdfPage.getCurrentPath().moveTo((float) p.getX(), (float) p.getY());
+
+			if (log.isTraceEnabled()) {
+				log.trace("Moving current path to x:" + p.getX() + ",y:" + p.getY());
+			}
+		} catch (Exception e) {
+			log.warn("Error processing operator 'm'.", e);
+		}
+	}
+
+}
diff --git a/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseAndStrokePath.java b/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseAndStrokePath.java
new file mode 100644
index 00000000..552a033c
--- /dev/null
+++ b/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseAndStrokePath.java
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * <copyright> Copyright 2014 by E-Government Innovation Center EGIZ, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ * 
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ * 
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ ******************************************************************************/
+/**
+ * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.knowcenter.wag.egov.egiz.pdf.operator.path.painting;
+
+import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathPaintingOperatorProcessor;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.pdfbox.cos.COSBase;
+import org.apache.pdfbox.util.PDFOperator;
+
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * Close and stroke the path. This operator shall have the same effect as the sequence <code>h S</code>.
+ *
+ * @see "PDF 1.7 specification, Section 8.5.3 'Path-Painting Operators'"
+ * @author PdfBox, modified by Datentechnik Innovation GmbH
+ */
+public class CloseAndStrokePath extends PathPaintingOperatorProcessor {
+
+	private Log log = LogFactory.getLog(getClass());
+
+	public CloseAndStrokePath(PDFPage context) {
+		super(context);
+	}
+
+	@Override
+	public void process(PDFOperator operator, List<COSBase> operands) throws IOException {
+		if (log.isTraceEnabled()) {
+			log.trace("Closing and stroking path.");
+		}
+		context.processOperator("h", operands);
+		context.processOperator("S", operands);
+	}
+
+}
diff --git a/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseFillEvenOddAndStrokePath.java b/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseFillEvenOddAndStrokePath.java
new file mode 100644
index 00000000..718fe362
--- /dev/null
+++ b/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseFillEvenOddAndStrokePath.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * <copyright> Copyright 2014 by E-Government Innovation Center EGIZ, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ * 
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ * 
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ ******************************************************************************/
+/**
+ * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.knowcenter.wag.egov.egiz.pdf.operator.path.painting;
+
+import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathPaintingOperatorProcessor;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.pdfbox.cos.COSBase;
+import org.apache.pdfbox.util.PDFOperator;
+
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * Close, fill, and then stroke the path, using the even-odd rule to determine the region to fill. This operator shall
+ * have the same effect as the sequence <code>h B*</code>.
+ *
+ * @see "PDF 1.7 specification, Section 8.5.3 'Path-Painting Operators'"
+ * @author PdfBox, modified by Datentechnik Innovation GmbH
+ */
+public class CloseFillEvenOddAndStrokePath extends PathPaintingOperatorProcessor {
+
+	private Log log = LogFactory.getLog(getClass());
+
+	public CloseFillEvenOddAndStrokePath(PDFPage context) {
+		super(context);
+	}
+
+	@Override
+	public void process(PDFOperator operator, List<COSBase> operands) throws IOException {
+		if (log.isTraceEnabled()) {
+			log.trace("Closing, filling (even odd rule) and stroking path.");
+		}
+		context.processOperator("h", operands);
+		context.processOperator("B*", operands);
+	}
+
+}
diff --git a/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseFillNonZeroAndStrokePath.java b/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseFillNonZeroAndStrokePath.java
new file mode 100644
index 00000000..523f6681
--- /dev/null
+++ b/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/CloseFillNonZeroAndStrokePath.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * <copyright> Copyright 2014 by E-Government Innovation Center EGIZ, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ * 
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ * 
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ ******************************************************************************/
+/**
+ * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.knowcenter.wag.egov.egiz.pdf.operator.path.painting;
+
+import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathPaintingOperatorProcessor;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.pdfbox.cos.COSBase;
+import org.apache.pdfbox.util.PDFOperator;
+
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * Close, fill, and then stroke the path, using the nonzero winding number rule to determine the region to fill. This
+ * operator shall have the same effect as the sequence <code>h B</code>.
+ *
+ * @see "PDF 1.7 specification, Section 8.5.3 'Path-Painting Operators'"
+ * @author PdfBox, modified by Datentechnik Innovation GmbH
+ */
+public class CloseFillNonZeroAndStrokePath extends PathPaintingOperatorProcessor {
+
+	private Log log = LogFactory.getLog(getClass());
+
+	public CloseFillNonZeroAndStrokePath(PDFPage context) {
+		super(context);
+	}
+
+	@Override
+	public void process(PDFOperator operator, List<COSBase> operands) throws IOException {
+		if (log.isTraceEnabled()) {
+			log.trace("Closing, filling (non zero rule) and stroking path.");
+		}
+		context.processOperator("h", operands);
+		context.processOperator("B", operands);
+	}
+
+}
diff --git a/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/EndPath.java b/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/EndPath.java
new file mode 100644
index 00000000..5134ed2f
--- /dev/null
+++ b/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/EndPath.java
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * <copyright> Copyright 2014 by E-Government Innovation Center EGIZ, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ * 
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ * 
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ ******************************************************************************/
+/**
+ * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.knowcenter.wag.egov.egiz.pdf.operator.path.painting;
+
+import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathPaintingOperatorProcessor;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.pdfbox.cos.COSBase;
+import org.apache.pdfbox.util.PDFOperator;
+
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * End the path object without filling or stroking it. This operator shall be a path-painting no-op, used primarily for
+ * the side effect of changing the current clipping path.
+ *
+ * @see "PDF 1.7 specification, Section 8.5.3 'Path-Painting Operators'"
+ * @author PdfBox, modified by Datentechnik Innovation GmbH
+ */
+public class EndPath extends PathPaintingOperatorProcessor {
+
+	private Log log = LogFactory.getLog(getClass());
+
+	public EndPath(PDFPage context) {
+		super(context);
+	}
+
+	@Override
+	public void process(PDFOperator operator, List<COSBase> operands) throws IOException {
+		try {
+			PDFPage pdfPage = (PDFPage) context;
+
+			log.debug("Ending path " + pdfPage.getCurrentPath());
+			pdfPage.getCurrentPath().reset();
+
+			if (log.isTraceEnabled()) {
+				log.trace("End path without filling or stroking.");
+			}
+
+		} catch (Exception e) {
+			log.warn("Error processing operator 'n'.", e);
+		}
+	}
+
+}
diff --git a/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillEvenOddAndStrokePath.java b/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillEvenOddAndStrokePath.java
new file mode 100644
index 00000000..13623648
--- /dev/null
+++ b/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillEvenOddAndStrokePath.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * <copyright> Copyright 2014 by E-Government Innovation Center EGIZ, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ * 
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ * 
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ ******************************************************************************/
+/**
+ * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.knowcenter.wag.egov.egiz.pdf.operator.path.painting;
+
+import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathPaintingOperatorProcessor;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.pdfbox.cos.COSBase;
+import org.apache.pdfbox.util.PDFOperator;
+
+import java.awt.geom.GeneralPath;
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * Fill and then stroke the path, using the even-odd rule to determine the region to fill. This operator shall produce
+ * the same result as <code>B</code>, except that the path is filled as if with <code>f*</code> instead of
+ * <code>f</code>.
+ *
+ * @see "PDF 1.7 specification, Section 8.5.3 'Path-Painting Operators'"
+ * @author PdfBox, modified by Datentechnik Innovation GmbH
+ */
+public class FillEvenOddAndStrokePath extends PathPaintingOperatorProcessor {
+
+	private Log log = LogFactory.getLog(getClass());
+
+	public FillEvenOddAndStrokePath(PDFPage context) {
+		super(context);
+	}
+
+	@Override
+	public void process(PDFOperator operator, List<COSBase> operands) throws IOException {
+		try {
+			PDFPage pdfPage = (PDFPage) context;
+
+			if (log.isTraceEnabled()) {
+				log.trace("Filling (even odd rule) and stroking path.");
+			}
+
+			GeneralPath currentPath = (GeneralPath) pdfPage.getCurrentPath().clone();
+			context.processOperator("f*", operands);
+			pdfPage.setCurrentPath(currentPath);
+			context.processOperator("S", operands);
+
+		} catch (Exception e) {
+			log.warn("Error processing operator 'B*'.", e);
+		}
+	}
+
+}
diff --git a/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillNonZeroAndStrokePath.java b/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillNonZeroAndStrokePath.java
new file mode 100644
index 00000000..485411a8
--- /dev/null
+++ b/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillNonZeroAndStrokePath.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * <copyright> Copyright 2014 by E-Government Innovation Center EGIZ, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ * 
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ * 
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ ******************************************************************************/
+/**
+ * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.knowcenter.wag.egov.egiz.pdf.operator.path.painting;
+
+import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathPaintingOperatorProcessor;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.pdfbox.cos.COSBase;
+import org.apache.pdfbox.util.PDFOperator;
+
+import java.awt.geom.GeneralPath;
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * Fill and then stroke the path, using the nonzero winding number rule to determine the region to fill. This operator
+ * shall produce the same result as constructing two identical path objects, painting the first with <code>f</code> and
+ * the second with <code>S</code>.
+ *
+ * @see "PDF 1.7 specification, Section 8.5.3 'Path-Painting Operators'"
+ * @author PdfBox, modified by Datentechnik Innovation GmbH
+ */
+public class FillNonZeroAndStrokePath extends PathPaintingOperatorProcessor {
+
+	private Log log = LogFactory.getLog(getClass());
+
+	public FillNonZeroAndStrokePath(PDFPage context) {
+		super(context);
+	}
+
+	@Override
+	public void process(PDFOperator operator, List<COSBase> operands) throws IOException {
+		try {
+			PDFPage pdfPage = (PDFPage) context;
+
+			if (log.isTraceEnabled()) {
+				log.trace("Filling (non zero rule) and stroking path.");
+			}
+
+			GeneralPath currentPath = (GeneralPath) pdfPage.getCurrentPath().clone();
+			context.processOperator("f", operands);
+			pdfPage.setCurrentPath(currentPath);
+			context.processOperator("S", operands);
+
+		} catch (Exception e) {
+			log.warn("Error processing operator 'B'.", e);
+		}
+	}
+
+}
diff --git a/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillPathEvenOddRule.java b/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillPathEvenOddRule.java
new file mode 100644
index 00000000..bb3d3411
--- /dev/null
+++ b/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillPathEvenOddRule.java
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * <copyright> Copyright 2014 by E-Government Innovation Center EGIZ, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ * 
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ * 
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ ******************************************************************************/
+/**
+ * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.knowcenter.wag.egov.egiz.pdf.operator.path.painting;
+
+import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathPaintingOperatorProcessor;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.pdfbox.cos.COSBase;
+import org.apache.pdfbox.util.PDFOperator;
+
+import java.awt.*;
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * Fill the path, using the even-odd rule to determine the region to fill.
+ *
+ * @see "PDF 1.7 specification, Section 8.5.3 'Path-Painting Operators'"
+ * @author PdfBox, modified by Datentechnik Innovation GmbH
+ */
+public class FillPathEvenOddRule extends PathPaintingOperatorProcessor {
+
+	private Log log = LogFactory.getLog(getClass());
+
+	public FillPathEvenOddRule(PDFPage context) {
+		super(context);
+	}
+
+	@Override
+	public void process(PDFOperator operator, List<COSBase> operands) throws IOException {
+		try {
+			PDFPage pdfPage = (PDFPage) context;
+
+			pdfPage.getCurrentPath().setWindingRule(java.awt.geom.GeneralPath.WIND_EVEN_ODD);
+			Rectangle bounds = pdfPage.getCurrentPath().getBounds();
+			pdfPage.getCurrentPath().reset();
+
+			if (log.isTraceEnabled()) {
+				log.trace("Filling path, using even-odd rule.");
+			}
+
+			pdfPage.registerPathBounds(bounds);
+
+		} catch (Exception e) {
+			log.warn("Error processing operator 'f*'.", e);
+		}
+	}
+
+}
diff --git a/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillPathNonZeroWindingNumberRule.java b/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillPathNonZeroWindingNumberRule.java
new file mode 100644
index 00000000..6196c466
--- /dev/null
+++ b/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/FillPathNonZeroWindingNumberRule.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * <copyright> Copyright 2014 by E-Government Innovation Center EGIZ, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ * 
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ * 
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ ******************************************************************************/
+/**
+ * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.knowcenter.wag.egov.egiz.pdf.operator.path.painting;
+
+import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathPaintingOperatorProcessor;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.pdfbox.cos.COSBase;
+import org.apache.pdfbox.util.PDFOperator;
+
+import java.awt.*;
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * Fill the path, using the nonzero winding number rule to determine the region to fill. Any subpaths that are open
+ * shall be implicitly closed before being filled.
+ *
+ * @see "PDF 1.7 specification, Section 8.5.3 'Path-Painting Operators'"
+ * @author PdfBox, modified by Datentechnik Innovation GmbH
+ */
+public class FillPathNonZeroWindingNumberRule extends PathPaintingOperatorProcessor {
+
+	private Log log = LogFactory.getLog(getClass());
+
+	public FillPathNonZeroWindingNumberRule(PDFPage context) {
+		super(context);
+	}
+
+	@Override
+	public void process(PDFOperator operator, List<COSBase> operands) throws IOException {
+		try {
+			PDFPage pdfPage = (PDFPage) context;
+
+			pdfPage.getCurrentPath().setWindingRule(java.awt.geom.GeneralPath.WIND_NON_ZERO);
+			Rectangle bounds = pdfPage.getCurrentPath().getBounds();
+			pdfPage.getCurrentPath().reset();
+
+			if (log.isTraceEnabled()) {
+				log.trace("Filling path, using nonzero winding number rule.");
+			}
+
+			pdfPage.registerPathBounds(bounds);
+
+		} catch (Exception e) {
+			log.warn("Error processing operator 'f/F'.", e);
+		}
+	}
+
+}
diff --git a/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/StrokePath.java b/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/StrokePath.java
new file mode 100644
index 00000000..b114b60b
--- /dev/null
+++ b/pdf-as-pdfbox/src/main/java/at/knowcenter/wag/egov/egiz/pdf/operator/path/painting/StrokePath.java
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * <copyright> Copyright 2014 by E-Government Innovation Center EGIZ, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ * 
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ * 
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ ******************************************************************************/
+/**
+ * <copyright> Copyright 2006 by Know-Center, Graz, Austria </copyright>
+ * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a
+ * joint initiative of the Federal Chancellery Austria and Graz University of
+ * Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+package at.knowcenter.wag.egov.egiz.pdf.operator.path.painting;
+
+import at.knowcenter.wag.egov.egiz.pdf.PDFPage;
+import at.knowcenter.wag.egov.egiz.pdf.operator.path.PathPaintingOperatorProcessor;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.pdfbox.cos.COSBase;
+import org.apache.pdfbox.util.PDFOperator;
+
+import java.awt.*;
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * Strokes the path.
+ *
+ * @see "PDF 1.7 specification, Section 8.5.3 'Path-Painting Operators'"
+ * @author PdfBox, modified by Datentechnik Innovation GmbH
+ */
+public class StrokePath extends PathPaintingOperatorProcessor {
+
+	private Log log = LogFactory.getLog(getClass());
+
+	public StrokePath(PDFPage context) {
+		super(context);
+	}
+
+	@Override
+	public void process(PDFOperator operator, List<COSBase> operands) throws IOException {
+		try {
+			PDFPage pdfPage = (PDFPage) context;
+
+			Rectangle bounds = pdfPage.getCurrentPath().getBounds();
+			pdfPage.getCurrentPath().reset();
+
+			if (log.isTraceEnabled()) {
+				log.trace("Stroking path.");
+			}
+
+			pdfPage.registerPathBounds(bounds);
+
+		} catch (Exception e) {
+			log.warn("Error processing operator 'S'.", e);
+		}
+	}
+
+}
-- 
cgit v1.2.3