Index: /applications/editors/josm/plugins/pdfimport/build.xml
===================================================================
--- /applications/editors/josm/plugins/pdfimport/build.xml	(revision 23702)
+++ /applications/editors/josm/plugins/pdfimport/build.xml	(revision 23703)
@@ -2,4 +2,5 @@
 <!--
 ** This is the build file for the pdfimport plugin.
+** Same as build.xml, but uses local version of pdfclown
 **
 ** Maintaining versions
@@ -32,7 +33,7 @@
 
 	<!-- enter the SVN commit message -->
-	<property name="commit.message" value="adapt to latest josm" />
+	<property name="commit.message" value="Initial pdfimport version" />
 	<!-- enter the *lowest* JOSM version this plugin is currently compatible with -->
-	<property name="plugin.main.version" value="3348" />
+	<property name="plugin.main.version" value="3592" />
 
 
@@ -44,5 +45,4 @@
 	<property name="plugin.dist.dir" value="../../dist" />
 	<property name="plugin.name" value="${ant.project.name}" />
-	<property name="libpdfclown" value="lib/PDFClown.jar"/>	
 	<property name="plugin.jar" value="${plugin.dist.dir}/${plugin.name}.jar" />
 
@@ -62,8 +62,7 @@
 		<echo message="creating ${plugin.jar}" />
 		<javac srcdir="src" target="1.5" destdir="build" debug="true">
-			<include name="pdfimport/**/*.java" />
+			<include name="**/*.java" />
 			<classpath>
 				<pathelement location="${josm}"/>
-				<pathelement location="${libpdfclown}"/>
 			</classpath>			
 		</javac>
@@ -82,13 +81,13 @@
 
 	<target name="dist" depends="compile,revision">
- 		<unjar dest="${plugin.build.dir}" src="${libpdfclown}"/>
 		<copy todir="${plugin.build.dir}/images">
 			<fileset dir="images" />
 		</copy>
+
 		<jar destfile="${plugin.jar}" basedir="${plugin.build.dir}">
 			<manifest>
-				<attribute name="Author" value="Viesturs" />
+				<attribute name="Author" value="extropy" />
 				<attribute name="Plugin-Class" value="pdfimport.PdfImportPlugin" />
-				<attribute name="Plugin-Description" value="Import PDF files and convert to shapes." />
+				<attribute name="Plugin-Description" value="Import PDF file and convert to ways." />
 				<attribute name="Plugin-Icon" value="images/pdf_import.png"/>
 				<attribute name="Plugin-Version" value="${version.entry.commit.revision}" />
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/Engine.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/Engine.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/Engine.java	(revision 23703)
@@ -0,0 +1,29 @@
+/*
+  Copyright 2006-2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown;
+
+public class Engine
+{}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/bytes/Buffer.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/bytes/Buffer.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/bytes/Buffer.java	(revision 23703)
@@ -0,0 +1,744 @@
+/*
+  Copyright 2006-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.bytes;
+
+import it.stefanochizzolini.clown.bytes.filters.Filter;
+import it.stefanochizzolini.clown.util.ConvertUtils;
+
+import java.io.ByteArrayOutputStream;
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteOrder;
+
+/**
+  Byte buffer.
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+*/
+public final class Buffer
+  implements IBuffer
+{
+  // <class>
+  // <static>
+  // <fields>
+  /**
+    Default buffer capacity.
+  */
+  private static final int DefaultCapacity = 1 << 8;
+
+  private static final String Encoding = "ISO-8859-1";
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <fields>
+  /**
+    Inner buffer where data are stored.
+  */
+  private byte[] data;
+  /**
+    Number of bytes actually used in the buffer.
+  */
+  private int length;
+  /**
+    Pointer position within the buffer.
+  */
+  private int position = 0;
+
+  private ByteOrder byteOrder = ByteOrder.BIG_ENDIAN;
+  // </fields>
+
+  // <constructors>
+  public Buffer(
+    )
+  {this(0);}
+
+  public Buffer(
+    int capacity
+    )
+  {
+    if(capacity < 1)
+    {capacity = DefaultCapacity;}
+
+    this.data = new byte[capacity];
+    this.length = 0;
+  }
+
+  public Buffer(
+    java.io.BufferedReader dataStream
+    )
+  {
+    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+    try
+    {
+      char[] buffer = new char[8192]; int bufferLength;
+      while((bufferLength = dataStream.read(buffer, 0, buffer.length)) != -1)
+      {
+        for(int i = 0; i < bufferLength; i++)
+        {outputStream.write((byte)buffer[i]);}
+      }
+    }
+    catch(IOException exception)
+    {throw new RuntimeException(exception);}
+
+    this.data = outputStream.toByteArray();
+    this.length = data.length;
+  }
+
+  public Buffer(
+    InputStream dataStream
+    )
+  {
+    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+    try
+    {
+      byte[] buffer = new byte[8192]; int bufferLength;
+      while((bufferLength = dataStream.read(buffer, 0, buffer.length)) != -1)
+      {outputStream.write(buffer, 0, bufferLength);}
+    }
+    catch(IOException exception)
+    {throw new RuntimeException(exception);}
+
+    this.data = outputStream.toByteArray();
+    this.length = data.length;
+  }
+
+  public Buffer(
+    byte[] data
+    )
+  {
+    this.data = data;
+    this.length = data.length;
+  }
+
+  public Buffer(
+    byte[] data,
+    ByteOrder byteOrder
+    )
+  {
+    this.data = data;
+    this.length = data.length;
+    this.byteOrder = byteOrder;
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  // <IBuffer>
+  public void append(
+    byte data
+    )
+  {
+    while(true)
+    {
+      try
+      {
+        this.data[this.length] = data;
+        break; // Escape the loop.
+      }
+      catch(Exception e)
+      {
+        // Do NOT additional data exceed buffer capacity?
+        if(!ensureCapacity(1)) // Unhandled exception.
+        {
+          // Propagate the exception!
+          throw new RuntimeException(e);
+        }
+      }
+    }
+
+    // Update buffer size!
+    this.length++;
+  }
+
+  public void append(
+    byte[] data
+    )
+  {
+    append(
+      data,
+      0,
+      data.length
+      );
+  }
+
+  public void append(
+    byte[] data,
+    int offset,
+    int length
+    )
+  {
+    while(true)
+    {
+      try
+      {
+        System.arraycopy(
+          data,
+          offset,
+          this.data,
+          this.length,
+          length
+          );
+        break; // Escape the loop.
+      }
+      catch(Exception e)
+      {
+        // Do NOT additional data exceed buffer capacity?
+        if(!ensureCapacity(length)) // Unhandled exception.
+        {
+          // Propagate the exception!
+          throw new RuntimeException(e);
+        }
+      }
+    }
+
+    // Update buffer size!
+    this.length += length;
+  }
+
+  public void append(
+    String data
+    )
+  {
+    try
+    {append(data.getBytes(Encoding));}
+    catch(Exception e)
+    {throw new RuntimeException(e);}
+  }
+
+  public void append(
+    IInputStream data
+    )
+  {
+    append(
+      data.toByteArray(),
+      0,
+      (int)data.getLength()
+      );
+  }
+
+  public Buffer clone(
+    )
+  {
+    Buffer clone = new Buffer(getCapacity());
+    clone.append(data);
+
+    return clone;
+  }
+
+  public void decode(
+    Filter filter
+    )
+  {
+    data = filter.decode(data,0,length);
+    length = data.length;
+  }
+
+  public void delete(
+    int index,
+    int length
+    )
+  {
+    try
+    {
+      // Shift left the trailing data block to override the deleted data!
+      System.arraycopy(
+        this.data,
+        index + length,
+        this.data,
+        index,
+        this.length - (index + length)
+        );
+    }
+    catch(Exception e)
+    {throw new RuntimeException(e);}
+
+    // Update the buffer size!
+    this.length -= length;
+  }
+
+  public byte[] encode(
+    Filter filter
+    )
+  {return filter.encode(data,0,length);}
+
+  public int getByte(
+    int index
+    )
+  {return data[index];}
+
+  public byte[] getByteArray(
+    int index,
+    int length
+    )
+  {
+    byte[] data = new byte[length];
+    System.arraycopy(
+      this.data,
+      index,
+      data,
+      0,
+      length
+      );
+
+    return data;
+  }
+
+  public String getString(
+    int index,
+    int length
+    )
+  {//TODO:verify Javascript action Unicode encoding!!!
+    try
+    {return new String(data,index,length,Encoding);}
+    catch(Exception e)
+    {throw new RuntimeException(e);}
+  }
+
+  public int getCapacity(
+    )
+  {return data.length;}
+
+  public void insert(
+    int index,
+    byte[] data
+    )
+  {
+    insert(
+      index,
+      data,
+      0,
+      data.length
+      );
+  }
+
+  public void insert(
+    int index,
+    byte[] data,
+    int offset,
+    int length
+    )
+  {
+    while(true)
+    {
+      try
+      {
+        // Shift right the existing data block to make room for new data!
+        System.arraycopy(
+          this.data,
+          index,
+          this.data,
+          index + length,
+          this.length - index
+          );
+        break; // Escape the loop.
+      }
+      catch(Exception e)
+      {
+        // Do NOT additional data exceed buffer capacity?
+        if(!ensureCapacity(length)) // Unhandled exception.
+        {
+          // Propagate the exception!
+          throw new RuntimeException(e);
+        }
+      }
+    }
+
+    // Insert additional data!
+    System.arraycopy(
+      data,
+      offset,
+      this.data,
+      index,
+      length
+      );
+
+    // Update the buffer size!
+    this.length += length;
+  }
+
+  public void insert(
+    int index,
+    String data
+    )
+  {
+    try
+    {
+      insert(
+        index,
+        data.getBytes(Encoding)
+        );
+    }
+    catch(Exception e)
+    {
+      // Propagate the exception!
+      throw new RuntimeException(e);
+    }
+  }
+
+  public void insert(
+    int index,
+    IInputStream data
+    )
+  {
+    insert(
+      index,
+      data.toByteArray()
+      );
+  }
+
+  public void replace(
+    int index,
+    byte[] data
+    )
+  {
+    // Replace data!
+    System.arraycopy(
+      data,
+      0,
+      this.data,
+      index,
+      data.length
+      );
+  }
+
+  public void replace(
+    int index,
+    byte[] data,
+    int offset,
+    int length
+    )
+  {
+    // Replace data!
+    System.arraycopy(
+      data,
+      offset,
+      this.data,
+      index,
+      data.length
+      );
+  }
+
+  public void replace(
+    int index,
+    String data
+    )
+  {
+    try
+    {
+      // Replace data!
+      replace(
+        index,
+        data.getBytes(Encoding)
+        );
+    }
+    catch(Exception e)
+    {throw new RuntimeException(e);}
+  }
+
+  public void replace(
+    int index,
+    IInputStream data
+    )
+  {
+    // Replace data!
+    replace(
+      index,
+      data.toByteArray()
+      );
+  }
+
+  public void setLength(
+    int value
+    )
+  {length = value;}
+
+  public void writeTo(
+    IOutputStream stream
+    )
+  {
+    stream.write(
+      data,
+      0,
+      length
+      );
+  }
+
+  // <IInputStream>
+  public ByteOrder getByteOrder(
+    )
+  {return byteOrder;}
+
+  public long getLength(
+    )
+  {return length;}
+
+  public long getPosition(
+    )
+  {return position;}
+
+  /* int hashCode() uses inherited implementation. */
+
+  public void read(
+    byte[] data
+    )
+  {
+    read(
+      data,
+      0,
+      data.length
+      );
+  }
+
+  public void read(
+    byte[] data,
+    int offset,
+    int length
+    )
+  {
+    try
+    {
+      System.arraycopy(
+        this.data,
+        position,
+        data,
+        offset,
+        length
+        );
+      position += length;
+    }
+    catch(Exception e)
+    {throw new RuntimeException(e);}
+  }
+
+  public byte readByte(
+    ) throws EOFException
+  {
+    try
+    {return data[position++];}
+    catch(ArrayIndexOutOfBoundsException e)
+    {throw new EOFException();}
+  }
+
+  public int readInt(
+    ) throws EOFException
+  {
+    int value = ConvertUtils.byteArrayToInt(data,position,byteOrder);
+    position +=4;
+    return value;
+  }
+
+  public String readLine(
+    ) throws EOFException
+  {
+    StringBuilder buffer = new StringBuilder();
+    try
+    {
+      while(true)
+      {
+        int c = data[position++];
+        if(c == '\r'
+          || c == '\n')
+          break;
+
+        buffer.append((char)c);
+      }
+    }
+    catch(ArrayIndexOutOfBoundsException e)
+    {throw new EOFException();}
+
+    return buffer.toString();
+  }
+
+  public short readShort(
+    ) throws EOFException
+  {
+    short value = (short)ConvertUtils.byteArrayToNumber(data,position,2,byteOrder);
+    position += 2;
+    return value;
+  }
+
+  public String readString(
+    int length
+    )
+  {
+    try
+    {
+      String data = new String(
+        this.data,
+        position,
+        length,
+        Encoding
+        );
+      position += length;
+
+      return data;
+    }
+    catch(Exception e)
+    {throw new RuntimeException(e);}
+  }
+
+  public int readUnsignedByte(
+    ) throws EOFException
+  {
+    try
+    {return (data[position++] & 0xFF);}
+    catch(ArrayIndexOutOfBoundsException e)
+    {throw new EOFException();}
+  }
+
+  public int readUnsignedShort(
+    ) throws EOFException
+  {
+  //TODO: harmonize byteorder semantics with C# version!!!
+    try
+    {
+      if(byteOrder == ByteOrder.LITTLE_ENDIAN)
+        return (data[position++] & 0xFF) | (data[position++] & 0xFF) << 8;
+      else // ByteOrder.BIG_ENDIAN
+        return (data[position++] & 0xFF) << 8 | (data[position++] & 0xFF);
+    }
+    catch(ArrayIndexOutOfBoundsException e)
+    {throw new EOFException();}
+  }
+
+  public void seek(
+    long position
+    )
+  {this.position = (int)position;}
+
+  public void setByteOrder(
+    ByteOrder value
+    )
+  {byteOrder = value;}
+
+  public void setPosition(
+    long value
+    )
+  {position = (int)value;}
+
+  public void skip(
+    long offset
+    )
+  {position += (int)offset;}
+
+  public byte[] toByteArray(
+    )
+  {
+    byte[] data = new byte[this.length];
+    System.arraycopy(
+      this.data,
+      0,
+      data,
+      0,
+      this.length
+      );
+
+    return data;
+  }
+
+  // <Closeable>
+  public void close(
+    ) throws IOException
+  {}
+  // </Closeable>
+  // </IInputStream>
+  // </IBuffer>
+
+  // <IOutputStream>
+  public void write(
+    byte[] data
+    )
+  {append(data);}
+
+  public void write(
+    byte[] data,
+    int offset,
+    int length
+    )
+  {append(data,offset,length);}
+
+  public void write(
+    String data
+    )
+  {append(data);}
+
+  public void write(
+    IInputStream data
+    )
+  {append(data);}
+  // </IOutputStream>
+  // </public>
+
+  // <protected>
+  /**
+    Check whether the buffer capacity has sufficient room for adding data.
+  */
+  protected boolean ensureCapacity(
+    int additionalLength
+    )
+  {
+    int minCapacity = this.length + additionalLength;
+    // Is additional data within the buffer capacity?
+    if(minCapacity <= this.data.length)
+      return false; // OK -- No change.
+
+    // Additional data exceed buffer capacity.
+    // Reallocate the buffer!
+    byte[] data = new byte[
+      Math.max(
+        this.data.length << 1, // 1 order of magnitude greater than current capacity.
+        minCapacity // Minimum capacity required.
+        )
+      ];
+    System.arraycopy(
+      this.data,
+      0,
+      data,
+      0,
+      this.length
+      );
+    this.data = data;
+
+    return true; // Reallocation happened.
+  }
+
+  @Override
+  protected void finalize(
+    ) throws Throwable
+  {
+    try
+    {close();}
+    finally
+    {super.finalize();}
+  }
+  // </protected>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/bytes/FileInputStream.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/bytes/FileInputStream.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/bytes/FileInputStream.java	(revision 23703)
@@ -0,0 +1,274 @@
+/*
+  Copyright 2006-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.bytes;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.ByteOrder;
+
+/**
+  File stream.
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+*/
+public final class FileInputStream
+  implements IInputStream
+{
+  // <class>
+  // <dynamic>
+  // <fields>
+  private RandomAccessFile file;
+  // </fields>
+
+  // <constructors>
+  public FileInputStream(
+    RandomAccessFile file
+    )
+  {this.file = file;}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  // <IInputStream>
+  public ByteOrder getByteOrder(
+    )
+  {return ByteOrder.BIG_ENDIAN;}
+
+  public long getPosition(
+    )
+  {
+    try
+    {return file.getFilePointer();}
+    catch(IOException e)
+    {throw new RuntimeException(e);}
+  }
+
+  public int hashCode(
+    )
+  {return file.hashCode();}
+
+  public void read(
+    byte[] data
+    ) throws EOFException
+  {
+    try
+    {file.readFully(data);}
+    catch(EOFException e)
+    {throw e;}
+    catch(IOException e)
+    {throw new RuntimeException(e);}
+  }
+
+  public void read(
+    byte[] data,
+    int offset,
+    int length
+    ) throws EOFException
+  {
+    try
+    {file.readFully(data,offset,length);}
+    catch(EOFException e)
+    {throw e;}
+    catch(IOException e)
+    {throw new RuntimeException(e);}
+  }
+
+  public byte readByte(
+    ) throws EOFException
+  {
+    try
+    {return file.readByte();}
+    catch(EOFException e)
+    {throw e;}
+    catch(IOException e)
+    {throw new RuntimeException(e);}
+  }
+
+  public int readInt(
+    ) throws EOFException
+  {
+    try
+    {return file.readInt();}
+    catch(EOFException e)
+    {throw e;}
+    catch(IOException e)
+    {throw new RuntimeException(e);}
+  }
+
+  public String readLine(
+    ) throws EOFException
+  {
+    try
+    {return file.readLine();}
+    catch(EOFException e)
+    {throw e;}
+    catch(IOException e)
+    {throw new RuntimeException(e);}
+  }
+
+  public short readShort(
+    ) throws EOFException
+  {
+    try
+    {return file.readShort();}
+    catch(EOFException e)
+    {throw e;}
+    catch(IOException e)
+    {throw new RuntimeException(e);}
+  }
+
+  public String readString(
+    int length
+    ) throws EOFException
+  {
+    byte[] data = new byte[length];
+    try
+    {
+      file.readFully(data);
+
+      return new String(data,"ISO-8859-1");
+    }
+    catch(EOFException e)
+    {throw e;}
+    catch(Exception e)
+    {throw new RuntimeException(e);}
+  }
+
+  public int readUnsignedByte(
+    ) throws EOFException
+  {
+    try
+    {return file.readUnsignedByte();}
+    catch(EOFException e)
+    {throw e;}
+    catch(IOException e)
+    {throw new RuntimeException(e);}
+  }
+
+  public int readUnsignedShort(
+    ) throws EOFException
+  {
+    try
+    {return file.readUnsignedShort();}
+    catch(EOFException e)
+    {throw e;}
+    catch(IOException e)
+    {throw new RuntimeException(e);}
+  }
+
+  public void seek(
+    long offset
+    )
+  {
+    try
+    {file.seek(offset);}
+    catch(IOException e)
+    {throw new RuntimeException(e);}
+  }
+
+  public void setByteOrder(
+    ByteOrder value
+    )
+  {/* TODO */}
+
+  public void setPosition(
+    long value
+    )
+  {
+    try
+    {file.seek(value);}
+    catch(IOException e)
+    {throw new RuntimeException(e);}
+  }
+
+  public void skip(
+    long offset
+    )
+  {
+    try
+    {file.seek(file.getFilePointer() + offset);}
+    catch(IOException e)
+    {throw new RuntimeException(e);}
+  }
+
+  public byte[] toByteArray(
+    )
+  {
+    byte[] data = null;
+    try
+    {
+      file.seek(0);
+      data = new byte[(int)file.length()];
+      file.readFully(data);
+    }
+    catch(IOException e)
+    {throw new RuntimeException(e);}
+
+    return data;
+  }
+
+  // <IStream>
+  public long getLength(
+    )
+  {
+    try
+    {return file.length();}
+    catch(IOException e)
+    {throw new RuntimeException(e);}
+  }
+
+  // <Closeable>
+  public void close(
+    ) throws IOException
+  {
+    if(file != null)
+    {
+      file.close();
+      file = null;
+    }
+  }
+  // </Closeable>
+  // </IStream>
+  // </IInputStream>
+  // </public>
+
+  // <protected>
+  @Override
+  protected void finalize(
+    ) throws Throwable
+  {
+    try
+    {close();}
+    finally
+    {super.finalize();}
+  }
+  // </protected>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/bytes/IBuffer.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/bytes/IBuffer.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/bytes/IBuffer.java	(revision 23703)
@@ -0,0 +1,260 @@
+/*
+  Copyright 2006-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.bytes;
+
+import it.stefanochizzolini.clown.bytes.filters.Filter;
+
+/**
+  Buffer interface.
+  <p>Its pivotal concept is the array index.</p>
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+*/
+public interface IBuffer
+  extends IInputStream,
+    IOutputStream
+{
+  /**
+    Appends a byte to the buffer.
+    @param data Byte to copy.
+  */
+  void append(
+    byte data
+    );
+
+  /**
+    Appends a byte array to the buffer.
+    @param data Byte array to copy.
+  */
+  void append(
+    byte[] data
+    );
+
+  /**
+    Appends a byte range to the buffer.
+    @param data Byte array from which the byte range has to be copied.
+    @param offset Location in the byte array at which copying begins.
+    @param length Number of bytes to copy.
+  */
+  void append(
+    byte[] data,
+    int offset,
+    int length
+    );
+
+  /**
+    Appends a string to the buffer.
+    @param data String to copy.
+  */
+  void append(
+    String data
+    );
+
+  /**
+    Appends an IInputStream to the buffer.
+    @param data Source data to copy.
+  */
+  void append(
+    IInputStream data
+    );
+
+  /**
+    Gets a clone of the buffer.
+    @return Deep copy of the buffer.
+  */
+  IBuffer clone(
+    );
+
+  /**
+    Applies the specified filter to decode the buffer.
+    @param filter Filter to use for decoding the buffer.
+  */
+  void decode(
+    Filter filter
+    );
+
+  /**
+    Deletes a byte chunk from the buffer.
+    @param index Location at which deletion has to begin.
+    @param length Number of bytes to delete.
+  */
+  void delete(
+    int index,
+    int length
+    );
+
+  /**
+    Applies the specified filter to encode the buffer.
+    @param filter Filter to use for encoding the buffer.
+    @return Encoded buffer.
+  */
+  byte[] encode(
+    Filter filter
+    );
+
+  /**
+    Gets the byte at a specified location.
+    @param index A location in the buffer.
+    @return Byte at the specified location.
+  */
+  int getByte(
+    int index
+    );
+
+    /**
+    Gets the byte range beginning at a specified location.
+    @param index Location at which the byte range has to begin.
+    @param length Number of bytes to copy.
+    @return Byte range beginning at the specified location.
+  */
+  byte[] getByteArray(
+    int index,
+    int length
+    );
+
+  /**
+    Gets the string beginning at a specified location.
+    @param index Location at which the string has to begin.
+    @param length Number of bytes to convert.
+    @return String beginning at the specified location.
+  */
+  String getString(
+    int index,
+    int length
+    );
+
+  /**
+    Gets the allocated buffer size.
+    @return Allocated buffer size.
+  */
+  int getCapacity(
+    );
+
+  /**
+    Inserts a byte array into the buffer.
+    @param index Location at which the byte array has to be inserted.
+    @param data Byte array to insert.
+  */
+  void insert(
+    int index,
+    byte[] data
+    );
+
+  /**
+    Inserts a byte range into the buffer.
+    @param index Location at which the byte range has to be inserted.
+    @param data Byte array from which the byte range has to be copied.
+    @param offset Location in the byte array at which copying begins.
+    @param length Number of bytes to copy.
+  */
+  void insert(
+    int index,
+    byte[] data,
+    int offset,
+    int length
+    );
+
+  /**
+    Inserts a string into the buffer.
+    @param index Location at which the string has to be inserted.
+    @param data String to insert.
+  */
+  void insert(
+    int index,
+    String data
+    );
+
+  /**
+    Inserts an IInputStream into the buffer.
+    @param index Location at which the IInputStream has to be inserted.
+    @param data Source data to copy.
+  */
+  void insert(
+    int index,
+    IInputStream data
+    );
+
+  /**
+    Replaces the buffer contents with a byte array.
+    @param index Location at which the byte array has to be copied.
+    @param data Byte array to copy.
+  */
+  void replace(
+    int index,
+    byte[] data
+    );
+
+  /**
+    Replaces the buffer contents with a byte range.
+    @param index Location at which the byte range has to be copied.
+    @param data Byte array from which the byte range has to be copied.
+    @param offset Location in the byte array at which copying begins.
+    @param length Number of bytes to copy.
+  */
+  void replace(
+    int index,
+    byte[] data,
+    int offset,
+    int length
+    );
+
+  /**
+    Replaces the buffer contents with a string.
+    @param index Location at which the string has to be copied.
+    @param data String to copy.
+  */
+  void replace(
+    int index,
+    String data
+    );
+
+  /**
+    Replaces the buffer contents with an IInputStream.
+    @param index Location at which the IInputStream has to be copied.
+    @param data Source data to copy.
+  */
+  void replace(
+    int index,
+    IInputStream data
+    );
+
+  /**
+    Sets the used buffer size.
+    @param value New length.
+  */
+  void setLength(
+    int value
+    );
+
+  /**
+    Writes the buffer data to a stream.
+    @param stream Target stream.
+  */
+  void writeTo(
+    IOutputStream stream
+    );
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/bytes/IInputStream.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/bytes/IInputStream.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/bytes/IInputStream.java	(revision 23703)
@@ -0,0 +1,172 @@
+/*
+  Copyright 2006-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.bytes;
+
+import java.io.EOFException;
+import java.nio.ByteOrder;
+
+/**
+  Input stream.
+  <p>Its pivotal concept is the access pointer.</p>
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+*/
+public interface IInputStream
+  extends IStream
+{
+  /**
+    Gets the byte order.
+  */
+  ByteOrder getByteOrder(
+    );
+
+  /**
+    Gets the pointer position.
+  */
+  long getPosition(
+    );
+
+  /**
+    Gets the hash representation of the sequence.
+  */
+  int hashCode(
+    );
+
+  /**
+    Reads a sequence of bytes from the stream and advances the position within the stream.
+    @param data Target byte array.
+  */
+  void read(
+    byte[] data
+    )
+    throws EOFException;
+
+  /**
+    Reads a sequence of bytes from the stream and advances the position within the stream.
+    @param data Target byte array.
+    @param offset Location in the byte array at which storing begins.
+    @param length Number of bytes to copy.
+  */
+  void read(
+    byte[] data,
+    int offset,
+    int length
+    )
+    throws EOFException;
+
+  /**
+    Reads a byte from the stream and advances the position within the stream.
+    @return Byte from the stream.
+  */
+  byte readByte(
+    )
+    throws EOFException;
+
+  /**
+    Reads an integer from the stream and advances the position within the stream.
+    @return Integer from the stream.
+  */
+  int readInt(
+    )
+    throws EOFException;
+
+  /**
+    Reads the next line of text.
+    @return String from the stream.
+  */
+  String readLine(
+    )
+    throws EOFException;
+
+  /**
+    Reads a short integer from the stream and advances the position within the stream.
+    @return Short integer from the stream.
+  */
+  short readShort(
+    )
+    throws EOFException;
+
+  /**
+    Reads a string from the stream and advances the position within the stream.
+    @param length Number of bytes to read.
+    @return String from the stream.
+  */
+  String readString(
+    int length
+    )
+    throws EOFException;
+
+  /**
+    Reads an unsigned byte integer from the stream and advances the position within the stream.
+    @return Unsigned byte integer from the stream.
+  */
+  int readUnsignedByte(
+    )
+    throws EOFException;
+
+  /**
+    Reads an unsigned short integer from the stream and advances the position within the stream.
+    @return Unsigned short integer from the stream.
+  */
+  int readUnsignedShort(
+    )
+    throws EOFException;
+
+  /**
+    Sets the pointer absolute position.
+  */
+  void seek(
+    long position
+    );
+
+  /**
+    Sets the byte order.
+  */
+  void setByteOrder(
+    ByteOrder value
+    );
+
+  /**
+    Sets the pointer position.
+  */
+  void setPosition(
+    long value
+    );
+
+  /**
+    Sets the pointer relative position.
+  */
+  void skip(
+    long offset
+    );
+
+  /**
+    Gets the buffer data copied to a newly-allocated byte array.
+  */
+  byte[] toByteArray(
+    );
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/bytes/IOutputStream.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/bytes/IOutputStream.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/bytes/IOutputStream.java	(revision 23703)
@@ -0,0 +1,76 @@
+/*
+  Copyright 2006-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.bytes;
+
+/**
+  Output stream interface.
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+*/
+public interface IOutputStream
+  extends IStream
+{
+  /**
+    Writes a byte array into the stream.
+
+    @param data Byte array to write into the stream.
+  */
+  void write(
+    byte[] data
+    );
+
+  /**
+    Writes a byte range into the stream.
+
+    @param data Byte array to write into the stream.
+    @param offset Location in the byte array at which writing begins.
+    @param length Number of bytes to write.
+  */
+  void write(
+    byte[] data,
+    int offset,
+    int length
+    );
+
+  /**
+    Writes a string into the stream.
+
+    @param data String to write into the stream.
+  */
+  void write(
+    String data
+    );
+
+  /**
+    Writes an {@link IInputStream IInputStream} into the stream.
+
+    @param data IInputStream to write into the stream.
+  */
+  void write(
+    IInputStream data
+    );
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/bytes/IStream.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/bytes/IStream.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/bytes/IStream.java	(revision 23703)
@@ -0,0 +1,45 @@
+/*
+  Copyright 2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.bytes;
+
+import java.io.Closeable;
+
+/**
+  Base stream interface.
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+  @since 0.0.8
+*/
+public interface IStream
+  extends Closeable
+{
+  /**
+    Gets the length of the stream.
+  */
+  long getLength(
+    );
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/bytes/OutputStream.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/bytes/OutputStream.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/bytes/OutputStream.java	(revision 23703)
@@ -0,0 +1,149 @@
+/*
+  Copyright 2006-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.bytes;
+
+import java.io.EOFException;
+import java.io.IOException;
+
+/**
+  Output stream default implementation.
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+*/
+public final class OutputStream
+  implements IOutputStream
+{
+  // <class>
+  // <dynamic>
+  // <fields>
+  private java.io.OutputStream stream;
+
+  private int length;
+  // </fields>
+
+  // <constructors>
+  public OutputStream(
+    java.io.OutputStream stream
+    )
+  {this.stream = stream;}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  // <IOutputStream>
+  public void write(
+    byte[] data
+    )
+  {
+    try
+    {stream.write(data);}
+    catch(IOException e)
+    {throw new RuntimeException(e);}
+
+    length += data.length;
+  }
+
+  public void write(
+    byte[] data,
+    int offset,
+    int length
+    )
+  {
+    try
+    {stream.write(data,offset,length);}
+    catch(IOException e)
+    {throw new RuntimeException(e);}
+
+    this.length += length;
+  }
+
+  public void write(
+    String data
+    )
+  {
+    try
+    {stream.write(data.getBytes("ISO-8859-1"));}
+    catch(IOException e)
+    {throw new RuntimeException(e);}
+
+    length += data.length();
+  }
+
+  public void write(
+    IInputStream data
+    )
+  {
+    try
+    {
+      // TODO:IMPL bufferize!!!
+      byte[] baseData = new byte[(int)data.getLength()];
+      // Force the source pointer to the BOF (as we must copy the entire content)!
+      data.seek(0);
+      // Read source content!
+      data.read(baseData);
+      // Write target content!
+      write(baseData);
+    }
+    catch(EOFException e)
+    {throw new RuntimeException(e);}
+  }
+
+  // <IStream>
+  public long getLength(
+    )
+  {return length;}
+  
+  // <Closeable>
+  public void close(
+    ) throws IOException
+  {
+    if(stream != null)
+    {
+      stream.close();
+      stream = null;
+    }
+  }
+  // </Closeable>
+  // </IStream>
+  // </IOutputStream>
+  // </public>
+  
+  // <protected>
+  @Override
+  protected void finalize(
+    ) throws Throwable
+  {
+    try
+    {close();}
+    finally
+    {super.finalize();}
+  }
+  // </protected>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/bytes/filters/ASCII85Filter.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/bytes/filters/ASCII85Filter.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/bytes/filters/ASCII85Filter.java	(revision 23703)
@@ -0,0 +1,314 @@
+/*
+  Copyright 2009 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * J. James Jack, Ph.D., Senior Consultant at Symyx Technologies UK Ltd. (original
+      C# code developer, james{dot}jack{at}symyx{dot}com)
+    * Stefano Chizzolini (source code porting to Java, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.bytes.filters;
+
+import java.io.ByteArrayOutputStream;
+
+/**
+  ASCII base-85 filter [PDF:1.6:3.3.2].
+
+  @author J. James Jack (james{dot}jack{at}symyx{dot}com)
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+  @since 0.0.8
+*/
+public class ASCII85Filter
+  extends Filter
+{
+  // <class>
+  // <types>
+  private static final class Params
+  {
+    int linePos;
+    int tuple = 0;
+  }
+  // </types>
+
+  // <static>
+  // <fields>
+  /**
+    Prefix mark that identifies an encoded ASCII85 string.
+  */
+  private static final String PrefixMark = "<~";
+  /**
+    Suffix mark that identifies an encoded ASCII85 string.
+  */
+  private static final String SuffixMark = "~>";
+
+  /**
+    Add the Prefix and Suffix marks when encoding, and enforce their presence for decoding.
+  */
+  private static final boolean EnforceMarks = true;
+
+  /**
+    Maximum line length for encoded ASCII85 string; set to zero for one unbroken line.
+  */
+  private static final int LineLength = 75;
+
+  private static final int AsciiOffset = 33;
+
+  private static final int[] Pow85 = { 85 * 85 * 85 * 85, 85 * 85 * 85, 85 * 85, 85, 1 };
+
+  private static final String Encoding = "US-ASCII";
+  // </fields>
+
+  // <interface>
+  // <private>
+  private static void appendChar(
+    StringBuilder buffer,
+    char data,
+    Params params
+    )
+  {
+    buffer.append(data);
+    params.linePos++;
+    if(LineLength > 0
+      && params.linePos >= LineLength)
+    {
+      params.linePos = 0;
+      buffer.append('\n');
+    }
+  }
+
+  private static void appendString(
+    StringBuilder buffer,
+    String data,
+    Params params
+    )
+  {
+    if(LineLength > 0
+      && params.linePos + data.length() > LineLength)
+    {
+      params.linePos = 0;
+      buffer.append('\n');
+    }
+    else
+    {params.linePos += data.length();}
+    buffer.append(data);
+  }
+
+  private static void decodeBlock(
+    byte[] decodedBlock,
+    Params params
+    )
+  {decodeBlock(decodedBlock, decodedBlock.length, params);}
+
+  private static void decodeBlock(
+    byte[] decodedBlock,
+    int count,
+    Params params
+    )
+  {
+    for(int i = 0; i < count; i++)
+    {decodedBlock[i] = (byte)(params.tuple >> 24 - (i * 8));}
+  }
+
+  private static void encodeBlock(
+    byte[] encodedBlock,
+    StringBuilder buffer,
+    Params params
+    )
+  {encodeBlock(encodedBlock, encodedBlock.length, buffer, params);}
+
+  private static void encodeBlock(
+    byte[] encodedBlock,
+    int count,
+    StringBuilder buffer,
+    Params params
+    )
+  {
+    for(int i = encodedBlock.length - 1; i >= 0; i--)
+    {
+      encodedBlock[i] = (byte)((params.tuple % 85) + AsciiOffset);
+      params.tuple /= 85;
+    }
+
+    for(int i = 0; i < count; i++)
+    {appendChar(buffer, (char)encodedBlock[i], params);}
+  }
+
+  private static byte[] getBytes(
+    String data
+    )
+  {
+    try{return data.getBytes(Encoding);}
+    catch(Exception e)
+    {throw new RuntimeException(e);}
+  }
+  // </private>
+  // </interface>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  ASCII85Filter(
+    )
+  {}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public byte[] decode(
+    byte[] data,
+    int offset,
+    int length
+    )
+  {
+    byte[] decodedBlock = new byte[4];
+    byte[] encodedBlock = new byte[5];
+
+    Params params = new Params();
+
+    String dataString;
+    try
+    {dataString = new String(data,Encoding).trim();}
+    catch(Exception e)
+    {throw new RuntimeException(e);}
+
+    // Stripping prefix and suffix...
+    if(dataString.startsWith(PrefixMark))
+    {dataString = dataString.substring(PrefixMark.length());}
+    if(dataString.endsWith(SuffixMark))
+    {dataString = dataString.substring(0, dataString.length() - SuffixMark.length());}
+
+    ByteArrayOutputStream stream = new ByteArrayOutputStream();
+    int count = 0;
+    boolean processChar = false;
+    for(char dataChar : dataString.toCharArray())
+    {
+      switch(dataChar)
+      {
+        case 'z':
+          if(count != 0)
+            throw new RuntimeException("The character 'z' is invalid inside an ASCII85 block.");
+
+          decodedBlock[0] = 0;
+          decodedBlock[1] = 0;
+          decodedBlock[2] = 0;
+          decodedBlock[3] = 0;
+          stream.write(decodedBlock, 0,decodedBlock.length);
+          processChar = false;
+          break;
+        case '\n':
+        case '\r':
+        case '\t':
+        case '\0':
+        case '\f':
+        case '\b':
+          processChar = false;
+          break;
+        default:
+          if(dataChar < '!' || dataChar > 'u')
+            throw new RuntimeException("Bad character '" + dataChar + "' found. ASCII85 only allows characters '!' to 'u'.");
+
+          processChar = true;
+          break;
+      }
+
+      if(processChar)
+      {
+        params.tuple += ((int)(dataChar - AsciiOffset) * Pow85[count]);
+        count++;
+        if(count == encodedBlock.length)
+        {
+          decodeBlock(decodedBlock, params);
+          stream.write(decodedBlock, 0,decodedBlock.length);
+          params.tuple = 0;
+          count = 0;
+        }
+      }
+    }
+
+    // Bytes left over at the end?
+    if(count != 0)
+    {
+      if(count == 1)
+        throw new RuntimeException("The last block of ASCII85 data cannot be a single byte.");
+
+      count--;
+      params.tuple += Pow85[count];
+      decodeBlock(decodedBlock, count, params);
+      for(int i = 0; i < count; i++)
+      {stream.write(decodedBlock[i]);}
+    }
+
+    return stream.toByteArray();
+  }
+
+  @Override
+  public byte[] encode(
+    byte[] data,
+    int offset,
+    int length
+    )
+  {
+      byte[] decodedBlock = new byte[4];
+      byte[] encodedBlock = new byte[5];
+
+      Params params = new Params();
+
+      StringBuilder buffer = new StringBuilder((int)(data.length * (encodedBlock.length / decodedBlock.length)));
+
+      if(EnforceMarks)
+      {appendString(buffer, PrefixMark, params);}
+
+      int count = 0;
+      for(byte dataByte : data)
+      {
+        if(count >= decodedBlock.length - 1)
+        {
+          params.tuple |= dataByte;
+          if(params.tuple == 0)
+          {appendChar(buffer, 'z', params);}
+          else
+          {encodeBlock(encodedBlock, buffer, params);}
+          params.tuple = 0;
+          count = 0;
+        }
+        else
+        {
+          params.tuple |= (int)(dataByte << (24 - (count * 8)));
+          count++;
+        }
+      }
+
+      // if we have some bytes left over at the end..
+      if(count > 0)
+      {encodeBlock(encodedBlock, count + 1, buffer, params);}
+
+      if(EnforceMarks)
+      {appendString(buffer, SuffixMark, params);}
+
+      return getBytes(buffer.toString());
+  }
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/bytes/filters/Filter.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/bytes/filters/Filter.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/bytes/filters/Filter.java	(revision 23703)
@@ -0,0 +1,122 @@
+/*
+  Copyright 2006-2009 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.bytes.filters;
+
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+/**
+  Abstract filter [PDF:1.6:3.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+  @since 0.0.2
+*/
+public abstract class Filter
+{
+  // <class>
+  // <static>
+  // <fields>
+  private static final Filter ASCII85Filter = new ASCII85Filter();
+  private static final Filter FlateDecode = new FlateFilter();
+  // </fields>
+
+  // <interface>
+  // <public>
+  /**
+    Gets a specific filter object.
+    @param name Name of the requested filter.
+    @return Filter object associated to the name.
+  */
+  public static Filter get(
+    PdfName name
+    )
+  {
+    /*
+      NOTE: This is a factory singleton method for any filter-derived object.
+    */
+    if(name == null)
+      return null;
+
+    if(name.equals(PdfName.FlateDecode)
+      || name.equals(PdfName.Fl))
+      return FlateDecode;
+    else if(name.equals(PdfName.LZWDecode)
+      || name.equals(PdfName.LZW))
+      throw new NotImplementedException("LZWDecode");
+    else if(name.equals(PdfName.ASCIIHexDecode)
+      || name.equals(PdfName.AHx))
+      throw new NotImplementedException("ASCIIHexDecode");
+    else if(name.equals(PdfName.ASCII85Decode)
+      || name.equals(PdfName.A85))
+      return ASCII85Filter;
+    else if(name.equals(PdfName.RunLengthDecode)
+      || name.equals(PdfName.RL))
+      throw new NotImplementedException("RunLengthDecode");
+    else if(name.equals(PdfName.CCITTFaxDecode)
+      || name.equals(PdfName.CCF))
+      throw new NotImplementedException("CCITTFaxDecode");
+    else if(name.equals(PdfName.JBIG2Decode))
+      throw new NotImplementedException("JBIG2Decode");
+    else if(name.equals(PdfName.DCTDecode)
+      || name.equals(PdfName.DCT))
+      throw new NotImplementedException("DCTDecode");
+    else if(name.equals(PdfName.JPXDecode))
+      throw new NotImplementedException("JPXDecode");
+    else if(name.equals(PdfName.Crypt))
+      throw new NotImplementedException("Crypt");
+
+    return null;
+  }
+  // </public>
+  // </interface>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  protected Filter(
+    )
+  {}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  public abstract byte[] decode(
+    byte[] data,
+    int offset,
+    int length
+    );
+
+  public abstract byte[] encode(
+    byte[] data,
+    int offset,
+    int length
+    );
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/bytes/filters/FlateFilter.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/bytes/filters/FlateFilter.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/bytes/filters/FlateFilter.java	(revision 23703)
@@ -0,0 +1,117 @@
+/*
+  Copyright 2006 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.bytes.filters;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.zip.DeflaterOutputStream;
+import java.util.zip.InflaterInputStream;
+
+/**
+  zlib/deflate [RFC:1950,1951] filter [PDF:1.6:3.3.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.2
+  @since 0.0.2
+*/
+public class FlateFilter
+  extends Filter
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  FlateFilter(
+    )
+  {}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public byte[] decode(
+    byte[] data,
+    int offset,
+    int length
+    )
+  {
+    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+    try
+    {
+      InflaterInputStream inputFilter = new InflaterInputStream(
+        new ByteArrayInputStream(data,offset,length)
+        );
+
+      transform(inputFilter,outputStream);
+    }
+    catch(IOException e)
+    {throw new RuntimeException("Decoding failed.",e);}
+
+    return outputStream.toByteArray();
+  }
+
+  @Override
+  public byte[] encode(
+    byte[] data,
+    int offset,
+    int length
+    )
+  {
+    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+    try
+    {
+      DeflaterOutputStream outputFilter = new DeflaterOutputStream(outputStream);
+      ByteArrayInputStream inputStream = new ByteArrayInputStream(data,offset,length);
+
+      transform(inputStream,outputFilter);
+    }
+    catch(IOException e)
+    {throw new RuntimeException("Encoding failed.",e);}
+
+    return outputStream.toByteArray();
+  }
+  // </public>
+
+  // <private>
+  private void transform(
+    InputStream input,
+    OutputStream output
+    )
+    throws IOException
+  {
+    byte[] buffer = new byte[8192]; int bufferLength;
+    while((bufferLength = input.read(buffer, 0, buffer.length)) != -1)
+    {output.write(buffer, 0, bufferLength);}
+
+    input.close(); output.close();
+  }
+  // </private>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/bytes/filters/package.html
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/bytes/filters/package.html	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/bytes/filters/package.html	(revision 23703)
@@ -0,0 +1,37 @@
+<html>
+<head>
+<!--
+  Copyright 2006-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+-->
+</head>
+<body>
+<p>Stream encoding/decoding filters [PDF:1.6:3.3].</p>
+
+<h2>Related Documentation</h2>
+<p>For overviews, tutorials, examples, guides, and tool documentation, please see:</p>
+<ul>
+  <li><a href="http://clown.stefanochizzolini.it">PDF Clown Home Page</a>
+</ul>
+</body>
+</html>
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/bytes/package.html
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/bytes/package.html	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/bytes/package.html	(revision 23703)
@@ -0,0 +1,37 @@
+<html>
+<head>
+<!--
+  Copyright 2006-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+-->
+</head>
+<body>
+<p>I/O support.</p>
+
+<h2>Related Documentation</h2>
+<p>For overviews, tutorials, examples, guides, and tool documentation, please see:</p>
+<ul>
+  <li><a href="http://clown.stefanochizzolini.it">PDF Clown Home Page</a>
+</ul>
+</body>
+</html>
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/Document.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/Document.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/Document.java	(revision 23703)
@@ -0,0 +1,622 @@
+/*
+  Copyright 2006-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents;
+
+import it.stefanochizzolini.clown.documents.contents.Resources;
+import it.stefanochizzolini.clown.documents.interaction.forms.Form;
+import it.stefanochizzolini.clown.documents.interaction.navigation.document.Bookmarks;
+import it.stefanochizzolini.clown.documents.interaction.navigation.document.Destination;
+import it.stefanochizzolini.clown.documents.interaction.viewer.ViewerPreferences;
+import it.stefanochizzolini.clown.documents.interchange.metadata.Information;
+import it.stefanochizzolini.clown.files.File;
+import it.stefanochizzolini.clown.objects.IPdfNumber;
+import it.stefanochizzolini.clown.objects.PdfArray;
+import it.stefanochizzolini.clown.objects.PdfDictionary;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfObjectWrapper;
+import it.stefanochizzolini.clown.objects.PdfReal;
+import it.stefanochizzolini.clown.objects.PdfReference;
+import it.stefanochizzolini.clown.objects.PdfString;
+import it.stefanochizzolini.clown.objects.Rectangle;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.awt.Dimension;
+import java.awt.geom.Dimension2D;
+import java.util.ArrayList;
+import java.util.Collection;
+
+/**
+  PDF document [PDF:1.6:3.6.1].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+*/
+public class Document
+  extends PdfObjectWrapper<PdfDictionary>
+{
+  // <class>
+  // <static>
+  // <interface>
+  // <public>
+  @SuppressWarnings("unchecked")
+  public static <T extends PdfObjectWrapper<?>> T resolve(
+    Class<T> type,
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {
+    if(Destination.class.isAssignableFrom(type))
+      return (T)Destination.wrap(baseObject,container,null);
+    throw new UnsupportedOperationException("Type '" + type.getName() + "' wrapping is not supported.");
+  }
+
+  /**
+    Forces a named base object to be expressed as its corresponding
+    high-level representation.
+  */
+  public static <T extends PdfObjectWrapper<?>> T resolveName(
+    Class<T> type,
+    PdfDirectObject namedBaseObject,
+    PdfIndirectObject container
+    )
+  {
+    if(namedBaseObject instanceof PdfString) // Named destination.
+      return container.getFile().getDocument().getNames().resolve(type,(PdfString)namedBaseObject);
+    else // Explicit destination.
+      return resolve(type,namedBaseObject,container);
+  }
+  // </public>
+  // </interface>
+  // </static>
+
+  // <dynamic>
+  // <fields>
+  /**
+    For internal use only.
+  */
+  public java.util.Hashtable<PdfReference,Object> cache = new java.util.Hashtable<PdfReference,Object>();
+  // </fields>
+
+  // <constructors>
+  /**
+    For internal use only.
+  */
+  public Document(
+    File context
+    )
+  {
+    super(
+      context,
+      new PdfDictionary(
+        new PdfName[]{PdfName.Type},
+        new PdfDirectObject[]{PdfName.Catalog}
+        ) // Document catalog [PDF:1.6:3.6.1].
+      );
+
+    /*
+      NOTE: Here is just a minimal initialization.
+      Any further customization is upon client's responsibility.
+    */
+    // Link the document to the file!
+    context.getTrailer().put(PdfName.Root,getBaseObject()); // Attaches the catalog reference to the file trailer.
+
+    // Initialize the pages collection (page-tree root node)!
+    /*
+      NOTE: The page-tree root node is required [PDF:1.6:3.6.1].
+    */
+    setPages(new Pages(this));
+
+    // Default page size.
+    setPageSize(PageFormat.getSize());
+
+    // Default resources collection.
+    setResources(new Resources(this));
+  }
+
+  /**
+    For internal use only.
+  */
+  public Document(
+    PdfDirectObject baseObject // Catalog.
+    )
+  {
+    super(
+      baseObject,
+      null // NO container (catalog MUST be an indirect object [PDF:1.6:3.4.4]).
+      );
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public Document clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    Clones the object within this document context.
+  */
+  public Object contextualize(
+    PdfObjectWrapper<?> object
+    )
+  {
+    if(object.getFile() == getFile())
+      return object;
+
+    return object.clone(this);
+  }
+
+  /**
+    Clones the collection's objects within this document context.
+  */
+  public Collection<? extends PdfObjectWrapper<?>> contextualize(
+    Collection<? extends PdfObjectWrapper<?>> objects
+    )
+  {
+    ArrayList<PdfObjectWrapper<?>> contextualizedObjects = new ArrayList<PdfObjectWrapper<?>>(objects.size());
+    for(PdfObjectWrapper<?> object : objects)
+    {contextualizedObjects.add((PdfObjectWrapper<?>)contextualize(object));}
+
+    return contextualizedObjects;
+  }
+
+  /**
+    Drops the object from this document context.
+  */
+  public void decontextualize(
+    PdfObjectWrapper<?> object
+    )
+  {
+    if(object.getFile() != getFile())
+      return;
+
+    object.delete();
+  }
+
+  /**
+    Drops the collection's objects from this document context.
+  */
+  public void decontextualize(
+    Collection<? extends PdfObjectWrapper<?>> objects
+    )
+  {
+    for(PdfObjectWrapper<?> object : objects)
+    {decontextualize(object);}
+  }
+
+  /**
+    Gets the document's behavior in response to trigger events.
+
+    @since 0.0.7
+  */
+  public DocumentActions getActions(
+    )
+  {
+    PdfDirectObject actionsObject = getBaseDataObject().get(PdfName.AA);
+    if(actionsObject == null)
+      return null;
+
+    return new DocumentActions(actionsObject,getContainer());
+  }
+
+  /**
+    Gets the bookmark collection [PDF:1.6:8.2.2].
+  */
+  public Bookmarks getBookmarks(
+    )
+  {
+    PdfDirectObject bookmarksObject = getBaseDataObject().get(PdfName.Outlines);
+    if(bookmarksObject == null)
+      return null;
+
+    return new Bookmarks(bookmarksObject);
+  }
+
+  /**
+    Gets the interactive form (AcroForm) [PDF:1.6:8.6.1].
+
+    @since 0.0.7
+  */
+  public Form getForm(
+    )
+  {
+    PdfDirectObject formObject = getBaseDataObject().get(PdfName.AcroForm);
+    if(formObject == null)
+      return null;
+
+    return new Form(formObject,getContainer());
+  }
+
+  /**
+    Gets the document information dictionary [PDF:1.6:10.2.1].
+  */
+  public Information getInformation(
+    )
+  {
+    PdfDirectObject informationObject = getFile().getTrailer().get(PdfName.Info);
+    if(informationObject == null)
+      return null;
+
+    return new Information(informationObject);
+  }
+
+  /**
+    Gets the name dictionary [PDF:1.6:3.6.3].
+  */
+  public Names getNames(
+    )
+  {
+    PdfDirectObject namesObject = getBaseDataObject().get(PdfName.Names);
+    if(namesObject == null)
+      return null;
+
+    return new Names(
+      namesObject,
+      ((PdfReference)getBaseObject()).getIndirectObject()
+      );
+  }
+
+  /**
+    Gets the page layout to be used when the document is opened.
+  */
+  public PageLayoutEnum getPageLayout(
+    )
+  {
+    PdfName value = (PdfName)getBaseDataObject().get(PdfName.PageLayout);
+    if(value.equals(PdfName.OneColumn))
+      return PageLayoutEnum.OneColumn;
+    else if(value.equals(PdfName.TwoColumnLeft))
+      return PageLayoutEnum.TwoColumns;
+    else
+      return PageLayoutEnum.SinglePage;
+  }
+
+  /**
+    Gets the page mode, that is how the document should be displayed when is opened.
+  */
+  public PageModeEnum getPageMode(
+    )
+  {
+    PdfName value = (PdfName)getBaseDataObject().get(PdfName.PageMode);
+    if(value.equals(PdfName.UseOutlines))
+      return PageModeEnum.Outlines;
+    else if(value.equals(PdfName.UseThumbs))
+      return PageModeEnum.Thumbnails;
+    else if(value.equals(PdfName.FullScreen))
+      return PageModeEnum.FullScreen;
+    else
+      return PageModeEnum.Simple;
+  }
+
+  /**
+    Gets the page collection [PDF:1.6:3.6.2].
+  */
+  public Pages getPages(
+    )
+  {return new Pages(getBaseDataObject().get(PdfName.Pages)); /* NOTE: Required. */}
+
+  /**
+    Gets the default page size [PDF:1.6:3.6.2].
+  */
+  public Dimension2D getPageSize(
+    )
+  {
+    /*
+      NOTE: Due to the contract,
+      we cannot force the existence of the default media box at document level.
+    */
+    PdfArray box = getMediaBox();
+    if(box == null)
+      return null;
+
+    return new Dimension(
+      (int)((IPdfNumber)box.get(2)).getNumberValue(),
+      (int)((IPdfNumber)box.get(3)).getNumberValue()
+      );
+  }
+
+  /**
+    Gets the default resource collection [PDF:1.6:3.6.2].
+    <h3>Remarks</h3>
+    <p>The default resource collection is used as last resort by every page that doesn't reference one
+    explicitly (and doesn't reference an intermediate one implicitly).</p>
+  */
+  public Resources getResources(
+    )
+  {
+    PdfReference pages = (PdfReference)getBaseDataObject().get(PdfName.Pages);
+    PdfDirectObject resources = ((PdfDictionary)File.resolve(pages)).get(PdfName.Resources);
+    if(resources == null)
+      return null;
+
+    return new Resources(
+      resources,
+      pages.getIndirectObject()
+      );
+  }
+
+  /**
+    Gets the document size, that is the maximum page dimensions across the whole document.
+  */
+  public Dimension2D getSize(
+    )
+  {
+    int height = 0, width = 0;
+    for(Page page : getPages())
+    {
+      Dimension2D pageSize = page.getSize();
+      if(pageSize == null)
+        continue;
+
+      height = Math.max(height,(int)pageSize.getHeight());
+      width = Math.max(width,(int)pageSize.getWidth());
+    }
+    return new Dimension(width,height);
+  }
+
+  /**
+    Gets the version of the PDF specification to which the document conforms [PDF:1.6:3.6.1].
+  */
+  public String getVersion(
+    )
+  {
+    /*
+      NOTE: If the header specifies a later version, or if this entry is absent,
+      the document conforms to the version specified in the header.
+    */
+    String fileVersion = getFile().getVersion(); // Header version.
+
+    /*
+      NOTE: 'Version' entry may be undefined.
+    */
+    PdfName versionObject = (PdfName)getBaseDataObject().get(PdfName.Version);
+    if(versionObject == null)
+      return fileVersion;
+
+    String version = versionObject.getRawValue();
+    if(getFile().getReader() == null) // New file.
+      return version;
+
+    String[] fileVersionDigits;
+    String[] versionDigits;
+    try
+    {
+      fileVersionDigits = fileVersion.split("\\.");
+      versionDigits = version.split("\\.");
+    }
+    catch(Exception exception)
+    {throw new RuntimeException("Version decomposition failed.",exception);}
+
+    try
+    {
+      if(Integer.parseInt(versionDigits[0]) > Integer.parseInt(fileVersionDigits[0])
+        || (Integer.parseInt(versionDigits[0]) == Integer.parseInt(fileVersionDigits[0])
+          && Integer.parseInt(versionDigits[1]) > Integer.parseInt(fileVersionDigits[1])))
+        return version;
+
+      return fileVersion;
+    }
+    catch(Exception exception)
+    {throw new RuntimeException("Wrong version format.",exception);}
+  }
+
+  /**
+    Gets the way the document is to be presented [PDF:1.6:8.1].
+  */
+  public ViewerPreferences getViewerPreferences(
+    )
+  {
+    PdfDirectObject viewerPreferences = getBaseDataObject().get(PdfName.ViewerPreferences);
+    if(viewerPreferences == null)
+      return null;
+
+    return new ViewerPreferences(
+      viewerPreferences,
+      ((PdfReference)getBaseObject()).getIndirectObject() //TODO: getContainer()?
+      );
+  }
+
+  /**
+    @see #getActions()
+  */
+  public void setActions(
+    DocumentActions value
+    )
+  {getBaseDataObject().put(PdfName.AA, value.getBaseObject());}
+
+  /**
+    @see #getBookmarks()
+  */
+  public void setBookmarks(
+    Bookmarks value
+    )
+  {getBaseDataObject().put(PdfName.Outlines,value.getBaseObject());}
+
+  /**
+    @see #getForm()
+    @since 0.0.7
+  */
+  public void setForm(
+    Form value
+    )
+  {getBaseDataObject().put(PdfName.AcroForm,value.getBaseObject());}
+
+  /**
+    @see #getInformation()
+  */
+  public void setInformation(
+    Information value
+    )
+  {getFile().getTrailer().put(PdfName.Info,value.getBaseObject());}
+
+  /**
+    @see #getNames()
+    @since 0.0.4
+  */
+  public void setNames(
+    Names value
+    )
+  {getBaseDataObject().put(PdfName.Names,value.getBaseObject());}
+
+  /**
+    @see #getPageLayout()
+  */
+  public void setPageLayout(
+    PageLayoutEnum value
+    )
+  {
+    switch(value)
+    {
+      case SinglePage:
+        getBaseDataObject().put(PdfName.PageLayout,PdfName.SinglePage);
+        break;
+      case OneColumn:
+        getBaseDataObject().put(PdfName.PageLayout,PdfName.OneColumn);
+        break;
+      case TwoColumns:
+        getBaseDataObject().put(PdfName.PageLayout,PdfName.TwoColumnLeft);
+        break;
+    }
+  }
+
+  /**
+    @see #getPageMode()
+  */
+  public void setPageMode(
+    PageModeEnum value
+    )
+  {
+    switch(value)
+    {
+      case Simple:
+        getBaseDataObject().put(PdfName.PageMode,PdfName.UseNone);
+        break;
+      case Outlines:
+        getBaseDataObject().put(PdfName.PageMode,PdfName.UseOutlines);
+        break;
+      case Thumbnails:
+        getBaseDataObject().put(PdfName.PageMode,PdfName.UseThumbs);
+        break;
+      case FullScreen:
+        getBaseDataObject().put(PdfName.PageMode,PdfName.FullScreen);
+        break;
+    }
+  }
+
+  /**
+    @see #getPages()
+  */
+  public void setPages(
+    Pages value
+    )
+  {getBaseDataObject().put(PdfName.Pages,value.getBaseObject());}
+
+  /**
+    @see #getPageSize()
+  */
+  public void setPageSize(
+    Dimension2D value
+    )
+  {
+    PdfArray mediaBox = getMediaBox();
+    if(mediaBox == null)
+    {
+      // Create default media box!
+      mediaBox = new Rectangle(0,0,0,0).getBaseDataObject();
+      // Assign the media box to the document!
+      ((PdfDictionary)File.resolve(
+        getBaseDataObject().get(PdfName.Pages)
+        )).put(PdfName.MediaBox,mediaBox);
+    }
+
+    mediaBox.set(2,new PdfReal(value.getWidth()));
+    mediaBox.set(3,new PdfReal(value.getHeight()));
+  }
+
+  /**
+    @see #getResources()
+  */
+  public void setResources(
+    Resources value
+    )
+  {
+    PdfReference pages = (PdfReference)getBaseDataObject().get(PdfName.Pages);
+    ((PdfDictionary)File.resolve(pages)).put(
+      PdfName.Resources,
+      value.getBaseObject()
+      );
+    value.setContainer(
+      pages.getIndirectObject()
+      ); // Resources object could be directly inside a container.
+  }
+
+  /**
+    @see #getVersion()
+  */
+  public void setVersion(
+    String value
+    )
+  {getBaseDataObject().put(PdfName.Version,new PdfName(value));}
+
+  /**
+    @see #getViewerPreferences()
+  */
+  public void setViewerPreferences(
+    ViewerPreferences value
+    )
+  {
+    getBaseDataObject().put(
+      PdfName.ViewerPreferences,
+      value.getBaseObject()
+      );
+    value.setContainer(
+      ((PdfReference)getBaseObject()).getIndirectObject()
+      ); // ViewerPreferences object could be directly inside a container.
+  }
+  // </public>
+
+  // <private>
+  /**
+    Gets the default media box.
+  */
+  private PdfArray getMediaBox(
+    )
+  {
+    /*
+      NOTE: Document media box MUST be associated with the page-tree root node
+      in order to be inheritable by all the pages.
+    */
+    return (PdfArray)((PdfDictionary)getBaseDataObject().resolve(PdfName.Pages)).resolve(PdfName.MediaBox);
+  }
+  // </private>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/DocumentActions.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/DocumentActions.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/DocumentActions.java	(revision 23703)
@@ -0,0 +1,235 @@
+/*
+  Copyright 2008-2009 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents;
+
+import it.stefanochizzolini.clown.documents.interaction.actions.Action;
+import it.stefanochizzolini.clown.documents.interaction.navigation.document.Destination;
+import it.stefanochizzolini.clown.documents.interaction.navigation.document.LocalDestination;
+import it.stefanochizzolini.clown.objects.PdfDictionary;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfObjectWrapper;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+/**
+  Document actions [PDF:1.6:8.5.2].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+  @since 0.0.7
+*/
+public class DocumentActions
+  extends PdfObjectWrapper<PdfDictionary>
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  public DocumentActions(
+    Document context
+    )
+  {
+    super(
+      context.getFile(),
+      new PdfDictionary()
+      );
+  }
+
+  public DocumentActions(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {super(baseObject,container);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public DocumentActions clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    Gets the action to be performed after printing the document.
+  */
+  public Action getAfterPrint(
+    )
+  {
+    /*
+      NOTE: 'DP' entry may be undefined.
+    */
+    PdfDirectObject afterPrintObject = getBaseDataObject().get(PdfName.DP);
+    if(afterPrintObject == null)
+      return null;
+
+    return Action.wrap(afterPrintObject,getContainer());
+  }
+
+  /**
+    Gets the action to be performed after saving the document.
+  */
+  public Action getAfterSave(
+    )
+  {
+    /*
+      NOTE: 'DS' entry may be undefined.
+    */
+    PdfDirectObject afterSaveObject = getBaseDataObject().get(PdfName.DS);
+    if(afterSaveObject == null)
+      return null;
+
+    return Action.wrap(afterSaveObject,getContainer());
+  }
+
+  /**
+    Gets the action to be performed before printing the document.
+  */
+  public Action getBeforePrint(
+    )
+  {
+    /*
+      NOTE: 'WP' entry may be undefined.
+    */
+    PdfDirectObject beforePrintObject = getBaseDataObject().get(PdfName.WP);
+    if(beforePrintObject == null)
+      return null;
+
+    return Action.wrap(beforePrintObject,getContainer());
+  }
+
+  /**
+    Gets the action to be performed before saving the document.
+  */
+  public Action getBeforeSave(
+    )
+  {
+    /*
+      NOTE: 'WS' entry may be undefined.
+    */
+    PdfDirectObject beforeSaveObject = getBaseDataObject().get(PdfName.WS);
+    if(beforeSaveObject == null)
+      return null;
+
+    return Action.wrap(beforeSaveObject,getContainer());
+  }
+
+  /**
+    Gets the action to be performed before closing the document.
+  */
+  public Action getOnClose(
+    )
+  {
+    /*
+      NOTE: 'DC' entry may be undefined.
+    */
+    PdfDirectObject onCloseObject = getBaseDataObject().get(PdfName.DC);
+    if(onCloseObject == null)
+      return null;
+
+    return Action.wrap(onCloseObject,getContainer());
+  }
+
+  /**
+    Gets the destination to be displayed or the action to be performed
+    after opening the document.
+  */
+  public PdfObjectWrapper<?> getOnOpen(
+    )
+  {
+    /*
+      NOTE: 'OpenAction' entry may be undefined.
+    */
+    PdfDirectObject onOpenObject = getDocument().getBaseDataObject().get(PdfName.OpenAction);
+    if(onOpenObject == null)
+      return null;
+
+    if(onOpenObject instanceof PdfDictionary) // Action (dictionary).
+      return Action.wrap(onOpenObject,getContainer());
+    else // Destination (array).
+      return Destination.wrap(onOpenObject,getContainer(),null);
+  }
+
+  /**
+    @see #getAfterPrint()
+  */
+  public void setAfterPrint(
+    Action value
+    )
+  {getBaseDataObject().put(PdfName.DP, value.getBaseObject());}
+
+  /**
+    @see #getAfterSave()
+  */
+  public void setAfterSave(
+    Action value
+    )
+  {getBaseDataObject().put(PdfName.DS, value.getBaseObject());}
+
+  /**
+    @see #getBeforePrint()
+  */
+  public void setBeforePrint(
+    Action value
+    )
+  {getBaseDataObject().put(PdfName.WP, value.getBaseObject());}
+
+  /**
+    @see #getBeforeSave()
+  */
+  public void setBeforeSave(
+    Action value
+    )
+  {getBaseDataObject().put(PdfName.WS, value.getBaseObject());}
+
+  /**
+    @see #getOnClose()
+  */
+  public void setOnClose(
+    Action value
+    )
+  {getBaseDataObject().put(PdfName.DC, value.getBaseObject());}
+
+  /**
+    @see #getOnOpen()
+  */
+  public void setOnOpen(
+    PdfObjectWrapper<?> value
+    )
+  {
+    if(!(value instanceof Action
+      || value instanceof LocalDestination))
+      throw new IllegalArgumentException("Value MUST be either an Action or a LocalDestination.");
+
+    Document document = getDocument();
+    document.getBaseDataObject().put(PdfName.OpenAction, value.getBaseObject());
+    document.update(); // Ensures that the document's object modification is preserved.
+  }
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/NamedDestinations.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/NamedDestinations.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/NamedDestinations.java	(revision 23703)
@@ -0,0 +1,112 @@
+/*
+  Copyright 2007-2009 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents;
+
+import it.stefanochizzolini.clown.documents.interaction.navigation.document.Destination;
+import it.stefanochizzolini.clown.files.File;
+import it.stefanochizzolini.clown.objects.NameTree;
+import it.stefanochizzolini.clown.objects.PdfDataObject;
+import it.stefanochizzolini.clown.objects.PdfDictionary;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfReference;
+import it.stefanochizzolini.clown.objects.PdfString;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+/**
+  Named destinations [PDF:1.6:3.6.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+  @since 0.0.4
+*/
+public class NamedDestinations
+  extends NameTree<Destination>
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  public NamedDestinations(
+    Document context
+    )
+  {super(context);}
+
+  public NamedDestinations(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {
+    super(
+      baseObject,
+      container
+      );
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public NamedDestinations clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+  // </public>
+
+  // <protected>
+  @Override
+  protected Destination wrap(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container,
+    PdfString name
+    )
+  {
+    /*
+      NOTE: A named destination may be either an array defining the destination,
+      or a dictionary with a D entry whose value is such an array [PDF:1.6:8.2.1].
+    */
+    PdfDirectObject destinationObject;
+    {
+      PdfDataObject baseDataObject = File.resolve(baseObject);
+      if(baseDataObject instanceof PdfDictionary)
+      {destinationObject = ((PdfDictionary)baseDataObject).get(PdfName.D);}
+      else
+      {destinationObject = baseObject;}
+    }
+
+    return Destination.wrap(
+      destinationObject,
+      baseObject instanceof PdfReference
+        ? ((PdfReference)baseObject).getIndirectObject()
+        : container,
+      name
+      );
+  }
+  // </protected>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/NamedEmbeddedFiles.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/NamedEmbeddedFiles.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/NamedEmbeddedFiles.java	(revision 23703)
@@ -0,0 +1,92 @@
+/*
+  Copyright 2008-2009 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents;
+
+import it.stefanochizzolini.clown.documents.fileSpecs.FileSpec;
+import it.stefanochizzolini.clown.objects.NameTree;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfString;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+/**
+  Named embedded files [PDF:1.6:3.6.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+  @since 0.0.7
+*/
+public class NamedEmbeddedFiles
+  extends NameTree<FileSpec>
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  public NamedEmbeddedFiles(
+    Document context
+    )
+  {super(context);}
+
+  public NamedEmbeddedFiles(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {
+    super(
+      baseObject,
+      container
+      );
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public NamedEmbeddedFiles clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+  // </public>
+
+  // <protected>
+  @Override
+  protected FileSpec wrap(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container,
+    PdfString name
+    )
+  {
+    return new FileSpec(
+      baseObject,
+      container,
+      name
+      );
+  }
+  // </protected>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/Names.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/Names.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/Names.java	(revision 23703)
@@ -0,0 +1,155 @@
+/*
+  Copyright 2007-2009 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.fileSpecs.FileSpec;
+import it.stefanochizzolini.clown.documents.interaction.navigation.document.Destination;
+import it.stefanochizzolini.clown.objects.PdfDictionary;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfObjectWrapper;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfString;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+/**
+  Name dictionary [PDF:1.6:3.6.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.7
+  @since 0.0.4
+*/
+public class Names
+  extends PdfObjectWrapper<PdfDictionary>
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  public Names(
+    Document context
+    )
+  {
+    super(
+      context.getFile(),
+      new PdfDictionary()
+      );
+  }
+
+  /**
+    For internal use only.
+  */
+  public Names(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {
+    super(
+      baseObject,
+      container
+      );
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public Names clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    Gets the map of name strings to destinations.
+  */
+  public NamedDestinations getDestinations(
+    )
+  {
+    /*
+      NOTE: 'Dests' entry may be undefined.
+    */
+    PdfDirectObject destinations = getBaseDataObject().get(PdfName.Dests);
+    if(destinations == null)
+      return null;
+
+    return new NamedDestinations(
+      destinations,
+      getContainer()
+      );
+  }
+
+  /**
+    Gets the map of name strings to embedded files.
+  */
+  public NamedEmbeddedFiles getEmbeddedFiles(
+    )
+  {
+    /*
+      NOTE: 'EmbeddedFiles' entry may be undefined.
+    */
+    PdfDirectObject embeddedFiles = getBaseDataObject().get(PdfName.EmbeddedFiles);
+    if(embeddedFiles == null)
+      return null;
+
+    return new NamedEmbeddedFiles(
+      embeddedFiles,
+      getContainer()
+      );
+  }
+
+  @SuppressWarnings("unchecked")
+  public <T extends PdfObjectWrapper> T resolve(
+    Class<T> type,
+    PdfString name
+    )
+  {
+    if(Destination.class.isAssignableFrom(type))
+      return (T)getDestinations().get(name);
+    if(FileSpec.class.isAssignableFrom(type))
+      return (T)getEmbeddedFiles().get(name);
+    throw new UnsupportedOperationException("Named type '" + type.getName() + "' is not supported.");
+  }
+
+  /**
+    Sets the map of name strings to destinations.
+  */
+  public void setDestinations(
+    NamedDestinations value
+    )
+  {getBaseDataObject().put(PdfName.Dests,value.getBaseObject());}
+
+  /**
+    @see #getEmbeddedFiles()
+  */
+  public void setEmbeddedFiles(
+    NamedEmbeddedFiles value
+    )
+  {getBaseDataObject().put(PdfName.EmbeddedFiles,value.getBaseObject());}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/Page.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/Page.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/Page.java	(revision 23703)
@@ -0,0 +1,601 @@
+/*
+  Copyright 2006-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents;
+
+import it.stefanochizzolini.clown.bytes.IBuffer;
+import it.stefanochizzolini.clown.documents.contents.Contents;
+import it.stefanochizzolini.clown.documents.contents.IContentContext;
+import it.stefanochizzolini.clown.documents.contents.Resources;
+import it.stefanochizzolini.clown.documents.contents.composition.PrimitiveFilter;
+import it.stefanochizzolini.clown.documents.contents.objects.ContentObject;
+import it.stefanochizzolini.clown.documents.contents.xObjects.FormXObject;
+import it.stefanochizzolini.clown.documents.contents.xObjects.XObject;
+import it.stefanochizzolini.clown.documents.interaction.navigation.page.Transition;
+import it.stefanochizzolini.clown.files.File;
+import it.stefanochizzolini.clown.objects.IPdfNumber;
+import it.stefanochizzolini.clown.objects.PdfArray;
+import it.stefanochizzolini.clown.objects.PdfDataObject;
+import it.stefanochizzolini.clown.objects.PdfDictionary;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfInteger;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfObjectWrapper;
+import it.stefanochizzolini.clown.objects.PdfReal;
+import it.stefanochizzolini.clown.objects.PdfReference;
+import it.stefanochizzolini.clown.objects.PdfStream;
+import it.stefanochizzolini.clown.objects.Rectangle;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.awt.Dimension;
+import java.awt.geom.Dimension2D;
+import java.awt.geom.Rectangle2D;
+import java.util.Map;
+
+/**
+  Document page [PDF:1.6:3.6.2].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.0
+  @version 0.0.8
+*/
+public class Page
+  extends PdfObjectWrapper<PdfDictionary>
+  implements IContentContext
+{
+  /*
+    NOTE: Inheritable attributes are NOT early-collected, as they are NOT part
+    of the explicit representation of a page. They are retrieved everytime
+    clients call.
+  */
+  // <class>
+  // <classes>
+  /**
+    Annotations tab order [PDF:1.6:3.6.2].
+  */
+  public enum TabOrderEnum
+  {
+    // <class>
+    // <static>
+    // <fields>
+    /**
+      Row order.
+    */
+    Row(PdfName.R),
+    /**
+      Column order.
+    */
+    Column(PdfName.C),
+    /**
+      Structure order.
+    */
+    Structure(PdfName.S);
+    // </fields>
+
+    // <interface>
+    // <public>
+    /**
+      Gets the tab order corresponding to the given value.
+    */
+    public static TabOrderEnum get(
+      PdfName value
+      )
+    {
+      for(TabOrderEnum tabOrder : TabOrderEnum.values())
+      {
+        if(tabOrder.getCode().equals(value))
+          return tabOrder;
+      }
+      return null;
+    }
+    // </public>
+    // </interface>
+    // </static>
+
+    // <dynamic>
+    // <fields>
+    private final PdfName code;
+    // </fields>
+
+    // <constructors>
+    private TabOrderEnum(
+      PdfName code
+      )
+    {this.code = code;}
+    // </constructors>
+
+    // <interface>
+    // <public>
+    public PdfName getCode(
+      )
+    {return code;}
+    // </public>
+    // </interface>
+    // </dynamic>
+    // </class>
+  }
+  // </classes>
+
+  // <static>
+  // <interface>
+  // <public>
+  public static Page wrap(
+    PdfReference reference
+    )
+  {return new Page(reference);}
+  // </public>
+  // </interface>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  /**
+    Creates a new page within the given document context, using default resources.
+  */
+  public Page(
+    Document context
+    )
+  {
+    super(
+      context.getFile(),
+      new PdfDictionary(
+        new PdfName[]
+        {
+          PdfName.Type,
+          PdfName.Contents
+        },
+        new PdfDirectObject[]
+        {
+          PdfName.Page,
+          context.getFile().register(
+            new PdfStream()
+            )
+        }
+        )
+      );
+  }
+
+  /**
+    Creates a new page within the given document context, using custom resources.
+  */
+  public Page(
+    Document context,
+    Dimension2D size,
+    Resources resources
+    )
+  {
+    super(
+      context.getFile(),
+      new PdfDictionary(
+        new PdfName[]
+        {
+          PdfName.Type,
+          PdfName.MediaBox,
+          PdfName.Contents,
+          PdfName.Resources
+        },
+        new PdfDirectObject[]
+        {
+          PdfName.Page,
+          new Rectangle(0,0,size.getWidth(),size.getHeight()).getBaseDataObject(),
+          context.getFile().register(
+            new PdfStream()
+            ),
+          resources.getBaseObject()
+        }
+        )
+      );
+  }
+
+  /**
+    For internal use only.
+  */
+  public Page(
+    PdfDirectObject baseObject
+    )
+  {
+    super(
+      baseObject,
+      null // NO container. NOTE: this is a simplification (the spec [PDF:1.6] doesn't apparently prescribe the use of an indirect object for page dictionary, whilst the general practice is as such. If an exception occur, you'll need to specify the proper container).
+      );
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public Page clone(
+    Document context
+    )
+  {
+    /*
+      NOTE: We cannot just delegate the cloning to the base object, as it would
+      involve some unwanted objects like those in 'Parent' and 'Annots' entries that may
+      cause infinite loops (due to circular references) and may include exceeding contents
+      (due to copy propagations to the whole page-tree which this page belongs to).
+      TODO: 'Annots' entry must be finely treated to include any non-circular reference.
+    */
+    // TODO:IMPL deal with inheritable attributes!!!
+
+    File contextFile = context.getFile();
+    PdfDictionary clone = new PdfDictionary(getBaseDataObject().size());
+    for(
+      Map.Entry<PdfName,PdfDirectObject> entry : getBaseDataObject().entrySet()
+      )
+    {
+      PdfName key = entry.getKey();
+      // Is the entry unwanted?
+      if(key.equals(PdfName.Parent)
+        || key.equals(PdfName.Annots))
+        continue;
+
+      // Insert the clone of the entry into the clone of the page dictionary!
+      clone.put(
+        key,
+        (PdfDirectObject)entry.getValue().clone(contextFile)
+        );
+    }
+
+    return new Page(
+      contextFile.getIndirectObjects().add(clone).getReference()
+      );
+  }
+
+  /**
+    Gets the page's behavior in response to trigger events.
+  */
+  public PageActions getActions(
+    )
+  {
+    PdfDirectObject actionsObject = getBaseDataObject().get(PdfName.AA);
+    if(actionsObject == null)
+      return null;
+
+    return new PageActions(actionsObject,getContainer());
+  }
+
+  /**
+    Gets the annotations associated to the page.
+  */
+  public PageAnnotations getAnnotations(
+    )
+  {
+    PdfDirectObject annotationsObject = getBaseDataObject().get(PdfName.Annots);
+    if(annotationsObject == null)
+      return null;
+
+    return new PageAnnotations(annotationsObject,getContainer(),this);
+  }
+
+  /**
+    Gets the page's display duration.
+    <p>The page's display duration (also called its advance timing)
+    is the maximum length of time, in seconds, that the page is displayed
+    during presentations before the viewer application automatically advances
+    to the next page.</p>
+    <p>By default, the viewer does not advance automatically.</p>
+  */
+  public double getDuration(
+    )
+  {
+    IPdfNumber durationObject = (IPdfNumber)getBaseDataObject().get(PdfName.Dur);
+    if(durationObject == null)
+      return 0;
+
+    return durationObject.getNumberValue();
+  }
+
+  /**
+    Gets the index of the page.
+    <h3>Remarks</h3>
+    <p>The page index is not an explicit datum, therefore it needs to be
+    inferred from the position of the page object inside the page tree,
+    requiring a significant amount of computation: invoke it sparingly!</p>
+  */
+  public int getIndex(
+    )
+  {
+    /*
+      NOTE: We'll scan sequentially each page-tree level above this page object
+      collecting page counts. At each level we'll scan the kids array from the
+      lower-indexed item to the ancestor of this page object at that level.
+    */
+    PdfReference ancestorKidReference = (PdfReference)getBaseObject();
+    PdfReference parentReference = (PdfReference)getBaseDataObject().get(PdfName.Parent);
+    PdfDictionary parent = (PdfDictionary)File.resolve(parentReference);
+    PdfArray kids = (PdfArray)File.resolve(parent.get(PdfName.Kids));
+    int index = 0;
+    for(
+      int i = 0;
+      true;
+      i++
+      )
+    {
+      PdfReference kidReference = (PdfReference)kids.get(i);
+      // Is the current-level counting complete?
+      // NOTE: It's complete when it reaches the ancestor at the current level.
+      if(kidReference.equals(ancestorKidReference)) // Ancestor node.
+      {
+        // Does the current level correspond to the page-tree root node?
+        if(!parent.containsKey(PdfName.Parent))
+        {
+          // We reached the top: counting's finished.
+          return index;
+        }
+        // Set the ancestor at the next level!
+        ancestorKidReference = parentReference;
+        // Move up one level!
+        parentReference = (PdfReference)parent.get(PdfName.Parent);
+        parent = (PdfDictionary)File.resolve(parentReference);
+        kids = (PdfArray)File.resolve(parent.get(PdfName.Kids));
+        i = -1;
+      }
+      else // Intermediate node.
+      {
+        PdfDictionary kid = (PdfDictionary)File.resolve(kidReference);
+        if(kid.get(PdfName.Type).equals(PdfName.Page))
+          index++;
+        else
+          index += ((PdfInteger)kid.get(PdfName.Count)).getRawValue();
+      }
+    }
+  }
+
+  /**
+    Gets the page size.
+  */
+  public Dimension2D getSize(
+    )
+  {
+    PdfArray box = (PdfArray)File.resolve(
+      getInheritableAttribute(PdfName.MediaBox)
+      );
+    if(box == null)
+      return null;
+
+    return new Dimension(
+      (int)((IPdfNumber)box.get(2)).getNumberValue(),
+      (int)((IPdfNumber)box.get(3)).getNumberValue()
+      );
+  }
+
+  /**
+    Gets the tab order to be used for annotations on the page.
+  */
+  public TabOrderEnum getTabOrder(
+    )
+  {return TabOrderEnum.get((PdfName)getBaseDataObject().get(PdfName.Tabs));}
+
+  /**
+    Gets the transition effect to be used when displaying the page during presentations.
+  */
+  public Transition getTransition(
+    )
+  {
+    PdfDirectObject transitionObject = getBaseDataObject().get(PdfName.Trans);
+    if(transitionObject == null)
+      return null;
+
+    return new Transition(transitionObject,getContainer());
+  }
+
+  /**
+    @see #getActions()
+  */
+  public void setActions(
+    PageActions value
+    )
+  {getBaseDataObject().put(PdfName.AA, value.getBaseObject());}
+
+  /**
+    @see #getAnnotations()
+  */
+  public void setAnnotations(
+    PageAnnotations value
+    )
+  {getBaseDataObject().put(PdfName.Annots, value.getBaseObject());}
+
+  /**
+    @see #getDuration()
+  */
+  public void setDuration(
+    double value
+    )
+  {getBaseDataObject().put(PdfName.Dur,new PdfReal(value));}
+
+  /**
+    @see #getSize()
+  */
+  public void setSize(
+    Dimension2D value
+    )
+  {
+    /*
+      NOTE: When page size is about to be modified, we MUST ensure that the change will affect just
+      the mediaBox of this page; so, if such a mediaBox is implicit (inherited), it MUST be cloned
+      and explicitly assigned to this page in order to apply changes.
+    */
+    PdfDictionary dictionary = getBaseDataObject();
+    PdfDirectObject entry = dictionary.get(PdfName.MediaBox);
+    if(entry == null)
+    {
+      // Clone the inherited attribute in order to restrict its change to this page's scope only!
+      entry = (PdfDirectObject)getInheritableAttribute(PdfName.MediaBox).clone(getFile());
+      // Associate the cloned attribute to this page's dictionary!
+      dictionary.put(PdfName.MediaBox,entry);
+    }
+
+    PdfArray box = (PdfArray)File.resolve(entry);
+    ((IPdfNumber)box.get(2)).setNumberValue(value.getWidth());
+    ((IPdfNumber)box.get(3)).setNumberValue(value.getHeight());
+  }
+
+  /**
+    @see #getTabOrder()
+  */
+  public void setTabOrder(
+    TabOrderEnum value
+    )
+  {getBaseDataObject().put(PdfName.Tabs,value.getCode());}
+
+  /**
+    @see #getTransition()
+  */
+  public void setTransition(
+    Transition value
+    )
+  {getBaseDataObject().put(PdfName.Trans, value.getBaseObject());}
+
+  // <IContentContext>
+  public Rectangle2D getBox(
+    )
+  {
+    PdfArray box = (PdfArray)File.resolve(
+      getInheritableAttribute(PdfName.MediaBox)
+      );
+
+    return new Rectangle2D.Double(
+      ((IPdfNumber)box.get(0)).getNumberValue(),
+      ((IPdfNumber)box.get(1)).getNumberValue(),
+      ((IPdfNumber)box.get(2)).getNumberValue(),
+      ((IPdfNumber)box.get(3)).getNumberValue()
+      );
+  }
+
+  public Contents getContents(
+    )
+  {
+    return new Contents(
+      getBaseDataObject().get(PdfName.Contents),
+      ((PdfReference)getBaseObject()).getIndirectObject(),
+      this
+      );
+  }
+
+  public Resources getResources(
+    )
+  {
+    return new Resources(
+      getInheritableAttribute(PdfName.Resources),
+      ((PdfReference)getBaseObject()).getIndirectObject()
+      );
+  }
+
+  // <IContentEntity>
+  /**
+    @since 0.0.6
+  */
+  public ContentObject toInlineObject(
+    PrimitiveFilter context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    @since 0.0.5
+  */
+  public XObject toXObject(
+    Document context
+    )
+  {
+    File contextFile = context.getFile();
+
+    FormXObject form = new FormXObject(context);
+    PdfStream formStream = form.getBaseDataObject();
+
+    // Header.
+    {
+      PdfDictionary formHeader = formStream.getHeader();
+      // Bounding box.
+      formHeader.put(
+        PdfName.BBox,
+        (PdfDirectObject)getInheritableAttribute(PdfName.MediaBox).clone(contextFile)
+        );
+      // Resources.
+      {
+        PdfDirectObject resourcesObject = getInheritableAttribute(PdfName.Resources);
+        formHeader.put(
+          PdfName.Resources,
+          // Same document?
+          /* NOTE: Try to reuse the resource dictionary whenever possible. */
+          (context.equals(getDocument()) ?
+            resourcesObject
+            : (PdfDirectObject)resourcesObject.clone(contextFile))
+          );
+      }
+    }
+
+    // Body (contents).
+    {
+      IBuffer formBody = formStream.getBody();
+      PdfDataObject contentsDataObject = File.resolve(getBaseDataObject().get(PdfName.Contents));
+      if(contentsDataObject instanceof PdfStream)
+      {formBody.append(((PdfStream)contentsDataObject).getBody());}
+      else
+      {
+        for(PdfDirectObject contentStreamObject : (PdfArray)contentsDataObject)
+        {formBody.append(((PdfStream)File.resolve(contentStreamObject)).getBody());}
+      }
+    }
+
+    return form;
+  }
+  // </IContentEntity>
+  // </IContentContext>
+  // </public>
+
+  // <protected>
+  protected PdfDirectObject getInheritableAttribute(
+    PdfName key
+    )
+  {
+    /*
+      NOTE: It moves upward until it finds the inherited attribute.
+    */
+    PdfDictionary dictionary = getBaseDataObject();
+    while(true)
+    {
+      PdfDirectObject entry = dictionary.get(key);
+      if(entry != null)
+        return entry;
+
+      dictionary = (PdfDictionary)File.resolve(
+        dictionary.get(PdfName.Parent)
+        );
+      if(dictionary == null)
+      {
+        // Isn't the page attached to the page tree?
+        /* NOTE: This condition is illegal. */
+        if(getBaseDataObject().get(PdfName.Parent) == null)
+          throw new RuntimeException("Inheritable attributes unreachable: Page objects MUST be inserted into their document's Pages collection before being used.");
+
+        return null;
+      }
+    }
+  }
+  // </protected>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/PageActions.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/PageActions.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/PageActions.java	(revision 23703)
@@ -0,0 +1,125 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents;
+
+import it.stefanochizzolini.clown.documents.interaction.actions.Action;
+import it.stefanochizzolini.clown.objects.PdfDictionary;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfObjectWrapper;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+/**
+  Page actions [PDF:1.6:8.5.2].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.7
+  @since 0.0.7
+*/
+public class PageActions
+  extends PdfObjectWrapper<PdfDictionary>
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  public PageActions(
+    Document context
+    )
+  {
+    super(
+      context.getFile(),
+      new PdfDictionary()
+      );
+  }
+
+  public PageActions(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {super(baseObject,container);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public PageActions clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    Gets the action to be performed when the page is closed.
+  */
+  public Action getOnClose(
+    )
+  {
+    /*
+      NOTE: 'C' entry may be undefined.
+    */
+    PdfDirectObject onCloseObject = getBaseDataObject().get(PdfName.C);
+    if(onCloseObject == null)
+      return null;
+
+    return Action.wrap(onCloseObject,getContainer());
+  }
+
+  /**
+    Gets the action to be performed when the page is opened.
+  */
+  public Action getOnOpen(
+    )
+  {
+    /*
+      NOTE: 'O' entry may be undefined.
+    */
+    PdfDirectObject onOpenObject = getBaseDataObject().get(PdfName.O);
+    if(onOpenObject == null)
+      return null;
+
+    return Action.wrap(onOpenObject,getContainer());
+  }
+
+  /**
+    @see #getOnClose()
+  */
+  public void setOnClose(
+    Action value
+    )
+  {getBaseDataObject().put(PdfName.C, value.getBaseObject());}
+
+  /**
+    @see #getOnOpen()
+  */
+  public void setOnOpen(
+    Action value
+    )
+  {getBaseDataObject().put(PdfName.O, value.getBaseObject());}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/PageAnnotations.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/PageAnnotations.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/PageAnnotations.java	(revision 23703)
@@ -0,0 +1,311 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents;
+
+import it.stefanochizzolini.clown.documents.interaction.annotations.Annotation;
+import it.stefanochizzolini.clown.objects.PdfArray;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfObjectWrapper;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.NoSuchElementException;
+
+/**
+  Page annotations [PDF:1.6:3.6.2].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+  @since 0.0.7
+*/
+public class PageAnnotations
+  extends PdfObjectWrapper<PdfArray>
+  implements List<Annotation>
+{
+  // <class>
+  // <dynamic>
+  // <fields>
+  private Page page;
+  // </fields>
+
+  // <constructors>
+  PageAnnotations(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container,
+    Page page
+    )
+  {
+    super(
+      baseObject,
+      container
+      );
+
+    this.page = page;
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public PageAnnotations clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    Gets the page associated to these annotations.
+  */
+  public Page getPage(
+    )
+  {return page;}
+
+  // <List>
+  public void add(
+    int index,
+    Annotation value
+    )
+  {getBaseDataObject().add(index,value.getBaseObject());}
+
+  public boolean addAll(
+    int index,
+    Collection<? extends Annotation> values
+    )
+  {
+    PdfArray items = getBaseDataObject();
+    for(Annotation value : values)
+    {items.add(index++,value.getBaseObject());}
+
+    return true;
+  }
+
+  public Annotation get(
+    int index
+    )
+  {return Annotation.wrap(getBaseDataObject().get(index),getContainer());}
+
+  public int indexOf(
+    Object value
+    )
+  {
+    if(!(value instanceof Annotation))
+      return -1;
+
+    return getBaseDataObject().indexOf(((Annotation)value).getBaseObject());
+  }
+
+  public int lastIndexOf(
+    Object value
+    )
+  {
+    /*
+      NOTE: Annotations are expected not to be duplicate.
+    */
+    return indexOf(value);
+  }
+
+  public ListIterator<Annotation> listIterator(
+    )
+  {throw new NotImplementedException();}
+
+  public ListIterator<Annotation> listIterator(
+    int index
+    )
+  {throw new NotImplementedException();}
+
+  public Annotation remove(
+    int index
+    )
+  {
+    PdfDirectObject annotationObject = getBaseDataObject().remove(index);
+    return Annotation.wrap(annotationObject,getContainer());
+  }
+
+  public Annotation set(
+    int index,
+    Annotation value
+    )
+  {return Annotation.wrap(getBaseDataObject().set(index,value.getBaseObject()),getContainer());}
+
+  public List<Annotation> subList(
+    int fromIndex,
+    int toIndex
+    )
+  {throw new NotImplementedException();}
+
+  // <Collection>
+  public boolean add(
+    Annotation value
+    )
+  {
+    // Assign the annotation to the page!
+    value.getBaseDataObject().put(PdfName.P,page.getBaseObject());
+
+    return getBaseDataObject().add(value.getBaseObject());
+  }
+
+  public boolean addAll(
+    Collection<? extends Annotation> values
+    )
+  {
+    for(Annotation value : values)
+    {add(value);}
+
+    return true;
+  }
+
+  public void clear(
+    )
+  {getBaseDataObject().clear();}
+
+  public boolean contains(
+    Object value
+    )
+  {
+    if(!(value instanceof Annotation))
+      return false;
+
+    return getBaseDataObject().contains(((Annotation)value).getBaseObject());
+  }
+
+  public boolean containsAll(
+    Collection<?> values
+    )
+  {throw new NotImplementedException();}
+
+  public boolean equals(
+    Object object
+    )
+  {throw new NotImplementedException();}
+
+  public int hashCode(
+    )
+  {throw new NotImplementedException();}
+
+  public boolean isEmpty(
+    )
+  {return getBaseDataObject().isEmpty();}
+
+  public boolean remove(
+    Object value
+    )
+  {return getBaseDataObject().remove(((Annotation)value).getBaseObject());}
+
+  public boolean removeAll(
+    Collection<?> values
+    )
+  {throw new NotImplementedException();}
+
+  public boolean retainAll(
+    Collection<?> values
+    )
+  {throw new NotImplementedException();}
+
+  public int size(
+    )
+  {return getBaseDataObject().size();}
+
+  public Object[] toArray(
+    )
+  {return toArray(new Annotation[0]);}
+
+  @SuppressWarnings("unchecked")
+  public <T> T[] toArray(
+    T[] values
+    )
+  {
+    PdfArray annotationObjects = getBaseDataObject();
+    if(values.length < annotationObjects.size())
+    {values = (T[])new Object[annotationObjects.size()];}
+
+    PdfIndirectObject container = getContainer();
+    for(
+      int index = 0,
+        length = annotationObjects.size();
+      index < length;
+      index++
+      )
+    {values[index] = (T)Annotation.wrap(annotationObjects.get(index),container);}
+    return values;
+  }
+
+  // <Iterable>
+  public Iterator<Annotation> iterator(
+    )
+  {
+    return new Iterator<Annotation>()
+    {
+      // <class>
+      // <dynamic>
+      // <fields>
+      /**
+        Index of the next item.
+      */
+      private int index = 0;
+      /**
+        Collection size.
+      */
+      private int size = size();
+      // </fields>
+
+      // <interface>
+      // <public>
+      // <Iterator>
+      public boolean hasNext(
+        )
+      {return (index < size);}
+
+      public Annotation next(
+        )
+      {
+        if(!hasNext())
+          throw new NoSuchElementException();
+
+        return get(index++);
+      }
+
+      public void remove(
+        )
+      {throw new UnsupportedOperationException();}
+      // </Iterator>
+      // </public>
+      // </interface>
+      // </dynamic>
+      // </class>
+    };
+  }
+  // </Iterable>
+  // </Collection>
+  // </List>
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/PageFormat.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/PageFormat.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/PageFormat.java	(revision 23703)
@@ -0,0 +1,204 @@
+/*
+  Copyright 2007 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents;
+
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.awt.Dimension;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+  Page format.
+  <p>This utility provides an easy access to the dimension of common page formats.</p>
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.4
+  @since 0.0.3
+  @see Document#setPageSize(Dimension2D)
+  @see Page#setSize(Dimension2D)
+*/
+public class PageFormat
+{
+  // <class>
+  // <classes>
+  /**
+    Paper size.
+    <h3>Remarks</h3>
+    <p>References:</p>
+    <ul>
+      <li>{ 'A' digit+ }: [ISO 216] "A" series: Paper and boards, trimmed sizes.</li>
+      <li>{ 'B' digit+ }: [ISO 216] "B" series: Posters, wall charts and similar items.</li>
+      <li>{ 'C' digit+ }: [ISO 269] "C" series: Envelopes or folders suitable for A-size
+      stationery.</li>
+      <li>{ 'Ansi' letter }: [ANSI/ASME Y14.1] ANSI series: US engineering drawing series.</li>
+      <li>{ 'Arch' letter }: Architectural series.</li>
+      <li>{ "Letter", "Legal", "Executive", "Statement", "Tabloid" }: Traditional north-american
+      sizes.</li>
+    </ul>
+  */
+  public enum SizeEnum
+  {
+    A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,
+    B0,B1,B2,B3,B4,B5,B6,B7,B8,B9,B10,
+    C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,
+    Letter,
+    Legal,
+    Executive,
+    Statement,
+    Tabloid,
+    ArchA, ArchB, ArchC, ArchD, ArchE,
+    AnsiA, AnsiB, AnsiC, AnsiD, AnsiE
+  };
+
+  /**
+    Page orientation.
+  */
+  public enum OrientationEnum
+  {
+    Portrait,
+    Landscape
+  }
+  // </classes>
+
+  // <static>
+  // <fields>
+  private static final String IsoSeriesSize_A = "A";
+  private static final String IsoSeriesSize_B = "B";
+  private static final String IsoSeriesSize_C = "C";
+
+  private static final Pattern IsoSeriesSizePattern = Pattern.compile(
+    "(["
+      + IsoSeriesSize_A
+      + IsoSeriesSize_B
+      + IsoSeriesSize_C
+      + "])([\\d]+)"
+    );
+  // </fields>
+
+  // <interface>
+  // <public>
+  /**
+    Gets the default page size.
+    <h3>Remarks</h3>
+    <p>The returned dimension corresponds to the widely-established ISO A4 standard paper format,
+    portrait orientation.</p>
+  */
+  public static Dimension getSize(
+    )
+  {return getSize(SizeEnum.A4);}
+
+  /**
+    Gets the page size of the given format, portrait orientation.
+    @param size Page size.
+  */
+  public static Dimension getSize(
+    SizeEnum size
+    )
+  {return getSize(size,OrientationEnum.Portrait);}
+
+  /**
+    Gets the page size of the given format and orientation.
+    @param size Page size.
+    @param orientation Page orientation.
+  */
+  public static Dimension getSize(
+    SizeEnum size,
+    OrientationEnum orientation
+    )
+  {
+    int width, height = 0;
+
+    // Size.
+    {
+      String sizeName = size.name();
+      Matcher matcher = IsoSeriesSizePattern.matcher(sizeName);
+      // Is it an ISO standard size?
+      if(matcher.matches())
+      {
+        int baseWidth, baseHeight = 0;
+        String isoSeriesSize = matcher.group(1);
+        if(isoSeriesSize.equals(IsoSeriesSize_A))
+        {baseWidth = 2384; baseHeight = 3370;}
+        else if(isoSeriesSize.equals(IsoSeriesSize_B))
+        {baseWidth = 2834; baseHeight = 4008;}
+        else if(isoSeriesSize.equals(IsoSeriesSize_C))
+        {baseWidth = 2599; baseHeight = 3676;}
+        else
+        {throw new NotImplementedException("Paper format " + size + " not supported yet.");}
+
+        int isoSeriesSizeIndex = Integer.parseInt(matcher.group(2));
+        double isoSeriesSizeFactor = 1 / Math.pow(2,isoSeriesSizeIndex/2d);
+
+        width = (int)Math.floor(baseWidth * isoSeriesSizeFactor);
+        height = (int)Math.floor(baseHeight * isoSeriesSizeFactor);
+      }
+      else // Non-ISO size.
+      {
+        switch(size)
+        {
+          case ArchA: width = 648; height = 864; break;
+          case ArchB: width = 864; height = 1296; break;
+          case ArchC: width = 1296; height = 1728; break;
+          case ArchD: width = 1728; height = 2592; break;
+          case ArchE: width = 2592; height = 3456; break;
+          case AnsiA: case Letter: width = 612; height = 792; break;
+          case AnsiB: case Tabloid: width = 792; height = 1224; break;
+          case AnsiC: width = 1224; height = 1584; break;
+          case AnsiD: width = 1584; height = 2448; break;
+          case AnsiE: width = 2448; height = 3168; break;
+          case Legal: width = 612; height = 1008; break;
+          case Executive: width = 522; height = 756; break;
+          case Statement: width = 396; height = 612; break;
+          default: throw new NotImplementedException("Paper format " + size + " not supported yet.");
+        }
+      }
+    }
+
+    // Orientation.
+    switch(orientation)
+    {
+      case Portrait:
+        return new Dimension(width,height);
+      case Landscape:
+        return new Dimension(height,width);
+      default:
+        throw new NotImplementedException("Orientation " + orientation + " not supported yet.");
+    }
+  }
+  // </public>
+  // </interface>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  private PageFormat(
+    )
+  {}
+  // </constructors>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/PageLayoutEnum.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/PageLayoutEnum.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/PageLayoutEnum.java	(revision 23703)
@@ -0,0 +1,36 @@
+/*
+  Copyright 2006 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents;
+
+/**
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+*/
+public enum PageLayoutEnum
+{
+  SinglePage,
+  OneColumn,
+  TwoColumns
+};
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/PageModeEnum.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/PageModeEnum.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/PageModeEnum.java	(revision 23703)
@@ -0,0 +1,37 @@
+/*
+  Copyright 2006 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents;
+
+/**
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+*/
+public enum PageModeEnum
+{
+  Simple,
+  Outlines,
+  Thumbnails,
+  FullScreen
+};
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/Pages.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/Pages.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/Pages.java	(revision 23703)
@@ -0,0 +1,579 @@
+/*
+  Copyright 2006-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents;
+
+import it.stefanochizzolini.clown.files.File;
+import it.stefanochizzolini.clown.objects.IPdfNumber;
+import it.stefanochizzolini.clown.objects.PdfArray;
+import it.stefanochizzolini.clown.objects.PdfDictionary;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfInteger;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfObjectWrapper;
+import it.stefanochizzolini.clown.objects.PdfReference;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.NoSuchElementException;
+import java.util.Stack;
+
+/**
+  Document pages collection.
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+*/
+public class Pages
+  extends PdfObjectWrapper<PdfDictionary>
+  implements List<Page>
+{
+  /*
+    TODO:IMPL A B-tree algorithm should be implemented to optimize the inner layout
+    of the page tree (better insertion/deletion performance). In this case, it would
+    be necessary to keep track of the modified tree nodes for incremental update.
+  */
+  // <class>
+  // <dynamic>
+  // <constructors>
+  Pages(
+    Document context
+    )
+  {
+    super(
+      context.getFile(),
+      new PdfDictionary(
+        new PdfName[]
+        {
+          PdfName.Type,
+          PdfName.Kids,
+          PdfName.Count
+        },
+        new PdfDirectObject[]
+        {
+          PdfName.Pages,
+          new PdfArray(),
+          new PdfInteger(0)
+        }
+        )
+      );
+  }
+
+  Pages(
+    PdfDirectObject baseObject
+    )
+  {
+    super(
+      baseObject,
+      null // NO container (page tree root node MUST be an indirect object [PDF:1.6:3.6.1]).
+      );
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public Pages clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  // <List>
+  public void add(
+    int index,
+    Page page
+    )
+  {commonAddAll(index,Arrays.asList(page));}
+
+  public boolean addAll(
+    int index,
+    Collection<? extends Page> pages
+    )
+  {return commonAddAll(index,pages);}
+
+  public Page get(
+    int index
+    )
+  {
+    /*
+      NOTE: As stated in [PDF:1.6:3.6.2], to retrieve pages is a matter of diving
+      inside a B-tree. To keep it as efficient as possible, this implementation
+      does NOT adopt recursion to deepen its search, opting for an iterative strategy
+      instead.
+    */
+    int pageOffset = 0;
+    PdfDictionary parent = getBaseDataObject();
+    PdfArray kids = (PdfArray)File.resolve(parent.get(PdfName.Kids));
+    for(
+      int i = 0;
+      i < kids.size();
+      i++
+      )
+    {
+      PdfReference kidReference = (PdfReference)kids.get(i);
+      PdfDictionary kid = (PdfDictionary)File.resolve(kidReference);
+      // Is current kid a page object?
+      if(kid.get(PdfName.Type).equals(PdfName.Page)) // Page object.
+      {
+        // Did we reach the searched position?
+        if(pageOffset == index) // Vertical scan (we finished).
+        {
+          // We got it!
+          return new Page(kidReference);
+        }
+        else // Horizontal scan (go past).
+        {
+          // Cumulate current page object count!
+          pageOffset++;
+        }
+      }
+      else // Page tree node.
+      {
+        // Does the current subtree contain the searched page?
+        if(((PdfInteger)kid.get(PdfName.Count)).getRawValue() + pageOffset > index) // Vertical scan (deepen the search).
+        {
+          // Go down one level!
+          parent = kid;
+          kids = (PdfArray)File.resolve(parent.get(PdfName.Kids));
+          i = -1;
+        }
+        else // Horizontal scan (go past).
+        {
+          // Cumulate current subtree count!
+          pageOffset += ((PdfInteger)kid.get(PdfName.Count)).getRawValue();
+        }
+      }
+    }
+
+    return null;
+  }
+
+  public int indexOf(
+    Object page
+    )
+  {return ((Page)page).getIndex();}
+
+  public int lastIndexOf(
+    Object page
+    )
+  {
+    /*
+      NOTE: Each page object should NOT appear more than once inside the same document.
+    */
+    return indexOf(page);
+  }
+
+  public ListIterator<Page> listIterator(
+    )
+  {throw new NotImplementedException();}
+
+  public ListIterator<Page> listIterator(
+    int index
+    )
+  {throw new NotImplementedException();}
+
+  public Page remove(
+    int index
+    )
+  {
+    Page page = get(index);
+    remove(page);
+
+    return page;
+  }
+
+  public Page set(
+    int index,
+    Page page
+    )
+  {
+    Page old = remove(index);
+    add(index,page);
+
+    return old;
+  }
+
+  public List<Page> subList(
+    int fromIndex,
+    int toIndex
+    )
+  {
+  /*
+  TODO:IMPL this implementation is incoherent with the subList contract --> move to another location!
+  */
+    ArrayList<Page> pages = new ArrayList<Page>(toIndex - fromIndex);
+    int i = fromIndex;
+    while(i < toIndex)
+    {pages.add(get(i++));}
+
+    return pages;
+  }
+
+  // <Collection>
+  public boolean add(
+    Page page
+    )
+  {return commonAddAll(-1,Arrays.asList(page));}
+
+  public boolean addAll(
+    Collection<? extends Page> pages
+    )
+  {return commonAddAll(-1,pages);}
+
+  public void clear(
+    )
+  {throw new NotImplementedException();}
+
+  public boolean contains(
+    Object page
+    )
+  {throw new NotImplementedException();}
+
+  public boolean containsAll(
+    Collection<?> pages
+    )
+  {throw new NotImplementedException();}
+
+  public boolean equals(
+    Object object
+    )
+  {throw new NotImplementedException();}
+
+  public int hashCode(
+    )
+  {throw new NotImplementedException();}
+
+  public boolean isEmpty(
+    )
+  {throw new NotImplementedException();}
+
+  public boolean remove(
+    Object page
+    )
+  {
+    Page pageObj = (Page)page;
+    PdfDictionary pageData = pageObj.getBaseDataObject();
+    // Get the parent tree node!
+    PdfDirectObject parent = pageData.get(PdfName.Parent);
+    PdfDictionary parentData = (PdfDictionary)File.resolve(parent);
+    // Get the parent's page collection!
+    PdfDirectObject kids = parentData.get(PdfName.Kids);
+    PdfArray kidsData = (PdfArray)File.resolve(kids);
+    // Remove the page!
+    kidsData.remove(pageObj.getBaseObject());
+    boolean updateParent = !File.update(kids); // Try to update the page collection.
+    // Unbind the page from its parent!
+    pageData.put(PdfName.Parent,null);
+    pageObj.update();
+    // Decrementing the pages counters...
+    do
+    {
+      // Get the page collection counter!
+      PdfDirectObject count = parentData.get(PdfName.Count);
+      IPdfNumber countData = (IPdfNumber)File.resolve(count);
+      // Decrement the counter at the current level!
+      countData.translateNumberValue(-1);
+      updateParent |= !File.update(count); // Try to update the counter.
+      // Is the parent tree node to be updated?
+      /*
+        NOTE: It avoids to update the parent tree node if its modified fields are all
+        indirect objects which perform independent updates.
+      */
+      if(updateParent)
+      {
+        File.update(parent);
+        updateParent = false; // Reset.
+      }
+
+      // Iterate upward!
+      parent = parentData.get(PdfName.Parent);
+      parentData = (PdfDictionary)File.resolve(parent);
+    } while(parent != null);
+
+    return true;
+  }
+
+  public boolean removeAll(
+    Collection<?> pages
+    )
+  {
+    /*
+      NOTE: The interface contract doesn't prescribe any relation among the removing-collection's
+      items, so we cannot adopt the optimized approach of the add*(...) methods family,
+      where adding-collection's items are explicitly ordered.
+    */
+    boolean changed = false;
+    for(Object page : pages)
+    {changed |= remove(page);}
+
+    return changed;
+  }
+
+  public boolean retainAll(
+    Collection<?> pages
+    )
+  {throw new NotImplementedException();}
+
+  public int size(
+    )
+  {return ((PdfInteger)getBaseDataObject().get(PdfName.Count)).getRawValue();}
+
+  public Page[] toArray(
+    )
+  {throw new NotImplementedException();}
+
+  public <T> T[] toArray(
+    T[] pages
+    )
+  {throw new NotImplementedException();}
+
+  // <Iterable>
+  public Iterator<Page> iterator(
+    )
+  {
+    return new Iterator<Page>()
+    {
+      // <class>
+      // <dynamic>
+      // <fields>
+      /**
+        Index of the next item.
+      */
+      private int index = 0;
+      /**
+        Collection size.
+      */
+      private int size = size();
+
+      /**
+        Current level index.
+      */
+      private int levelIndex = 0;
+      /**
+        Stacked level indexes.
+      */
+      private Stack<Integer> levelIndexes = new Stack<Integer>();
+      /**
+        Current parent tree node.
+      */
+      private PdfDictionary parent = getBaseDataObject();
+      /**
+        Current child tree nodes.
+      */
+      private PdfArray kids = (PdfArray)File.resolve(parent.get(PdfName.Kids));
+      // </fields>
+
+      // <interface>
+      // <public>
+      // <Iterator>
+      public boolean hasNext(
+        )
+      {return (index < size);}
+
+      public Page next(
+        )
+      {
+        if(!hasNext())
+          throw new NoSuchElementException();
+
+        return getNext();
+      }
+
+      public void remove(
+        )
+      {throw new UnsupportedOperationException();}
+      // </Iterator>
+      // </public>
+
+      // <private>
+      private Page getNext(
+        )
+      {
+        /*
+          NOTE: As stated in [PDF:1.6:3.6.2], to retrieve pages is a matter of diving
+          inside a B-tree.
+          This is a special adaptation of the get() algorithm necessary to keep
+          a low overhead throughout the page tree scan (using the get() method
+          would have implied a nonlinear computational cost).
+        */
+        /*
+          NOTE: Algorithm:
+          1. [Vertical, down] We have to go downward the page tree till we reach
+          a page (leaf node).
+          2. [Horizontal] Then we iterate across the page collection it belongs to,
+          repeating step 1 whenever we find a subtree.
+          3. [Vertical, up] When leaf-nodes scan is complete, we go upward solving
+          parent nodes, repeating step 2.
+        */
+        while(true)
+        {
+          // Did we complete current page-tree-branch level?
+          if(kids.size() == levelIndex) // Page subtree complete.
+          {
+            // 3. Go upward one level.
+            // Restore node index at the current level!
+            levelIndex = levelIndexes.pop() + 1; // Next node (partially scanned level).
+            // Move upward!
+            parent = (PdfDictionary)File.resolve(parent.get(PdfName.Parent));
+            kids = (PdfArray)File.resolve(parent.get(PdfName.Kids));
+          }
+          else // Page subtree incomplete.
+          {
+            PdfReference kidReference = (PdfReference)kids.get(levelIndex);
+            PdfDictionary kid = (PdfDictionary)File.resolve(kidReference);
+            // Is current kid a page object?
+            if(kid.get(PdfName.Type).equals(PdfName.Page)) // Page object.
+            {
+              // 2. Page found.
+              index++; // Absolute page index.
+              levelIndex++; // Current level node index.
+
+              return new Page(kidReference);
+            }
+            else // Page tree node.
+            {
+              // 1. Go downward one level.
+              // Save node index at the current level!
+              levelIndexes.push(levelIndex);
+              // Move downward!
+              parent = kid;
+              kids = (PdfArray)File.resolve(parent.get(PdfName.Kids));
+              levelIndex = 0; // First node (new level).
+            }
+          }
+        }
+      }
+      // </private>
+      // </interface>
+      // </dynamic>
+      // </class>
+    };
+  }
+  // </Iterable>
+  // </Collection>
+  // </List>
+  // </public>
+
+  // <private>
+  /**
+    Add a collection of pages at the specified position.
+    @param index Addition position. To append, use value -1.
+    @param pages Collection of pages to add.
+  */
+  private boolean commonAddAll(
+    int index,
+    Collection<? extends Page> pages
+    )
+  {
+    PdfDirectObject parent;
+    PdfDictionary parentData;
+    PdfDirectObject kids;
+    PdfArray kidsData;
+    int offset;
+    // Append operation?
+    if(index == -1) // Append operation.
+    {
+      // Get the parent tree node!
+      parent = getBaseObject();
+      parentData = getBaseDataObject();
+      // Get the parent's page collection!
+      kids = parentData.get(PdfName.Kids);
+      kidsData = (PdfArray)File.resolve(kids);
+      offset = 0; // Not used.
+    }
+    else // Insert operation.
+    {
+      // Get the page currently at the specified position!
+      Page pivotPage = get(index);
+      // Get the parent tree node!
+      parent = pivotPage.getBaseDataObject().get(PdfName.Parent);
+      parentData = (PdfDictionary)File.resolve(parent);
+      // Get the parent's page collection!
+      kids = parentData.get(PdfName.Kids);
+      kidsData = (PdfArray)File.resolve(kids);
+      // Get the insertion's relative position within the parent's page collection!
+      offset = kidsData.indexOf(pivotPage.getBaseObject());
+    }
+
+    // Adding the pages...
+    for(Page page : pages)
+    {
+      // Append?
+      if(index == -1) // Append.
+      {
+        // Append the page to the collection!
+        kidsData.add(page.getBaseObject());
+      }
+      else // Insert.
+      {
+        // Insert the page into the collection!
+        kidsData.add(
+          offset++,
+          page.getBaseObject()
+          );
+      }
+      // Bind the page to the collection!
+      page.getBaseDataObject().put(PdfName.Parent,parent);
+      page.update();
+    }
+    boolean updateParent = !File.update(kids); // Try to update the page collection.
+
+    // Incrementing the pages counters...
+    do
+    {
+      // Get the page collection counter!
+      PdfDirectObject count = parentData.get(PdfName.Count);
+      IPdfNumber countData = (IPdfNumber)File.resolve(count);
+      // Increment the counter at the current level!
+      countData.translateNumberValue(pages.size());
+      updateParent |= !File.update(count); // Try to update the page counter.
+      // Is the parent tree node to be updated?
+      /*
+        NOTE: It avoids to update the parent tree node if its modified fields are all
+        indirect objects which perform independent updates.
+      */
+      if(updateParent)
+      {
+        File.update(parent);
+        updateParent = false; // Reset.
+      }
+
+      // Iterate upward!
+      parent = parentData.get(PdfName.Parent);
+      parentData = (PdfDictionary)File.resolve(parent);
+    } while(parent != null);
+
+    return true;
+  }
+  // </private>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/ColorSpaceResources.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/ColorSpaceResources.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/ColorSpaceResources.java	(revision 23703)
@@ -0,0 +1,191 @@
+/*
+  Copyright 2006-2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents;
+
+import it.stefanochizzolini.clown.documents.contents.colorSpaces.ColorSpace;
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.objects.PdfDictionary;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfObjectWrapper;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+
+/**
+  Color space resources collection [PDF:1.6:3.7.2].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.7
+*/
+public class ColorSpaceResources
+  extends PdfObjectWrapper<PdfDictionary>
+  implements Map<PdfName,ColorSpace>
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  public ColorSpaceResources(
+    Document context
+    )
+  {
+    super(
+      context.getFile(),
+      new PdfDictionary()
+      );
+  }
+
+  ColorSpaceResources(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {
+    super(
+      baseObject,
+      container
+      );
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public ColorSpaceResources clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    Gets the key associated to a given value.
+  */
+  public PdfName getKey(
+    ColorSpace value
+    )
+  {return getBaseDataObject().getKey(value.getBaseObject());}
+
+  // <Map>
+  public void clear(
+    )
+  {getBaseDataObject().clear();}
+
+  public boolean containsKey(
+    Object key
+    )
+  {return getBaseDataObject().containsKey(key);}
+
+  public boolean containsValue(
+    Object value
+    )
+  {return getBaseDataObject().containsValue(((ColorSpace)value).getBaseObject());}
+
+  public Set<Map.Entry<PdfName,ColorSpace>> entrySet(
+    )
+  {throw new NotImplementedException();}
+
+  public boolean equals(
+    PdfDirectObject object
+    )
+  {throw new NotImplementedException();}
+
+  public ColorSpace get(
+    Object key
+    )
+  {
+    return ColorSpace.wrap(
+      getBaseDataObject().get(key),
+      getContainer()
+      );
+  }
+
+  public int hashCode(
+    )
+  {throw new NotImplementedException();}
+
+  public boolean isEmpty(
+    )
+  {return getBaseDataObject().isEmpty();}
+
+  public Set<PdfName> keySet(
+    )
+  {return getBaseDataObject().keySet();}
+
+  public ColorSpace put(
+    PdfName key,
+    ColorSpace value
+    )
+  {
+    return ColorSpace.wrap(
+      getBaseDataObject().put(key,value.getBaseObject()),
+      getContainer()
+      );
+  }
+
+  public void putAll(
+    Map<? extends PdfName,? extends ColorSpace> entries
+    )
+  {throw new NotImplementedException();}
+
+  public ColorSpace remove(
+    Object key
+    )
+  {
+    return ColorSpace.wrap(
+      getBaseDataObject().remove(key),
+      getContainer()
+      );
+  }
+
+  public int size(
+    )
+  {return getBaseDataObject().size();}
+
+  public Collection<ColorSpace> values(
+    )
+  {
+    // Get the raw objects!
+    Collection<PdfDirectObject> objects = getBaseDataObject().values();
+    // Get room for the corresponding Font collection!
+    Collection<ColorSpace> values = new ArrayList<ColorSpace>(objects.size());
+    // Populating the collection...
+    for(PdfDirectObject object : objects)
+    {
+      values.add(
+        ColorSpace.wrap(object,getContainer())
+        );
+    }
+
+    return values;
+  }
+  // </Map>
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/ContentScanner.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/ContentScanner.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/ContentScanner.java	(revision 23703)
@@ -0,0 +1,948 @@
+/*
+  Copyright 2007-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents;
+
+import it.stefanochizzolini.clown.documents.contents.colorSpaces.Color;
+import it.stefanochizzolini.clown.documents.contents.colorSpaces.ColorSpace;
+import it.stefanochizzolini.clown.documents.contents.colorSpaces.DeviceGrayColor;
+import it.stefanochizzolini.clown.documents.contents.colorSpaces.DeviceGrayColorSpace;
+import it.stefanochizzolini.clown.documents.contents.fonts.Font;
+import it.stefanochizzolini.clown.documents.contents.objects.CompositeObject;
+import it.stefanochizzolini.clown.documents.contents.objects.ContainerObject;
+import it.stefanochizzolini.clown.documents.contents.objects.ContentObject;
+import it.stefanochizzolini.clown.documents.contents.objects.InlineImage;
+import it.stefanochizzolini.clown.documents.contents.objects.ShowText;
+import it.stefanochizzolini.clown.documents.contents.objects.Text;
+import it.stefanochizzolini.clown.documents.contents.objects.XObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+/**
+  Content objects scanner.
+  <h3>Remarks</h3>
+  <p>It wraps the content objects collection ({@link Contents}) to scan its graphics state
+  through a forward cursor.</p>
+  <p>Scanning is performed at an arbitrary depth, according to the content objects nesting:
+  each depth level corresponds to a scan level so that at any time it's possible
+  to seamlessly navigate across the levels (see {@link #getParentLevel() },
+  {@link #getChildLevel() })</p>
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.4
+  @version 0.0.8
+*/
+public final class ContentScanner
+{
+  // <class>
+  // <classes>
+  /**
+    Graphics state [PDF:1.6:4.3].
+  */
+  public static final class GraphicsState
+    implements Cloneable
+  {
+    // <class>
+    // <static>
+    // <interface>
+    // <public>
+    /**
+      Concatenates the given coordinate matrices.
+    */
+    public static double[] concat(
+      double[] matrix1,
+      double[] matrix2
+      )
+    {
+      double[] result = new double[6];
+      result[0] = matrix1[0]*matrix2[0] + matrix1[1]*matrix2[2]; // a.
+      result[1] = matrix1[0]*matrix2[1] + matrix1[1]*matrix2[3]; // b.
+      result[2] = matrix1[2]*matrix2[0] + matrix1[3]*matrix2[2]; // c.
+      result[3] = matrix1[2]*matrix2[1] + matrix1[3]*matrix2[3]; // d.
+      result[4] = matrix1[4]*matrix2[0] + matrix1[5]*matrix2[2] + 1*matrix2[4]; // e.
+      result[5] = matrix1[4]*matrix2[1] + matrix1[5]*matrix2[3] + 1*matrix2[5]; // f.
+
+      return result;
+    }
+    // </public>
+    // </interface>
+    // </static>
+
+    // <dynamic>
+    // <fields>
+    /**
+      Current character spacing [PDF:1.6:5.2.1].
+    */
+    public double charSpace;
+    /**
+      Current transformation matrix.
+    */
+    public double[] ctm;
+    /**
+      Current color for nonstroking operations [PDF:1.6:4.5.1].
+    */
+    public Color fillColor;
+    /**
+      Current color space for nonstroking operations [PDF:1.6:4.5.1].
+    */
+    public ColorSpace fillColorSpace;
+    /**
+      Current font [PDF:1.6:5.2].
+    */
+    public Font font;
+    /**
+      Current font size [PDF:1.6:5.2].
+    */
+    public double fontSize;
+    /**
+      Current leading [PDF:1.6:5.2.4].
+    */
+    public double lead;
+    /**
+      Current line cap style [PDF:1.6:4.3.2].
+    */
+    public LineCapEnum lineCap;
+    /**
+      Current line dash pattern [PDF:1.6:4.3.2].
+    */
+    public LineDash lineDash;
+    /**
+      Current line join style [PDF:1.6:4.3.2].
+    */
+    public LineJoinEnum lineJoin;
+    /**
+      Current line width [PDF:1.6:4.3.2].
+    */
+    public double lineWidth;
+    /**
+      Current miter limit [PDF:1.6:4.3.2].
+    */
+    public double miterLimit;
+    /**
+      Current text rendering mode [PDF:1.6:5.2.5].
+    */
+    public TextRenderModeEnum renderMode;
+    /**
+      Current text rise [PDF:1.6:5.2.6].
+    */
+    public double rise;
+    /**
+      Current horizontal scaling [PDF:1.6:5.2.3].
+    */
+    public double scale;
+    /**
+      Current color for stroking operations [PDF:1.6:4.5.1].
+    */
+    public Color strokeColor;
+    /**
+      Current color space for stroking operations [PDF:1.6:4.5.1].
+    */
+    public ColorSpace strokeColorSpace;
+    /**
+      Text line matrix [PDF:1.6:5.3].
+    */
+    public double[] tlm;
+    /**
+      Text matrix [PDF:1.6:5.3].
+    */
+    public double[] tm;
+    /**
+      Current word spacing [PDF:1.6:5.2.2].
+    */
+    public double wordSpace;
+
+    private ContentScanner scanner;
+    // </fields>
+
+    // <constructors>
+    private GraphicsState(
+      ContentScanner scanner
+      )
+    {
+      this.scanner = scanner;
+      initialize();
+    }
+    // </constructors>
+
+    // <interface>
+    // <public>
+    /**
+      Gets a deep copy of the graphics state object.
+    */
+    @Override
+    public GraphicsState clone(
+      )
+    {
+      GraphicsState clone;
+
+      // Shallow copy.
+      try
+      {clone = (GraphicsState)super.clone();}
+      catch(CloneNotSupportedException e)
+      {throw new RuntimeException(e); /* NOTE: It should never happen. */}
+
+      // Deep copy.
+      /* NOTE: Mutable objects are to be cloned. */
+
+      return clone;
+    }
+
+    public void copyTo(
+      GraphicsState state
+      )
+    {//TODO:cache fields!!!
+      ContentScanner stateScanner = state.scanner;
+      for(Field field : GraphicsState.class.getDeclaredFields())
+      {
+        try
+        {field.set(state,field.get(this));}
+        catch (IllegalAccessException e)
+        {throw new RuntimeException(e);}
+      }
+      state.scanner = stateScanner;
+//TODO:temporary hack (define TextState for textual parameters!)...
+      if(!(state.scanner.getParent() instanceof Text))
+      {
+        state.tlm = new double[]{1,0,0,1,0,0};
+        state.tm = new double[]{1,0,0,1,0,0};
+      }
+    }
+
+    /**
+      Gets the scanner associated to this state.
+    */
+    public ContentScanner getScanner(
+      )
+    {return scanner;}
+
+    /**
+      Resolves the given text-space point to its equivalent device-space one [PDF:1.6:5.3.3].
+    */
+    public Point2D textToDeviceSpace(
+      Point2D point
+      )
+    {
+      /*
+        NOTE: The text rendering matrix (trm) is obtained from the concatenation
+        of the text parameters (fontSize, scale, rise) matrix, the text matrix (tm) and the CTM.
+      */
+      double[] trm = concat(tm,ctm);
+
+      return new Point2D.Double(
+        trm[0] * point.getX() + trm[2] * point.getY() + trm[4],
+        scanner.getContentContext().getBox().getHeight() - (trm[1] * point.getX() + trm[3] * point.getY() + trm[5])
+        );
+    }
+
+    /**
+      Resolves the given user-space point to its equivalent device-space one [PDF:1.6:4.2.3].
+    */
+    public Point2D userToDeviceSpace(
+      Point2D point
+      )
+    {
+      return new Point2D.Double(
+        ctm[0] * point.getX() + ctm[2] * point.getY() + ctm[4],
+        ctm[1] * point.getX() + ctm[3] * point.getY() + ctm[5]
+        );
+    }
+    // </public>
+
+    // <private>
+    private GraphicsState clone(
+      ContentScanner scanner
+      )
+    {
+      GraphicsState state = clone();
+      state.scanner = scanner;
+
+      return state;
+    }
+
+    private void initialize(
+      )
+    {
+      charSpace = 0;
+      ctm = new double[]{1,0,0,1,0,0};
+      fillColor = DeviceGrayColor.Default;
+      fillColorSpace = DeviceGrayColorSpace.Default;
+      font = null;
+      fontSize = 0;
+      lead = 0;
+      lineCap = LineCapEnum.Butt;
+      lineDash = new LineDash();
+      lineJoin = LineJoinEnum.Miter;
+      lineWidth = 1;
+      miterLimit = 10;
+      renderMode = TextRenderModeEnum.Fill;
+      rise = 0;
+      scale = 100;
+      strokeColor = DeviceGrayColor.Default;
+      strokeColorSpace = DeviceGrayColorSpace.Default;
+      tlm = new double[]{1,0,0,1,0,0};
+      tm = new double[]{1,0,0,1,0,0};
+      wordSpace = 0;
+    }
+    // </private>
+    // </interface>
+    // </dynamic>
+    // </class>
+  }
+
+  /**
+    Object information.
+    <h3>Remarks</h3>
+    <p>This class provides derivative (higher-level) information
+    about the currently scanned object.</p>
+  */
+  public static abstract class GraphicsObjectWrapper<TDataObject extends ContentObject>
+  {
+    // <static>
+    @SuppressWarnings("unchecked")
+    private static GraphicsObjectWrapper get(
+      ContentScanner scanner
+      )
+    {
+      ContentObject object = scanner.getCurrent();
+      if(object instanceof ShowText)
+        return new TextStringWrapper(scanner);
+      else if(object instanceof Text)
+        return new TextWrapper(scanner);
+      else if(object instanceof XObject)
+        return new XObjectWrapper(scanner);
+      else if(object instanceof InlineImage)
+        return new InlineImageWrapper(scanner);
+      else
+        return null;
+    }
+    // </static>
+
+    // <dynamic>
+    // <fields>
+    protected Rectangle2D box;
+
+    private TDataObject baseDataObject;
+    // </fields>
+
+    // <constructors>
+    protected GraphicsObjectWrapper(
+      TDataObject baseDataObject
+      )
+    {this.baseDataObject = baseDataObject;}
+    // </constructors>
+
+    // <interface>
+    // <public>
+    /**
+      Gets the underlying data object.
+    */
+    public TDataObject getBaseDataObject(
+      )
+    {return baseDataObject;}
+
+    /**
+      Gets the object's bounding box.
+    */
+    public Rectangle2D getBox(
+      )
+    {return box;}
+    // </public>
+    // </interface>
+    // </dynamic>
+  }
+
+  /**
+    Inline image information.
+  */
+  public static final class InlineImageWrapper
+    extends GraphicsObjectWrapper<InlineImage>
+  {
+    private InlineImageWrapper(
+      ContentScanner scanner
+      )
+    {
+      super((InlineImage)scanner.getCurrent());
+
+      double[] ctm = scanner.getState().ctm;
+      this.box = new Rectangle2D.Double(
+        ctm[4],
+        scanner.getContentContext().getBox().getHeight() - ctm[5],
+        ctm[0],
+        Math.abs(ctm[3])
+        );
+    }
+
+    /**
+      Gets the inline image.
+    */
+    public InlineImage getInlineImage(
+      )
+    {return getBaseDataObject();}
+  }
+
+  /**
+    Text information.
+  */
+  public static final class TextWrapper
+    extends GraphicsObjectWrapper<Text>
+  {
+    private List<TextStringWrapper> textStrings;
+
+    private TextWrapper(
+      ContentScanner scanner
+      )
+    {
+      super((Text)scanner.getCurrent());
+
+      textStrings = new ArrayList<TextStringWrapper>();
+      extract(scanner.getChildLevel());
+    }
+    
+    @Override
+    public Rectangle2D getBox(
+      )
+    {
+      if(box == null)
+      {
+        for(TextStringWrapper textString : textStrings)
+        {
+          if(box == null)
+          {box = (Rectangle2D)textString.getBox().clone();}
+          else
+          {box.add(textString.getBox());}
+        }
+      }
+      return box;
+    }
+
+    /**
+      Gets the text strings.
+    */
+    public List<TextStringWrapper> getTextStrings(
+      )
+    {return textStrings;}
+
+    private void extract(
+      ContentScanner level
+      )
+    {
+      if(level == null)
+        return;
+
+      while(level.moveNext())
+      {
+        ContentObject content = level.getCurrent();
+        if(content instanceof ShowText)
+        {textStrings.add((TextStringWrapper)level.getCurrentWrapper());}
+        else if(content instanceof ContainerObject)
+        {extract(level.getChildLevel());}
+      }
+    }
+  }
+
+  /**
+    Text string information.
+  */
+  public static final class TextStringWrapper
+    extends GraphicsObjectWrapper<ShowText>
+    implements ITextString
+  {
+    private TextStyle style;
+    private List<TextChar> textChars;
+
+    TextStringWrapper(
+      ContentScanner scanner
+      )
+    {
+      super((ShowText)scanner.getCurrent());
+
+      textChars = new ArrayList<TextChar>();
+      {
+        GraphicsState state = scanner.getState();
+        style = new TextStyle(
+          state.font,
+          state.fontSize,
+          state.renderMode,
+          state.strokeColor,
+          state.strokeColorSpace,
+          state.fillColor,
+          state.fillColorSpace
+          );
+        getBaseDataObject().scan(
+          state,
+          new ShowText.IScanner()
+          {
+            public void scanChar(
+              char textChar,
+              Rectangle2D textCharBox
+              )
+            {
+              textChars.add(
+                new TextChar(
+                  textChar,
+                  textCharBox,
+                  style,
+                  false
+                  )
+                );
+            }
+            public void scanFont(
+              double fontSize
+              )
+            {style.fontSize = fontSize;}
+          }
+          );
+      }
+    }
+
+    @Override
+    public Rectangle2D getBox(
+      )
+    {
+      if(box == null)
+      {
+        for(TextChar textChar : textChars)
+        {
+          if(box == null)
+          {box = (Rectangle2D)textChar.box.clone();}
+          else
+          {box.add(textChar.box);}
+        }
+      }
+      return box;
+    }
+
+    /**
+      Gets the text style.
+     */
+    public TextStyle getStyle(
+      )
+    {return style;}
+
+    public String getText(
+      )
+    {
+      StringBuilder textBuilder = new StringBuilder();
+      for(TextChar textChar : textChars)
+      {textBuilder.append(textChar);}
+      return textBuilder.toString();
+    }
+
+    public List<TextChar> getTextChars(
+      )
+    {return textChars;}
+  }
+
+  /**
+    External object information.
+  */
+  public static final class XObjectWrapper
+    extends GraphicsObjectWrapper<XObject>
+  {
+    private PdfName name;
+    private it.stefanochizzolini.clown.documents.contents.xObjects.XObject xObject;
+
+    private XObjectWrapper(
+      ContentScanner scanner
+      )
+    {
+      super((XObject)scanner.getCurrent());
+
+      IContentContext context = scanner.getContentContext();
+      double[] ctm = scanner.getState().ctm;
+      this.box = new Rectangle2D.Double(
+        ctm[4],
+        context.getBox().getHeight() - ctm[5],
+        ctm[0],
+        Math.abs(ctm[3])
+        );
+      this.name = getBaseDataObject().getName();
+      this.xObject = context.getResources().getXObjects().get(name);
+    }
+
+    /**
+      Gets the corresponding resource key.
+    */
+    public PdfName getName(
+      )
+    {return name;}
+
+    /**
+      Gets the external object.
+    */
+    public it.stefanochizzolini.clown.documents.contents.xObjects.XObject getXObject(
+      )
+    {return xObject;}
+  }
+  // </classes>
+
+  // <static>
+  // <fields>
+  private static final int StartIndex = -1;
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <fields>
+  /**
+    Child level.
+  */
+  private ContentScanner childLevel;
+  /**
+    Content objects collection.
+  */
+  private Contents contents;
+  /**
+    Current object index at this level.
+  */
+  private int index;
+  /**
+    Object collection at this level.
+  */
+  private List<ContentObject> objects;
+  /**
+    Parent level.
+  */
+  private ContentScanner parentLevel;
+  /**
+    Current graphics state.
+  */
+  private GraphicsState state;
+  // </fields>
+
+  // <constructors>
+  /**
+    @param contents Content objects collection to scan.
+  */
+  public ContentScanner(
+    Contents contents
+    )
+  {
+    this.parentLevel = null;
+    this.objects = this.contents = contents;
+
+    moveStart();
+  }
+
+  /**
+    @param contentContext Content context containing the content objects collection to scan.
+  */
+  public ContentScanner(
+    IContentContext contentContext
+    )
+  {this(contentContext.getContents());}
+
+  /**
+    @param parentLevel Parent scan level.
+  */
+  private ContentScanner(
+    ContentScanner parentLevel
+    )
+  {
+    this.parentLevel = parentLevel;
+    this.contents = parentLevel.contents;
+    this.objects = ((CompositeObject)parentLevel.getCurrent()).getObjects();
+
+    moveStart();
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  /**
+    Gets the current child scan level.
+
+    @see #getParentLevel()
+  */
+  public ContentScanner getChildLevel(
+    )
+  {return childLevel;}
+
+  /**
+    Gets the content context associated to the content objects collection.
+  */
+  public IContentContext getContentContext(
+    )
+  {return contents.getContentContext();}
+
+  /**
+    Gets the content objects collection this scanner is inspecting.
+  */
+  public Contents getContents(
+    )
+  {return contents;}
+
+  /**
+    Gets the current content object.
+
+    @see #getIndex()
+    @see #getParent()
+  */
+  public ContentObject getCurrent(
+    )
+  {
+    try
+    {return objects.get(index);}
+    catch(Exception e)
+    {return null;}
+  }
+
+  /**
+    Gets the current content object's information.
+
+    @see #getCurrent()
+  */
+  @SuppressWarnings("unchecked")
+  public GraphicsObjectWrapper getCurrentWrapper(
+    )
+  {return GraphicsObjectWrapper.get(this);}
+
+  /**
+    Gets the current position.
+
+    @see #getCurrent()
+  */
+  public int getIndex(
+    )
+  {return index;}
+
+  /**
+    Gets the current parent object.
+
+    @see #getCurrent()
+  */
+  public CompositeObject getParent(
+    )
+  {return (parentLevel == null ? null : (CompositeObject)parentLevel.getCurrent());}
+
+  /**
+    Gets the parent scan level.
+
+    @see #getChildLevel()
+  */
+  public ContentScanner getParentLevel(
+    )
+  {return parentLevel;}
+
+  /**
+    Gets the current graphics state applied to the current content object.
+    <h3>Remarks</h3>
+    <p>The returned object of this method is fundamental for any content manipulation
+    as it represents the actual constraints that affect the current content object
+    rendering.</p>
+  */
+  public GraphicsState getState(
+    )
+  {return state;}
+
+  /**
+    Inserts a content object at the current position.
+  */
+  public void insert(
+    ContentObject object
+    )
+  {
+    if(index == -1)
+    {index = 0;}
+
+    objects.add(index,object);
+    refresh();
+  }
+
+  /**
+    Inserts content objects at the current position.
+    <h3>Remarks</h3>
+    <p>After insertion complete, lastly-inserted content object is at the current position.</p>
+  */
+  public void insert(
+    Collection<? extends ContentObject> objects
+    )
+  {
+    int index = 0;
+    int size = objects.size();
+    for(ContentObject object : objects)
+    {
+      insert(object);
+
+      if(++index < size)
+      {moveNext();}
+    }
+  }
+
+  /**
+    Moves to the object at the given position.
+
+    @since 0.0.8
+    @param index New position.
+    @return Whether the object was successfully reached.
+  */
+  public boolean move(
+    int index
+    )
+  {
+    if(this.index > index)
+    {moveStart();}
+    while(this.index < index
+      && moveNext())
+    {}
+    return getCurrent() != null;
+  }
+
+  /**
+    Moves after the last object.
+
+    @since 0.0.8
+  */
+  public void moveEnd(
+    )
+  {moveLast(); moveNext();}
+
+  /**
+    Moves to the first object.
+
+    @since 0.0.5
+    @return Whether the first object was successfully reached.
+  */
+  public boolean moveFirst(
+    )
+  {moveStart(); return moveNext();}
+
+  /**
+    Moves to the last object.
+
+    @since 0.0.5
+    @return Whether the last object was successfully reached.
+  */
+  public boolean moveLast(
+    )
+  {
+    int lastIndex = objects.size()-1;
+    while(index < lastIndex)
+    {moveNext();}
+    return getCurrent() != null;
+  }
+
+  /**
+    Moves to the next object.
+
+    @return Whether the next object was successfully reached.
+  */
+  public boolean moveNext(
+    )
+  {
+    // Updating the current graphics state...
+    ContentObject currentObject = getCurrent();
+    if(currentObject != null)
+    {currentObject.applyTo(state);}
+
+    // Moving to the next object...
+    if(index < objects.size())
+    {
+      index++;
+      refresh();
+    }
+
+    return getCurrent() != null;
+  }
+
+  /**
+    Moves before the first object.
+
+    @since 0.0.8
+  */
+  public void moveStart(
+    )
+  {
+    index = StartIndex;
+    if(state == null)
+    {
+      if(parentLevel == null)
+      {state = new GraphicsState(this);}
+      else
+      {state = parentLevel.state.clone(this);}
+    }
+    else
+    {
+      if(parentLevel == null)
+      {state.initialize();}
+      else
+      {parentLevel.state.copyTo(state);}
+    }
+    refresh();
+  }
+
+  /**
+    Removes the content object at the current position.
+
+    @return Removed object.
+  */
+  public ContentObject remove(
+    )
+  {
+    ContentObject removedObject = objects.remove(index);
+    refresh();
+
+    return removedObject;
+  }
+
+  /**
+    Replaces the content object at the current position.
+
+    @return Replaced object.
+  */
+  public ContentObject setCurrent(
+    ContentObject value
+    )
+  {
+    ContentObject replacedObject = objects.set(index,value);
+    refresh();
+
+    return replacedObject;
+  }
+  // </public>
+
+  // <private>
+  /**
+    Synchronizes the scanner state.
+  */
+  private void refresh(
+    )
+  {
+    if(getCurrent() instanceof CompositeObject)
+    {childLevel = new ContentScanner(this);}
+    else
+    {childLevel = null;}
+  }
+  // </private>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/Contents.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/Contents.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/Contents.java	(revision 23703)
@@ -0,0 +1,297 @@
+/*
+  Copyright 2007-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents;
+
+import it.stefanochizzolini.clown.bytes.IBuffer;
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.contents.objects.ContentObject;
+import it.stefanochizzolini.clown.documents.contents.tokens.Parser;
+import it.stefanochizzolini.clown.files.File;
+import it.stefanochizzolini.clown.objects.PdfArray;
+import it.stefanochizzolini.clown.objects.PdfDataObject;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfObjectWrapper;
+import it.stefanochizzolini.clown.objects.PdfReference;
+import it.stefanochizzolini.clown.objects.PdfStream;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+
+/**
+  Content objects collection.
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+  @since 0.0.4
+*/
+public class Contents
+  extends PdfObjectWrapper<PdfDataObject>
+  implements List<ContentObject>
+{
+  // <class>
+  // <dynamic>
+  // <fields>
+  private List<ContentObject> items;
+
+  private IContentContext contentContext;
+  // </fields>
+
+  // <constructors>
+  /**
+    For internal use only.
+  */
+  public Contents(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container,
+    IContentContext contentContext
+    )
+  {
+    super(
+      baseObject,
+      container
+      );
+
+    this.contentContext = contentContext;
+
+    load();
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public Contents clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    Serializes the contents into the content stream.
+  */
+  public void flush(
+    )
+  {
+    PdfStream stream;
+    PdfDataObject baseDataObject = getBaseDataObject();
+    // Are contents just a single stream object?
+    if(baseDataObject instanceof PdfStream) // Single stream.
+    {stream = (PdfStream)baseDataObject;}
+    else // Array of streams.
+    {
+      PdfArray streams = (PdfArray)baseDataObject;
+      // No stream available?
+      if(streams.size() == 0) // No stream.
+      {
+        // Add first stream!
+        stream = new PdfStream();
+        streams.add( // Inserts the new stream into the content stream.
+          getFile().register(stream) // Inserts the new stream into the file.
+          );
+      }
+      else // Streams exist.
+      {
+        // Eliminating exceeding streams...
+        /*
+          NOTE: Applications that consume or produce PDF files are not required to preserve
+          the existing structure of the Contents array [PDF:1.6:3.6.2].
+        */
+        while(streams.size() > 1)
+        {
+          getFile().unregister( // Removes the exceeding stream from the file.
+            (PdfReference)streams.remove(1) // Removes the exceeding stream from the content stream.
+            );
+        }
+
+        PdfReference streamReference = (PdfReference)streams.get(0);
+        File.update(streamReference); // Updates the existing stream into the file.
+        stream = (PdfStream)streamReference.getDataObject();
+      }
+    }
+
+    // Get the stream buffer!
+    IBuffer buffer = stream.getBody();
+    // Delete old contents from the stream buffer!
+    buffer.setLength(0);
+    // Serializing the new contents into the stream buffer...
+    for(ContentObject item : items)
+    {item.writeTo(buffer);}
+
+    // Update the content stream container!
+    update();
+  }
+
+  public IContentContext getContentContext(
+    )
+  {return contentContext;}
+
+  // <List>
+  public void add(
+    int index,
+    ContentObject content
+    )
+  {items.add(index,content);}
+
+  public boolean addAll(
+    int index,
+    Collection<? extends ContentObject> contents
+    )
+  {return items.addAll(index,contents);}
+
+  public ContentObject get(
+    int index
+    )
+  {return items.get(index);}
+
+  public int indexOf(
+    Object content
+    )
+  {return items.indexOf(content);}
+
+  public int lastIndexOf(
+    Object content
+    )
+  {return items.lastIndexOf(content);}
+
+  public ListIterator<ContentObject> listIterator(
+    )
+  {return items.listIterator();}
+
+  public ListIterator<ContentObject> listIterator(
+    int index
+    )
+  {return items.listIterator(index);}
+
+  public ContentObject remove(
+    int index
+    )
+  {return items.remove(index);}
+
+  public ContentObject set(
+    int index,
+    ContentObject content
+    )
+  {return items.set(index,content);}
+
+  public List<ContentObject> subList(
+    int fromIndex,
+    int toIndex
+    )
+  {return items.subList(fromIndex,toIndex);}
+
+  // <Collection>
+  public boolean add(
+    ContentObject content
+    )
+  {return items.add(content);}
+
+  public boolean addAll(
+    Collection<? extends ContentObject> contents
+    )
+  {return items.addAll(contents);}
+
+  public void clear(
+    )
+  {items.clear();}
+
+  public boolean contains(
+    Object content
+    )
+  {return items.contains(content);}
+
+  public boolean containsAll(
+    Collection<?> contents
+    )
+  {return items.containsAll(contents);}
+
+  public boolean equals(
+    Object object
+    )
+  {throw new NotImplementedException();}
+
+  public int hashCode(
+    )
+  {throw new NotImplementedException();}
+
+  public boolean isEmpty(
+    )
+  {return items.isEmpty();}
+
+  public boolean remove(
+    Object content
+    )
+  {return items.remove(content);}
+
+  public boolean removeAll(
+    Collection<?> contents
+    )
+  {return items.removeAll(contents);}
+
+  public boolean retainAll(
+    Collection<?> contents
+    )
+  {return items.retainAll(contents);}
+
+  public int size(
+    )
+  {return items.size();}
+
+  public Object[] toArray(
+    )
+  {return items.toArray();}
+
+  public <T> T[] toArray(
+    T[] contents
+    )
+  {return items.toArray(contents);}
+
+  // <Iterable>
+  public Iterator<ContentObject> iterator(
+    )
+  {return items.iterator();}
+  // </Iterable>
+  // </Collection>
+  // </List>
+  // </public>
+
+  // <private>
+  private void load(
+    )
+  {
+    final Parser parser = new Parser(getBaseDataObject());
+    try
+    {items = parser.parseContentObjects();}
+    catch(Exception e)
+    {throw new RuntimeException(e);}
+  }
+  // </private>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/ExtGState.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/ExtGState.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/ExtGState.java	(revision 23703)
@@ -0,0 +1,175 @@
+/*
+  Copyright 2009 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.contents.fonts.Font;
+import it.stefanochizzolini.clown.objects.IPdfNumber;
+import it.stefanochizzolini.clown.objects.PdfArray;
+import it.stefanochizzolini.clown.objects.PdfDictionary;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfInteger;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfObjectWrapper;
+import it.stefanochizzolini.clown.objects.PdfReference;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+/**
+  Graphics state parameter dictionary [PDF:1.6:4.3.4].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+  @since 0.0.8
+*/
+public class ExtGState
+  extends PdfObjectWrapper<PdfDictionary>
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  public ExtGState(
+    Document context,
+    PdfDictionary baseDataObject
+    )
+  {
+    super(
+      context.getFile(),
+      baseDataObject
+      );
+  }
+
+  ExtGState(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {
+    super(
+      baseObject,
+      container
+      );
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public ExtGState clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  public Font getFont(
+    )
+  {
+    PdfArray fontObject = (PdfArray)getBaseDataObject().get(PdfName.Font);
+    if(fontObject == null)
+      return null;
+
+    return Font.wrap(
+      (PdfReference)fontObject.get(0)
+      );
+  }
+
+  public Double getFontSize(
+    )
+  {
+    PdfArray fontObject = (PdfArray)getBaseDataObject().get(PdfName.Font);
+    if(fontObject == null)
+      return null;
+
+    return new Double(
+      ((IPdfNumber)fontObject.get(1)).getNumberValue()
+      );
+  }
+
+  public LineCapEnum getLineCap(
+    )
+  {
+    PdfInteger lineCapObject = (PdfInteger)getBaseDataObject().get(PdfName.LC);
+    if(lineCapObject == null)
+      return null;
+
+    return LineCapEnum.valueOf(lineCapObject.getRawValue());
+  }
+
+  public LineDash getLineDash(
+    )
+  {
+    PdfArray lineDashObject = (PdfArray)getBaseDataObject().get(PdfName.D);
+    if(lineDashObject == null)
+      return null;
+
+    // 1. Dash array.
+    PdfArray baseDashArray = (PdfArray)lineDashObject.get(0);
+    double[] dashArray = new double[baseDashArray.size()];
+    for(
+      int index = 0,
+        length = dashArray.length;
+      index < length;
+      index++
+      )
+    {dashArray[index] = ((IPdfNumber)baseDashArray.get(index)).getNumberValue();}
+    // 2. Dash phase.
+    double dashPhase = ((IPdfNumber)lineDashObject.get(1)).getNumberValue();
+
+    return new LineDash(dashArray,dashPhase);
+  }
+
+  public LineJoinEnum getLineJoin(
+    )
+  {
+    PdfInteger lineJoinObject = (PdfInteger)getBaseDataObject().get(PdfName.LJ);
+    if(lineJoinObject == null)
+      return null;
+
+    return LineJoinEnum.valueOf(lineJoinObject.getRawValue());
+  }
+
+  public Double getLineWidth(
+    )
+  {
+    IPdfNumber lineWidthObject = (IPdfNumber)getBaseDataObject().get(PdfName.LW);
+    if(lineWidthObject == null)
+      return null;
+
+    return new Double(lineWidthObject.getNumberValue());
+  }
+
+  public Double getMiterLimit(
+    )
+  {
+    IPdfNumber miterLimitObject = (IPdfNumber)getBaseDataObject().get(PdfName.ML);
+    if(miterLimitObject == null)
+      return null;
+
+    return new Double(miterLimitObject.getNumberValue());
+  }
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/ExtGStateResources.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/ExtGStateResources.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/ExtGStateResources.java	(revision 23703)
@@ -0,0 +1,186 @@
+/*
+  Copyright 2009 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.objects.PdfDictionary;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfObjectWrapper;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+
+/**
+  Graphics state parameter resources collection [PDF:1.6:3.7.2].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+  @since 0.0.8
+*/
+public class ExtGStateResources
+  extends PdfObjectWrapper<PdfDictionary>
+  implements Map<PdfName,ExtGState>
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  public ExtGStateResources(
+    Document context
+    )
+  {
+    super(
+      context.getFile(),
+      new PdfDictionary()
+      );
+  }
+
+  ExtGStateResources(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {
+    super(
+      baseObject,
+      container
+      );
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public ExtGStateResources clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    Gets the key associated to a given value.
+  */
+  public PdfName getKey(
+    ExtGState value
+    )
+  {return getBaseDataObject().getKey(value.getBaseObject());}
+
+  // <Map>
+  public void clear(
+    )
+  {getBaseDataObject().clear();}
+
+  public boolean containsKey(
+    Object key
+    )
+  {return getBaseDataObject().containsKey(key);}
+
+  public boolean containsValue(
+    Object value
+    )
+  {return getBaseDataObject().containsValue(((ExtGState)value).getBaseObject());}
+
+  public Set<Map.Entry<PdfName,ExtGState>> entrySet(
+    )
+  {throw new NotImplementedException();}
+
+  public boolean equals(
+    PdfDirectObject object
+    )
+  {throw new NotImplementedException();}
+
+  public ExtGState get(
+    Object key
+    )
+  {
+    return new ExtGState(
+      getBaseDataObject().get(key),
+      getContainer()
+      );
+  }
+
+  public int hashCode(
+    )
+  {throw new NotImplementedException();}
+
+  public boolean isEmpty(
+    )
+  {return getBaseDataObject().isEmpty();}
+
+  public Set<PdfName> keySet(
+    )
+  {return getBaseDataObject().keySet();}
+
+  public ExtGState put(
+    PdfName key,
+    ExtGState value
+    )
+  {
+    return new ExtGState(
+      getBaseDataObject().put(key,value.getBaseObject()),
+      getContainer()
+      );
+  }
+
+  public void putAll(
+    Map<? extends PdfName,? extends ExtGState> entries
+    )
+  {throw new NotImplementedException();}
+
+  public ExtGState remove(
+    Object key
+    )
+  {
+    return new ExtGState(
+      getBaseDataObject().remove(key),
+      getContainer()
+      );
+  }
+
+  public int size(
+    )
+  {return getBaseDataObject().size();}
+
+  public Collection<ExtGState> values(
+    )
+  {
+    // Get the raw objects!
+    Collection<PdfDirectObject> extGStateObjects = getBaseDataObject().values();
+    // Populating the collection...
+    Collection<ExtGState> values = new ArrayList<ExtGState>(extGStateObjects.size());
+    for(PdfDirectObject extGStateObject : extGStateObjects)
+    {values.add(new ExtGState(extGStateObject,getContainer()));}
+
+    return values;
+  }
+  // </Map>
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/FontResources.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/FontResources.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/FontResources.java	(revision 23703)
@@ -0,0 +1,185 @@
+/*
+  Copyright 2006 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.contents.fonts.Font;
+import it.stefanochizzolini.clown.objects.PdfDictionary;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfObjectWrapper;
+import it.stefanochizzolini.clown.objects.PdfReference;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+
+/**
+  Font resources collection [PDF:1.6:3.7.2].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.7
+*/
+public class FontResources
+  extends PdfObjectWrapper<PdfDictionary>
+  implements Map<PdfName,Font>
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  public FontResources(
+    Document context
+    )
+  {
+    super(
+      context.getFile(),
+      new PdfDictionary()
+      );
+  }
+
+  FontResources(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {
+    super(
+      baseObject,
+      container
+      );
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public FontResources clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    Gets the key associated to a given value.
+  */
+  public PdfName getKey(
+    Font value
+    )
+  {return getBaseDataObject().getKey(value.getBaseObject());}
+
+  // <Map>
+  public void clear(
+    )
+  {getBaseDataObject().clear();}
+
+  public boolean containsKey(
+    Object key
+    )
+  {return getBaseDataObject().containsKey(key);}
+
+  public boolean containsValue(
+    Object value
+    )
+  {return getBaseDataObject().containsValue(((Font)value).getBaseObject());}
+
+  public Set<Map.Entry<PdfName,Font>> entrySet(
+    )
+  {throw new NotImplementedException();}
+
+  public boolean equals(
+    PdfDirectObject object
+    )
+  {throw new NotImplementedException();}
+
+  public Font get(
+    Object key
+    )
+  {
+    return Font.wrap(
+      (PdfReference)getBaseDataObject().get(key)
+      );
+  }
+
+  public int hashCode(
+    )
+  {throw new NotImplementedException();}
+
+  public boolean isEmpty(
+    )
+  {return getBaseDataObject().isEmpty();}
+
+  public Set<PdfName> keySet(
+    )
+  {return getBaseDataObject().keySet();}
+
+  public Font put(
+    PdfName key,
+    Font value
+    )
+  {
+    return Font.wrap(
+      (PdfReference)getBaseDataObject().put(key,value.getBaseObject())
+      );
+  }
+
+  public void putAll(
+    Map<? extends PdfName,? extends Font> entries
+    )
+  {throw new NotImplementedException();}
+
+  public Font remove(
+    Object key
+    )
+  {
+    return Font.wrap(
+      (PdfReference)getBaseDataObject().remove(key)
+      );
+  }
+
+  public int size(
+    )
+  {return getBaseDataObject().size();}
+
+  public Collection<Font> values(
+    )
+  {
+    // Get the raw objects!
+    Collection<PdfDirectObject> objects = getBaseDataObject().values();
+    // Get room for the corresponding Font collection!
+    Collection<Font> values = new ArrayList<Font>(objects.size());
+    // Populating the Font collection...
+    for(PdfDirectObject object : objects)
+    {values.add(Font.wrap((PdfReference)object));}
+
+    return values;
+  }
+  // </Map>
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/IContentContext.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/IContentContext.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/IContentContext.java	(revision 23703)
@@ -0,0 +1,69 @@
+/*
+  Copyright 2006-2009 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents;
+
+import java.awt.geom.Rectangle2D;
+
+/**
+  Content stream context.
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+*/
+public interface IContentContext
+  extends IContentEntity
+{
+  /**
+    Gets the bounding box associated with the object, either explicitly (directly
+    associated to the object) or (if not explicitly available) implicitly (inherited
+    from a higher level object).
+    <h3>Remarks</h3>
+    <p>The box represents the physical-coordinates frame expressed in default
+    user-space units. This frame is crucial for the proper positioning of graphic
+    elements on the canvas, as the spec [PDF:1.6:4.2] states that the
+    coordinate system is positively-oriented, although the typographic coordinates
+    would be conveniently expressed as negatively-oriented.</p>
+  */
+  Rectangle2D getBox(
+    );
+
+  /**
+    Gets the contents collection representing the content stream.
+    @since 0.0.5
+  */
+  Contents getContents(
+    );
+
+  /**
+    Gets the resources associated with the object, either explicitly (directly
+    associated to the object) or (if not explicitly available) implicitly (inherited
+    from a higher-level object).
+    <h3>Remarks</h3>
+    <p>The implementing class MUST ensure that the returned object isn't null.</p>
+  */
+  Resources getResources(
+    );
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/IContentEntity.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/IContentEntity.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/IContentEntity.java	(revision 23703)
@@ -0,0 +1,76 @@
+/*
+  Copyright 2007-2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.contents.composition.PrimitiveFilter;
+import it.stefanochizzolini.clown.documents.contents.objects.ContentObject;
+import it.stefanochizzolini.clown.documents.contents.xObjects.XObject;
+
+/**
+  Generic content entity.
+  <p>It provides common ways to convert any content into content stream objects.</p>
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.6
+  @since 0.0.5
+*/
+public interface IContentEntity
+{
+  /**
+    Converts the entity to its equivalent inline (dependent) object representation [PDF:1.6:4.8.6].
+
+    <h3>Remarks</h3>
+    <p>This method creates and shows an inline object within the target content context,
+    returning it.</p>
+    <p>Due to its direct-content nature (opposite to the indirect-content nature of
+    external objects (see {@link #toXObject(Document)})), the resulting object should be shown
+    only one time in order not to wastefully duplicate its data.</p>
+
+    @param context Target content context.
+    @return The inline object representing the entity.
+    @since 0.0.6
+  */
+  ContentObject toInlineObject(
+    PrimitiveFilter context
+    );
+
+  /**
+    Converts the entity to its equivalent external (independent) object representation [PDF:1.6:4.7].
+
+    <h3>Remarks</h3>
+    <p>This method creates an external object within the target document, returning it. To show it
+    in a content context (for example: a page), then it must be applied in an appropriate manner (see
+    {@link it.stefanochizzolini.clown.documents.contents.composition.PrimitiveFilter PrimitiveFilter} object).</p>
+
+    @param context Target document.
+    @return The external object representing the entity.
+    @since 0.0.5
+  */
+  XObject toXObject(
+    Document context
+    );
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/ITextString.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/ITextString.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/ITextString.java	(revision 23703)
@@ -0,0 +1,56 @@
+/*
+  Copyright 2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents;
+
+import java.awt.geom.Rectangle2D;
+import java.util.List;
+
+/**
+  Text string.
+  Its purpose is to describe a text chunk extracted from content streams.
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.8
+  @version 0.0.8
+*/
+public interface ITextString
+{
+  /**
+    Gets the text string bounds.
+  */
+  public Rectangle2D getBox(
+    );
+  /**
+    Gets the decoded text.
+  */
+  public String getText(
+    );
+  /**
+    Gets the information of each text string character.
+  */
+  public List<TextChar> getTextChars(
+    );
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/LineCapEnum.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/LineCapEnum.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/LineCapEnum.java	(revision 23703)
@@ -0,0 +1,102 @@
+/*
+  Copyright 2006 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+  Shape to be used at the ends of stroked open subpaths [PDF:1.6:4.3.2].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.4
+*/
+public enum LineCapEnum
+{
+  // <class>
+  // <static>
+  // <fields>
+  /**
+    Truncated line cap.
+  */
+  Butt(0),
+  /**
+    Rounded line cap.
+  */
+  Round(1),
+  /**
+    Squared-off line cap.
+  */
+  Square(2);
+
+  private static Map<Integer, LineCapEnum> map = new HashMap<Integer, LineCapEnum>();
+  // </fields>
+
+  // <constructors>
+  static
+  {
+    for (LineCapEnum value : LineCapEnum.values())
+    {map.put(value.getCode(), value);}
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  public static LineCapEnum valueOf(
+    int code
+    )
+  {return map.get(code);}
+  // </public>
+  // </interface>
+  // </static>
+
+  // <dynamic>
+  // <fields>
+  /**
+    <h3>Remarks</h3>
+    <p>Code MUST be explicitly distinct from the ordinal position of the enum constant
+    as they coincide by chance only.</p>
+  */
+  private final int code;
+  // </fields>
+
+  // <constructors>
+  private LineCapEnum(
+    int code
+    )
+  {this.code = code;}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  public int getCode(
+    )
+  {return code;}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/LineDash.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/LineDash.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/LineDash.java	(revision 23703)
@@ -0,0 +1,78 @@
+/*
+  Copyright 2007-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents;
+
+
+/**
+  Line Dash Pattern [PDF:1.6:4.3.2].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.4
+  @version 0.0.8
+*/
+public final class LineDash
+{
+  // <class>
+  // <dynamic>
+  // <fields>
+  private double[] dashArray;
+  private double dashPhase;
+  // </fields>
+
+  // <constructors>
+  public LineDash(
+    )
+  {this(null);}
+
+  public LineDash(
+    double[] dashArray
+    )
+  {this(dashArray,0);}
+
+  public LineDash(
+    double[] dashArray,
+    double dashPhase
+    )
+  {
+    this.dashArray = dashArray;
+    this.dashPhase = dashPhase;
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  public double[] getDashArray(
+    )
+  {return dashArray;}
+
+  public double getDashPhase(
+    )
+  {return dashPhase;}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/LineJoinEnum.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/LineJoinEnum.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/LineJoinEnum.java	(revision 23703)
@@ -0,0 +1,102 @@
+/*
+  Copyright 2006 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+  Shape to be used at the corners of stroked paths [PDF:1.6:4.3.2].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.4
+*/
+public enum LineJoinEnum
+{
+  // <class>
+  // <static>
+  // <fields>
+  /**
+    Sharp line join.
+  */
+  Miter(0),
+  /**
+    Rounded line join.
+  */
+  Round(1),
+  /**
+    Squared-off line join.
+  */
+  Bevel(2);
+
+  private static Map<Integer, LineJoinEnum> map = new HashMap<Integer, LineJoinEnum>();
+  // </fields>
+
+  // <constructors>
+  static
+  {
+    for (LineJoinEnum value : LineJoinEnum.values())
+    {map.put(value.getCode(), value);}
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  public static LineJoinEnum valueOf(
+    int code
+    )
+  {return map.get(code);}
+  // </public>
+  // </interface>
+  // </static>
+
+  // <dynamic>
+  // <fields>
+  /**
+    <h3>Remarks</h3>
+    <p>Code MUST be explicitly distinct from the ordinal position of the enum constant
+    as they coincide by chance only.</p>
+  */
+  private final int code;
+  // </fields>
+
+  // <constructors>
+  private LineJoinEnum(
+    int code
+    )
+  {this.code = code;}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  public int getCode(
+    )
+  {return code;}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/Resources.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/Resources.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/Resources.java	(revision 23703)
@@ -0,0 +1,168 @@
+/*
+  Copyright 2006-2009 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.objects.PdfDictionary;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfObjectWrapper;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+/**
+  Resources collection [PDF:1.6:3.7.2].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+*/
+public class Resources
+  extends PdfObjectWrapper<PdfDictionary>
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  public Resources(
+    Document context
+    )
+  {
+    super(
+      context.getFile(),
+      new PdfDictionary()
+      );
+  }
+
+  /**
+    For internal use only.
+  */
+  public Resources(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {
+    super(
+      baseObject,
+      container
+      );
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public Resources clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  public ColorSpaceResources getColorSpaces(
+    )
+  {
+    /*
+      NOTE: ColorSpace entry may be undefined [PDF:1.6:3.7.2].
+    */
+    PdfDirectObject colorSpaces = getBaseDataObject().get(PdfName.ColorSpace);
+    if(colorSpaces == null)
+      return null;
+
+    return new ColorSpaceResources(
+      colorSpaces,
+      getContainer()
+      );
+  }
+
+  public ExtGStateResources getExtGStates(
+    )
+  {
+    /*
+      NOTE: ExtGState entry may be undefined [PDF:1.6:3.7.2].
+    */
+    PdfDirectObject extGStates = getBaseDataObject().get(PdfName.ExtGState);
+    if(extGStates == null)
+      return null;
+
+    return new ExtGStateResources(
+      extGStates,
+      getContainer()
+      );
+  }
+
+  public FontResources getFonts(
+    )
+  {
+    /*
+      NOTE: Font entry may be undefined [PDF:1.6:3.7.2].
+    */
+    PdfDirectObject fonts = getBaseDataObject().get(PdfName.Font);
+    if(fonts == null)
+      return null;
+
+    return new FontResources(
+      fonts,
+      getContainer()
+      );
+  }
+
+  public XObjectResources getXObjects(
+    )
+  {
+    /*
+      NOTE: XObject entry may be undefined [PDF:1.6:3.7.2].
+    */
+    PdfDirectObject xObjects = getBaseDataObject().get(PdfName.XObject);
+    if(xObjects == null)
+      return null;
+
+    return new XObjectResources(
+      xObjects,
+      getContainer()
+      );
+  }
+
+  public void setColorSpaces(
+    ColorSpaceResources value
+    )
+  {getBaseDataObject().put(PdfName.ColorSpace,value.getBaseObject());}
+
+  public void setExtGStates(
+    ExtGStateResources value
+    )
+  {getBaseDataObject().put(PdfName.ExtGState,value.getBaseObject());}
+
+  public void setFonts(
+    FontResources value
+    )
+  {getBaseDataObject().put(PdfName.Font,value.getBaseObject());}
+
+  public void setXObjects(
+    XObjectResources value
+    )
+  {getBaseDataObject().put(PdfName.XObject,value.getBaseObject());}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/TextChar.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/TextChar.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/TextChar.java	(revision 23703)
@@ -0,0 +1,75 @@
+/*
+  Copyright 2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents;
+
+import java.awt.geom.Rectangle2D;
+
+/**
+  Text character.
+  <h3>Remarks</h3>
+  <p>Its purpose is to describe a text element extracted from content streams.</p>
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.8
+  @version 0.0.8
+*/
+public final class TextChar
+{
+  // <class>
+  // <dynamic>
+  // <fields>
+  public final Rectangle2D box;
+  public final TextStyle style;
+  public final char value;
+  public final boolean virtual;
+  // </fields>
+
+  // <constructors>
+  public TextChar(
+    char value,
+    Rectangle2D box,
+    TextStyle style,
+    boolean virtual
+    )
+  {
+    this.value = value;
+    this.box = box;
+    this.style = style;
+    this.virtual = virtual;
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public String toString(
+    )
+  {return Character.toString(value);}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/TextRenderModeEnum.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/TextRenderModeEnum.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/TextRenderModeEnum.java	(revision 23703)
@@ -0,0 +1,121 @@
+/*
+  Copyright 2006 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+  Glyph-outlines appearance on text showing [PDF:1.6:5.2.5].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+*/
+public enum TextRenderModeEnum
+{
+  // <class>
+  // <static>
+  // <fields>
+  /**
+    Fill text glyphs.
+  */
+  Fill(0),
+  /**
+    Stroke text glyphs.
+  */
+  Stroke(1),
+  /**
+    Fill, then stroke text glyphs.
+  */
+  FillStroke(2),
+  /**
+    Do nothing (invisible text glyphs).
+  */
+  Invisible(3),
+  /**
+    Fill text glyphs, then apply to path for clipping.
+  */
+  FillClip(4),
+  /**
+    Stroke text glyphs, then apply to path for clipping.
+  */
+  StrokeClip(5),
+  /**
+    Fill, then stroke text glyphs, then apply to path for clipping.
+  */
+  FillStrokeClip(6),
+  /**
+    Apply text glyphs to path for clipping.
+  */
+  Clip(7);
+
+  private static Map<Integer, TextRenderModeEnum> map = new HashMap<Integer, TextRenderModeEnum>();
+  // </fields>
+
+  // <constructors>
+  static
+  {
+    for (TextRenderModeEnum value : TextRenderModeEnum.values())
+    {map.put(value.getCode(), value);}
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  public static TextRenderModeEnum valueOf(
+    int code
+    )
+  {return map.get(code);}
+  // </public>
+  // </interface>
+  // </static>
+
+  // <dynamic>
+  // <fields>
+  /**
+    <h3>Remarks</h3>
+    <p>Code MUST be explicitly distinct from the ordinal position of the enum constant
+    as they coincide by chance only.</p>
+  */
+  private final int code;
+  // </fields>
+
+  // <constructors>
+  private TextRenderModeEnum(
+    int code
+    )
+  {this.code = code;}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  public int getCode(
+    )
+  {return code;}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/TextStyle.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/TextStyle.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/TextStyle.java	(revision 23703)
@@ -0,0 +1,75 @@
+/*
+  Copyright 2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents;
+
+import it.stefanochizzolini.clown.documents.contents.colorSpaces.Color;
+import it.stefanochizzolini.clown.documents.contents.colorSpaces.ColorSpace;
+import it.stefanochizzolini.clown.documents.contents.fonts.Font;
+
+/**
+  Text style.
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.8
+  @version 0.0.8
+*/
+public final class TextStyle
+{
+  // <class>
+  // <dynamic>
+  // <fields>
+  public Color fillColor;
+  public ColorSpace fillColorSpace;
+  public Font font;
+  public double fontSize;
+  public TextRenderModeEnum renderMode;
+  public Color strokeColor;
+  public ColorSpace strokeColorSpace;
+  // </fields>
+
+  // <constructors>
+  public TextStyle(
+    Font font,
+    double fontSize,
+    TextRenderModeEnum renderMode,
+    Color strokeColor,
+    ColorSpace strokeColorSpace,
+    Color fillColor,
+    ColorSpace fillColorSpace
+    )
+  {
+    this.font = font;
+    this.fontSize = fontSize;
+    this.renderMode = renderMode;
+    this.strokeColor = strokeColor;
+    this.strokeColorSpace = strokeColorSpace;
+    this.fillColor = fillColor;
+    this.fillColorSpace = fillColorSpace;
+  }
+  // </constructors>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/XObjectResources.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/XObjectResources.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/XObjectResources.java	(revision 23703)
@@ -0,0 +1,185 @@
+/*
+  Copyright 2006 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.contents.xObjects.XObject;
+import it.stefanochizzolini.clown.objects.PdfDictionary;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfObjectWrapper;
+import it.stefanochizzolini.clown.objects.PdfReference;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+
+/**
+  External object resources collection [PDF:1.6:3.7.2].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.7
+*/
+public class XObjectResources
+  extends PdfObjectWrapper<PdfDictionary>
+  implements Map<PdfName,XObject>
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  public XObjectResources(
+    Document context
+    )
+  {
+    super(
+      context.getFile(),
+      new PdfDictionary()
+      );
+  }
+
+  XObjectResources(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {
+    super(
+      baseObject,
+      container
+      );
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public XObjectResources clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    Gets the key associated to a given value.
+  */
+  public PdfName getKey(
+    XObject value
+    )
+  {return getBaseDataObject().getKey(value.getBaseObject());}
+
+  // <Map>
+  public void clear(
+    )
+  {getBaseDataObject().clear();}
+
+  public boolean containsKey(
+    Object key
+    )
+  {return getBaseDataObject().containsKey(key);}
+
+  public boolean containsValue(
+    Object value
+    )
+  {return getBaseDataObject().containsValue(((XObject)value).getBaseObject());}
+
+  public Set<Map.Entry<PdfName,XObject>> entrySet(
+    )
+  {throw new NotImplementedException();}
+
+  public boolean equals(
+    PdfDirectObject object
+    )
+  {throw new NotImplementedException();}
+
+  public XObject get(
+    Object key
+    )
+  {
+    return XObject.wrap(
+      (PdfReference)getBaseDataObject().get(key)
+      );
+  }
+
+  public int hashCode(
+    )
+  {throw new NotImplementedException();}
+
+  public boolean isEmpty(
+    )
+  {return getBaseDataObject().isEmpty();}
+
+  public Set<PdfName> keySet(
+    )
+  {return getBaseDataObject().keySet();}
+
+  public XObject put(
+    PdfName key,
+    XObject value
+    )
+  {
+    return XObject.wrap(
+      (PdfReference)getBaseDataObject().put(key,value.getBaseObject())
+      );
+  }
+
+  public void putAll(
+    Map<? extends PdfName,? extends XObject> entries
+    )
+  {throw new NotImplementedException();}
+
+  public XObject remove(
+    Object key
+    )
+  {
+    return XObject.wrap(
+      (PdfReference)getBaseDataObject().remove(key)
+      );
+  }
+
+  public int size(
+    )
+  {return getBaseDataObject().size();}
+
+  public Collection<XObject> values(
+    )
+  {
+    // Get the raw objects!
+    Collection<PdfDirectObject> objects = getBaseDataObject().values();
+    // Get room for the corresponding Font collection!
+    Collection<XObject> values = new ArrayList<XObject>(objects.size());
+    // Populating the collection...
+    for(PdfDirectObject object : objects)
+    {values.add(XObject.wrap((PdfReference)object));}
+
+    return values;
+  }
+  // </Map>
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/colorSpaces/CIEBasedColorSpace.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/colorSpaces/CIEBasedColorSpace.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/colorSpaces/CIEBasedColorSpace.java	(revision 23703)
@@ -0,0 +1,67 @@
+/*
+  Copyright 2006 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.colorSpaces;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.objects.PdfArray;
+import it.stefanochizzolini.clown.objects.PdfDictionary;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+
+/**
+  Abstract CIE-based color space [PDF:1.6:4.5.4].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+*/
+public abstract class CIEBasedColorSpace
+  extends ColorSpace
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  protected CIEBasedColorSpace(
+    Document context,
+    PdfArray baseDataObject
+    )
+  {super(context,baseDataObject);}
+
+  protected CIEBasedColorSpace(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {super(baseObject,container);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  public PdfDictionary getParameters(
+    )
+  {return (PdfDictionary)((PdfArray)getBaseDataObject()).get(1);}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/colorSpaces/CalGrayColorSpace.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/colorSpaces/CalGrayColorSpace.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/colorSpaces/CalGrayColorSpace.java	(revision 23703)
@@ -0,0 +1,82 @@
+/*
+  Copyright 2006-2007 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.colorSpaces;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+/**
+  Single-component CIE-based color space, known as a 'CIE-based A' color
+  space [PDF:1.6:4.5.4].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.4
+*/
+public class CalGrayColorSpace
+  extends CIEBasedColorSpace
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+// TODO:IMPL!!!
+//     protected CalGrayColorSpace(
+//       Document context,
+//       PdfArray baseDataObject
+//       )
+//     {super(context,baseDataObject);}
+
+  CalGrayColorSpace(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {super(baseObject,container);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public CalGrayColorSpace clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+//TODO:IMPL
+  @Override
+  public Color getColor(
+    PdfDirectObject[] components
+    )
+  {return null;}
+//TODO:IMPL
+  @Override
+  public Color getDefaultColor(
+    )
+  {return null;}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/colorSpaces/CalRGBColorSpace.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/colorSpaces/CalRGBColorSpace.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/colorSpaces/CalRGBColorSpace.java	(revision 23703)
@@ -0,0 +1,82 @@
+/*
+  Copyright 2006-2007 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.colorSpaces;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+/**
+  CIE-based ABC single-transformation-stage color space (A, B, and C
+  represent calibrated red, green, and blue color values) [PDF:1.6:4.5.4].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.4
+*/
+public class CalRGBColorSpace
+  extends CIEBasedColorSpace
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+// TODO:IMPL!!!
+//     protected CalRGBColorSpace(
+//       Document context,
+//       PdfArray baseDataObject
+//       )
+//     {super(context,baseDataObject);}
+
+  CalRGBColorSpace(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {super(baseObject,container);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public CalRGBColorSpace clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+//TODO:IMPL
+  @Override
+  public Color getColor(
+    PdfDirectObject[] components
+    )
+  {return null;}
+//TODO:IMPL
+  @Override
+  public Color getDefaultColor(
+    )
+  {return null;}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/colorSpaces/Color.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/colorSpaces/Color.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/colorSpaces/Color.java	(revision 23703)
@@ -0,0 +1,89 @@
+/*
+  Copyright 2006-2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.colorSpaces;
+
+/**
+  Color value [PDF:1.6:4.5.1].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.6
+*/
+public abstract class Color
+{
+  // <class>
+  // <static>
+  // <interface>
+  // <protected>
+  /**
+    Gets the normalized value of a color component [PDF:1.6:4.5.1].
+    @param value Color component value to normalize.
+    @return Normalized color component value.
+  */
+  /*
+    NOTE: Further developments may result in a color-space family-specific
+    implementation of this method; currently this implementation focuses on
+    device colors only.
+  */
+  protected static double normalizeComponent(
+    double value
+    )
+  {
+    if(value < 0)
+      return 0d;
+    else if(value > 1)
+      return 1d;
+
+    return value;
+  }
+  // </protected>
+  // </interface>
+  // </static>
+
+  // <dynamic>
+  // <fields>
+  private ColorSpace colorSpace;
+  // </fields>
+
+  // <constructors>
+  protected Color(
+    ColorSpace colorSpace
+    )
+  {this.colorSpace = colorSpace;}
+  // </constructors>
+
+  // <interface>
+  // <internal>
+  public ColorSpace getColorSpace(
+    )
+  {return colorSpace;}
+
+  public abstract double[] getComponents(
+    );
+  // </internal>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/colorSpaces/ColorSpace.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/colorSpaces/ColorSpace.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/colorSpaces/ColorSpace.java	(revision 23703)
@@ -0,0 +1,152 @@
+/*
+  Copyright 2006-2007 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.colorSpaces;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.files.File;
+import it.stefanochizzolini.clown.objects.PdfArray;
+import it.stefanochizzolini.clown.objects.PdfDataObject;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfObjectWrapper;
+import it.stefanochizzolini.clown.objects.PdfReference;
+
+/**
+  Color space [PDF:1.6:4.5].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.4
+*/
+public abstract class ColorSpace
+  extends PdfObjectWrapper<PdfDirectObject>
+{
+  // <class>
+  // <static>
+  // <interface>
+  // <public>
+  /**
+    Wraps a color space reference into a color space object.
+    @param reference Reference to a color space object.
+    @return Color space object associated to the reference.
+  */
+  public static ColorSpace wrap(
+    PdfReference reference
+    )
+  {return wrap(reference,null);}
+
+  /**
+    Wraps a color space base object into a color space object.
+    @param baseObject Base object of a color space object.
+    @param container Indirect object possibly containing the color space
+    base object.
+    @return Color space object associated to the base object.
+  */
+  public static ColorSpace wrap(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {
+    /*
+      NOTE: This is a factory method for any ColorSpace-derived object.
+    */
+    if(baseObject == null)
+      return null;
+
+    PdfName name;
+    // Get the data object corresponding to the color space!
+    PdfDataObject baseDataObject = File.resolve(baseObject);
+    // Is it an array?
+    /*
+      NOTE: [PDF:1.6:4.5.2] A color space is defined by an array object whose
+      first element is a name object identifying the color space family. For
+      families that do not require parameters, the color space CAN be specified
+      simply by the family name itself instead of an array.
+    */
+    if(baseDataObject instanceof PdfArray) // PdfArray.
+    {name = (PdfName)((PdfArray)baseDataObject).get(0);}
+    else // PdfName (by definition).
+    {name = (PdfName)baseDataObject;}
+
+    if(name.equals(PdfName.DeviceRGB))
+      return new DeviceRGBColorSpace(baseObject,container);
+    else if(name.equals(PdfName.DeviceCMYK))
+      return new DeviceCMYKColorSpace(baseObject,container);
+    else if(name.equals(PdfName.DeviceGray))
+      return new DeviceGrayColorSpace(baseObject,container);
+    else if(name.equals(PdfName.CalRGB))
+      return new CalRGBColorSpace(baseObject,container);
+    else if(name.equals(PdfName.CalGray))
+      return new CalGrayColorSpace(baseObject,container);
+    else if(name.equals(PdfName.Lab))
+      return new LabColorSpace(baseObject,container);
+    else if(name.equals(PdfName.ICCBased))
+      return new ICCBasedColorSpace(baseObject,container);
+    else
+      return null; // Should never happen.
+  }
+  // </public>
+  // </interface>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  protected ColorSpace(
+    Document context,
+    PdfDirectObject baseDataObject
+    )
+  {
+    super(
+      context.getFile(),
+      baseDataObject
+      );
+  }
+
+  protected ColorSpace(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {
+    super(
+      baseObject,
+      container
+      );
+  }
+  // </constructors>
+
+  // <interface>
+  // <internal>
+  public abstract Color getColor(
+    PdfDirectObject[] components
+    );
+
+  public abstract Color getDefaultColor(
+    );
+  // </internal>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/colorSpaces/DeviceCMYKColor.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/colorSpaces/DeviceCMYKColor.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/colorSpaces/DeviceCMYKColor.java	(revision 23703)
@@ -0,0 +1,144 @@
+/*
+  Copyright 2006-2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.colorSpaces;
+
+/**
+  Device Cyan-Magenta-Yellow-Key color value [PDF:1.6:4.5.3].
+  <h3>Remarks</h3>
+  <p>The 'Key' component is renamed 'Black' to avoid semantic ambiguities.</p>
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.4
+*/
+public class DeviceCMYKColor
+  extends DeviceColor
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final DeviceCMYKColor Black = new DeviceCMYKColor(0,0,0,1);
+  public static final DeviceCMYKColor White = new DeviceCMYKColor(0,0,0,0);
+
+  public static final DeviceCMYKColor Default = Black;
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <fields>
+  private double blackComponent;
+  private double cyanComponent;
+  private double magentaComponent;
+  private double yellowComponent;
+  // </fields>
+
+  // <constructors>
+  public DeviceCMYKColor(
+    double cyanComponent,
+    double magentaComponent,
+    double yellowComponent,
+    double blackComponent
+    )
+  {
+    super(DeviceCMYKColorSpace.Default);
+
+    setCyanComponent(cyanComponent);
+    setMagentaComponent(magentaComponent);
+    setYellowComponent(yellowComponent);
+    setBlackComponent(blackComponent);
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  /**
+    Gets the black (key) component.
+  */
+  public double getBlackComponent(
+    )
+  {return blackComponent;}
+
+  @Override
+  public double[] getComponents(
+    )
+  {return new double[]{cyanComponent,magentaComponent,yellowComponent,blackComponent};}
+
+  /**
+    Gets the cyan component.
+  */
+  public double getCyanComponent(
+    )
+  {return cyanComponent;}
+
+  /**
+    Gets the magenta component.
+  */
+  public double getMagentaComponent(
+    )
+  {return magentaComponent;}
+
+  /**
+    Gets the yellow component.
+  */
+  public double getYellowComponent(
+    )
+  {return yellowComponent;}
+
+  /**
+    Sets the black (key) component.
+  */
+  public void setBlackComponent(
+    double value
+    )
+  {blackComponent = normalizeComponent(value);}
+
+  /**
+    Sets the cyan component.
+  */
+  public void setCyanComponent(
+    double value
+    )
+  {cyanComponent = normalizeComponent(value);}
+
+  /**
+    Sets the magenta component.
+  */
+  public void setMagentaComponent(
+    double value
+    )
+  {magentaComponent = normalizeComponent(value);}
+
+  /**
+    Sets the yellow component.
+  */
+  public void setYellowComponent(
+    double value
+    )
+  {yellowComponent = normalizeComponent(value);}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/colorSpaces/DeviceCMYKColorSpace.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/colorSpaces/DeviceCMYKColorSpace.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/colorSpaces/DeviceCMYKColorSpace.java	(revision 23703)
@@ -0,0 +1,108 @@
+/*
+  Copyright 2006-2007 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.colorSpaces;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.objects.IPdfNumber;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+/**
+  Device Cyan-Magenta-Yellow-Key color space [PDF:1.6:4.5.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.4
+*/
+public class DeviceCMYKColorSpace
+  extends DeviceColorSpace
+{
+  // <class>
+  // <static>
+  // <fields>
+  /*
+    NOTE: It may be specified directly (i.e. without being defined in the ColorSpace subdictionary
+    of the contextual resource dictionary) [PDF:1.6:4.5.7].
+  */
+  public static final DeviceCMYKColorSpace Default = new DeviceCMYKColorSpace(null,null);
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  public DeviceCMYKColorSpace(
+    Document context
+    )
+  {
+    super(
+      context,
+      PdfName.DeviceCMYK
+      );
+  }
+
+  DeviceCMYKColorSpace(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {
+    super(
+      baseObject,
+      container
+      );
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public DeviceCMYKColorSpace clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  @Override
+  public Color getColor(
+    PdfDirectObject[] components
+    )
+  {
+    return new DeviceCMYKColor(
+      ((IPdfNumber)components[0]).getNumberValue(),
+      ((IPdfNumber)components[1]).getNumberValue(),
+      ((IPdfNumber)components[2]).getNumberValue(),
+      ((IPdfNumber)components[3]).getNumberValue()
+      );
+  }
+
+  @Override
+  public Color getDefaultColor(
+    )
+  {return DeviceCMYKColor.Default;}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/colorSpaces/DeviceColor.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/colorSpaces/DeviceColor.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/colorSpaces/DeviceColor.java	(revision 23703)
@@ -0,0 +1,46 @@
+/*
+  Copyright 2006 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.colorSpaces;
+
+/**
+  Device color value [PDF:1.6:4.5.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+*/
+public abstract class DeviceColor
+  extends Color
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  protected DeviceColor(
+    ColorSpace colorSpace
+    )
+  {super(colorSpace);}
+  // </constructors>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/colorSpaces/DeviceColorSpace.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/colorSpaces/DeviceColorSpace.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/colorSpaces/DeviceColorSpace.java	(revision 23703)
@@ -0,0 +1,58 @@
+/*
+  Copyright 2006 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.colorSpaces;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+
+/**
+  Device color space [PDF:1.6:4.5.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+*/
+public abstract class DeviceColorSpace
+  extends ColorSpace
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  protected DeviceColorSpace(
+    Document context,
+    PdfName baseDataObject
+    )
+  {super(context,baseDataObject);}
+
+  protected DeviceColorSpace(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {super(baseObject,container);}
+  // </constructors>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/colorSpaces/DeviceGrayColor.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/colorSpaces/DeviceGrayColor.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/colorSpaces/DeviceGrayColor.java	(revision 23703)
@@ -0,0 +1,88 @@
+/*
+  Copyright 2006-2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.colorSpaces;
+
+/**
+  Device Gray color value [PDF:1.6:4.5.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.4
+*/
+public class DeviceGrayColor
+  extends DeviceColor
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final DeviceGrayColor Black = new DeviceGrayColor(0);
+  public static final DeviceGrayColor White = new DeviceGrayColor(1);
+
+  public static final DeviceGrayColor Default = Black;
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <fields>
+  private double intensity;
+  // </fields>
+
+  // <constructors>
+  public DeviceGrayColor(
+    double intensity
+    )
+  {
+    super(DeviceGrayColorSpace.Default);
+
+    setIntensity(intensity);
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public double[] getComponents(
+    )
+  {return new double[]{intensity};}
+
+  /**
+    Gets the gray component.
+  */
+  public double getIntensity(
+    )
+  {return intensity;}
+
+  /**
+    Sets the gray component.
+  */
+  public void setIntensity(
+    double value
+    )
+  {intensity = normalizeComponent(value);}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/colorSpaces/DeviceGrayColorSpace.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/colorSpaces/DeviceGrayColorSpace.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/colorSpaces/DeviceGrayColorSpace.java	(revision 23703)
@@ -0,0 +1,105 @@
+/*
+  Copyright 2006-2007 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.colorSpaces;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.objects.IPdfNumber;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+/**
+  Device Gray color space [PDF:1.6:4.5.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.4
+*/
+public class DeviceGrayColorSpace
+  extends DeviceColorSpace
+{
+  // <class>
+  // <static>
+  // <fields>
+  /*
+    NOTE: It may be specified directly (i.e. without being defined in the ColorSpace subdictionary
+    of the contextual resource dictionary) [PDF:1.6:4.5.7].
+  */
+  public static final DeviceGrayColorSpace Default = new DeviceGrayColorSpace(null,null);
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  public DeviceGrayColorSpace(
+    Document context
+    )
+  {
+    super(
+      context,
+      PdfName.DeviceGray
+      );
+  }
+
+  DeviceGrayColorSpace(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {
+    super(
+      baseObject,
+      container
+      );
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public DeviceGrayColorSpace clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  @Override
+  public Color getColor(
+    PdfDirectObject[] components
+    )
+  {
+    return new DeviceGrayColor(
+      ((IPdfNumber)components[0]).getNumberValue()
+      );
+  }
+
+  @Override
+  public Color getDefaultColor(
+    )
+  {return DeviceGrayColor.Default;}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/colorSpaces/DeviceRGBColor.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/colorSpaces/DeviceRGBColor.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/colorSpaces/DeviceRGBColor.java	(revision 23703)
@@ -0,0 +1,144 @@
+/*
+  Copyright 2006-2009 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.colorSpaces;
+
+/**
+  Device Red-Green-Blue color value [PDF:1.6:4.5.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+*/
+public class DeviceRGBColor
+  extends DeviceColor
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final DeviceRGBColor Black = new DeviceRGBColor(0,0,0);
+  public static final DeviceRGBColor White = new DeviceRGBColor(1,1,1);
+
+  public static final DeviceRGBColor Default = Black;
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <fields>
+  private double blueComponent;
+  private double greenComponent;
+  private double redComponent;
+  // </fields>
+
+  // <constructors>
+  public DeviceRGBColor(
+    double redComponent,
+    double greenComponent,
+    double blueComponent
+    )
+  {
+    super(DeviceRGBColorSpace.Default);
+
+    setRedComponent(redComponent);
+    setGreenComponent(greenComponent);
+    setBlueComponent(blueComponent);
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public boolean equals(
+    Object object
+    )
+  {
+    if(!(object instanceof DeviceRGBColor))
+      return false;
+
+    DeviceRGBColor other = (DeviceRGBColor)object;
+
+    return other.redComponent == this.redComponent
+      && other.greenComponent == this.greenComponent
+      && other.blueComponent == this.blueComponent;
+  }
+
+  /**
+    Gets the blue component.
+  */
+  public double getBlueComponent(
+    )
+  {return blueComponent;}
+
+  @Override
+  public double[] getComponents(
+    )
+  {return new double[]{redComponent,greenComponent,blueComponent};}
+
+  /**
+    Gets the green component.
+  */
+  public double getGreenComponent(
+    )
+  {return greenComponent;}
+
+  /**
+    Gets the red component.
+  */
+  public double getRedComponent(
+    )
+  {return redComponent;}
+
+  @Override
+  public int hashCode(
+    )
+  {return new Double(redComponent).hashCode() ^ new Double(greenComponent).hashCode() ^ new Double(blueComponent).hashCode();}
+
+  /**
+    Sets the blue component.
+  */
+  public void setBlueComponent(
+    double value
+    )
+  {blueComponent = normalizeComponent(value);}
+
+  /**
+    Sets the green component.
+  */
+  public void setGreenComponent(
+    double value
+    )
+  {greenComponent = normalizeComponent(value);}
+
+  /**
+    Sets the red component.
+  */
+  public void setRedComponent(
+    double value
+    )
+  {redComponent = normalizeComponent(value);}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/colorSpaces/DeviceRGBColorSpace.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/colorSpaces/DeviceRGBColorSpace.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/colorSpaces/DeviceRGBColorSpace.java	(revision 23703)
@@ -0,0 +1,107 @@
+/*
+  Copyright 2006-2007 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.colorSpaces;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.objects.IPdfNumber;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+/**
+  Device Red-Green-Blue color space [PDF:1.6:4.5.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.4
+*/
+public class DeviceRGBColorSpace
+  extends DeviceColorSpace
+{
+  // <class>
+  // <static>
+  // <fields>
+  /*
+    NOTE: It may be specified directly (i.e. without being defined in the ColorSpace subdictionary
+    of the contextual resource dictionary) [PDF:1.6:4.5.7].
+  */
+  public static final DeviceRGBColorSpace Default = new DeviceRGBColorSpace(null,null);
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  public DeviceRGBColorSpace(
+    Document context
+    )
+  {
+    super(
+      context,
+      PdfName.DeviceRGB
+      );
+  }
+
+  DeviceRGBColorSpace(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {
+    super(
+      baseObject,
+      container
+      );
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public DeviceRGBColorSpace clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  @Override
+  public Color getColor(
+    PdfDirectObject[] components
+    )
+  {
+    return new DeviceRGBColor(
+      ((IPdfNumber)components[0]).getNumberValue(),
+      ((IPdfNumber)components[1]).getNumberValue(),
+      ((IPdfNumber)components[2]).getNumberValue()
+      );
+  }
+
+  @Override
+  public Color getDefaultColor(
+    )
+  {return DeviceRGBColor.Default;}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/colorSpaces/ICCBasedColorSpace.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/colorSpaces/ICCBasedColorSpace.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/colorSpaces/ICCBasedColorSpace.java	(revision 23703)
@@ -0,0 +1,89 @@
+/*
+  Copyright 2006-2007 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.colorSpaces;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.files.File;
+import it.stefanochizzolini.clown.objects.PdfArray;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfStream;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+/**
+  ICC-based color space [PDF:1.6:4.5.4].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.4
+*/
+// TODO:IMPL improve profile support (see ICC.1:2003-09 spec)!!!
+public class ICCBasedColorSpace
+  extends ColorSpace
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+// TODO:IMPL!!!
+//     protected ICCBasedColorSpace(
+//       Document context,
+//       PdfArray baseDataObject
+//       )
+//     {super(context,baseDataObject);}
+
+  ICCBasedColorSpace(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {super(baseObject,container);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public ICCBasedColorSpace clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+//TODO:IMPL
+  @Override
+  public Color getColor(
+    PdfDirectObject[] components
+    )
+  {return null;}
+//TODO:IMPL
+  @Override
+  public Color getDefaultColor(
+    )
+  {return null;}
+
+  public PdfStream getProfile(
+    )
+  {return (PdfStream)File.resolve(((PdfArray)getBaseDataObject()).get(1));}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/colorSpaces/LabColorSpace.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/colorSpaces/LabColorSpace.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/colorSpaces/LabColorSpace.java	(revision 23703)
@@ -0,0 +1,83 @@
+/*
+  Copyright 2006-2007 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.colorSpaces;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+/**
+  CIE-based ABC double-transformation-stage color space (A, B, and C
+  represent the L*, a*, and b* components of a CIE 1976 L*a*b* space)
+  [PDF:1.6:4.5.4].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.4
+*/
+public class LabColorSpace
+  extends CIEBasedColorSpace
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+// TODO:IMPL!!!
+//     protected LabColorSpace(
+//       Document context,
+//       PdfArray baseDataObject
+//       )
+//     {super(context,baseDataObject);}
+
+  LabColorSpace(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {super(baseObject,container);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public LabColorSpace clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+//TODO:IMPL
+  @Override
+  public Color getColor(
+    PdfDirectObject[] components
+    )
+  {return null;}
+//TODO:IMPL
+  @Override
+  public Color getDefaultColor(
+    )
+  {return null;}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/colorSpaces/package.html
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/colorSpaces/package.html	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/colorSpaces/package.html	(revision 23703)
@@ -0,0 +1,37 @@
+<html>
+<head>
+<!--
+  Copyright 2006-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+-->
+</head>
+<body>
+<p>Color space types used to specify the colors of graphics objects inside content streams [PDF:1.6:4.5].</p>
+
+<h2>Related Documentation</h2>
+<p>For overviews, tutorials, examples, guides, and tool documentation, please see:</p>
+<ul>
+  <li><a href="http://clown.stefanochizzolini.it">PDF Clown Home Page</a>
+</ul>
+</body>
+</html>
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/composition/AlignmentXEnum.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/composition/AlignmentXEnum.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/composition/AlignmentXEnum.java	(revision 23703)
@@ -0,0 +1,39 @@
+/*
+  Copyright 2006 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.composition;
+
+/**
+  Horizontal alignment.
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+*/
+public enum AlignmentXEnum
+{
+  Left,
+  Right,
+  Center,
+  Justify
+};
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/composition/AlignmentYEnum.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/composition/AlignmentYEnum.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/composition/AlignmentYEnum.java	(revision 23703)
@@ -0,0 +1,38 @@
+/*
+  Copyright 2006-2007 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.composition;
+
+/**
+  Vertical alignment.
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+*/
+public enum AlignmentYEnum
+{
+  Top,
+  Bottom,
+  Middle
+};
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/composition/BlockFilter.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/composition/BlockFilter.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/composition/BlockFilter.java	(revision 23703)
@@ -0,0 +1,654 @@
+/*
+  Copyright 2007-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.composition;
+
+import it.stefanochizzolini.clown.bytes.IOutputStream;
+import it.stefanochizzolini.clown.documents.contents.ContentScanner;
+import it.stefanochizzolini.clown.documents.contents.fonts.Font;
+import it.stefanochizzolini.clown.documents.contents.objects.ContainerObject;
+import it.stefanochizzolini.clown.documents.contents.objects.ContentObject;
+import it.stefanochizzolini.clown.documents.contents.objects.LocalGraphicsState;
+import it.stefanochizzolini.clown.documents.contents.objects.ModifyCTM;
+import it.stefanochizzolini.clown.documents.contents.objects.Operation;
+import it.stefanochizzolini.clown.documents.contents.objects.SetWordSpace;
+
+import java.awt.geom.Dimension2D;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+  Content block filter.
+  <p>It provides content positioning functionalities for page typesetting.</p>
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+  @since 0.0.3
+*/
+/*
+  TODO: Manage all the graphics parameters (especially
+  those text-related, like horizontal scaling etc.) using ContentScanner -- see PDF:1.6:5.2-3!!!
+*/
+public final class BlockFilter
+{
+  // <class>
+  // <classes>
+  private static final class ContentPlaceholder
+    extends Operation
+  {
+    public List<ContentObject> objects = new ArrayList<ContentObject>(2);
+
+    public ContentPlaceholder(
+      )
+    {super(null);}
+
+    @SuppressWarnings("unused")
+    public List<ContentObject> getObjects(
+      )
+    {return objects;}
+
+    @Override
+    public void writeTo(
+      IOutputStream stream
+      )
+    {
+      for(ContentObject object : objects)
+      {object.writeTo(stream);}
+    }
+  }
+
+  private static final class Row
+  {
+    /**
+      Row's objects.
+    */
+    public ArrayList<RowObject> objects = new ArrayList<RowObject>();
+    /**
+      Number of space characters.
+    */
+    public int spaceCount = 0;
+    /**
+      Row's graphics objects container.
+    */
+    @SuppressWarnings("unused")
+    public ContentPlaceholder container;
+
+    public double height;
+    /**
+      Vertical location relative to the block frame.
+    */
+    public double y;
+    public double width;
+
+    Row(
+      ContentPlaceholder container,
+      double y
+      )
+    {
+      this.container = container;
+      this.y = y;
+    }
+  }
+
+  private static final class RowObject
+  {
+    /**
+      Row object's graphics objects container.
+    */
+    public ContainerObject container;
+
+    public double height;
+    @SuppressWarnings("unused")
+    public double width;
+
+    public int spaceCount;
+
+    RowObject(
+      ContainerObject container,
+      double height,
+      double width,
+      int spaceCount
+      )
+    {
+      this.container = container;
+      this.height = height;
+      this.width = width;
+      this.spaceCount = spaceCount;
+    }
+  }
+  // </classes>
+
+  // <dynamic>
+  /*
+    NOTE: In order to provide fine-grained alignment,
+    there are 2 postproduction state levels:
+      1- row level (see endRow());
+      2- block level (see end()).
+
+    NOTE: Graphics instructions' layout follows this scheme (XS-BNF syntax):
+      block = { beginLocalState translation parameters rows endLocalState }
+      beginLocalState { "q\r" }
+      translation = { "1 0 0 1 " number ' ' number "cm\r" }
+      parameters = { ... } // Graphics state parameters.
+      rows = { row* }
+      row = { object* }
+      object = { parameters beginLocalState translation content endLocalState }
+      content = { ... } // Text, image (and so on) showing operators.
+      endLocalState = { "Q\r" }
+    NOTE: all the graphics state parameters within a block are block-level or row-object ones,
+    i.e. they can't be represented inside row's local state, in order to allow parameter reuse
+    within the same block.
+  */
+  // <fields>
+  private PrimitiveFilter context;
+  private ContentScanner scanner;
+
+  private AlignmentXEnum alignmentX;
+  private AlignmentYEnum alignmentY;
+  private boolean hyphenation;
+
+  /** Available area where to render the block contents inside. */
+  private Rectangle2D frame;
+  /** Actual area occupied by the block contents. */
+  private Rectangle2D.Double boundBox;
+
+  private Row currentRow;
+  private boolean rowEnded;
+
+  private LocalGraphicsState container;
+  // </fields>
+
+  // <constructors>
+  public BlockFilter(
+    PrimitiveFilter context
+    )
+  {
+    this.context = context;
+
+    this.scanner = context.getScanner();
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  /**
+    Begins a content block.
+    @param frame Block boundaries.
+    @param alignmentX Horizontal alignment.
+    @param alignmentY Vertical alignment.
+  */
+  public void begin(
+    Rectangle2D frame,
+    AlignmentXEnum alignmentX,
+    AlignmentYEnum alignmentY
+    )
+  {
+    this.frame = frame;
+    this.alignmentX = alignmentX;
+    this.alignmentY = alignmentY;
+
+    // Open the block local state!
+    /*
+      NOTE: This device allows a fine-grained control over the block representation.
+      It MUST be coupled with a closing statement on block end.
+    */
+    container = context.beginLocalState();
+
+    boundBox = new Rectangle2D.Double(
+      frame.getX(),
+      frame.getY(),
+      frame.getWidth(),
+      0
+      );
+
+    beginRow();
+  }
+
+  /**
+    Ends the content block.
+  */
+  public void end(
+    )
+  {
+    // End last row!
+    endRow(true);
+
+    // Block translation.
+    container.getObjects().add(
+      0,
+      new ModifyCTM(
+        1, 0, 0, 1,
+        boundBox.x, // Horizontal translation.
+        -boundBox.y // Vertical translation.
+        )
+      );
+
+    // Close the block local state!
+    context.end();
+  }
+
+  /**
+    Gets the actual area occupied by the block contents.
+  */
+  public Rectangle2D getBoundBox(
+    )
+  {return boundBox;}
+
+  /**
+    Gets the content scanner.
+  */
+  public ContentScanner getScanner(
+    )
+  {return scanner;}
+
+  /**
+    Gets the context of the block filter.
+  */
+  public PrimitiveFilter getContext(
+    )
+  {return context;}
+
+  /**
+    Gets the available area where to render the block contents inside.
+  */
+  public Rectangle2D getFrame(
+    )
+  {return frame;}
+
+  /**
+    Gets whether the hyphenation algorithm has to be applied.
+  */
+  public boolean isHyphenation(
+    )
+  {return hyphenation;}
+
+  /**
+    Sets whether the hyphenation algorithm has to be applied.
+  */
+  public void setHyphenation(
+    boolean value
+    )
+  {hyphenation = value;}
+
+  /**
+    Ends current paragraph.
+  */
+  public void showBreak(
+    )
+  {
+    endRow(true);
+    beginRow();
+  }
+
+  /**
+    Ends current paragraph, specifying the offset of the next one.
+    <h3>Remarks</h3>
+    <p>This functionality allows higher-level features such as paragraph indentation and margin.</p>
+    @param offset Relative location of the next paragraph.
+  */
+  public void showBreak(
+    Dimension2D offset
+    )
+  {
+    showBreak();
+
+    currentRow.y += offset.getHeight();
+    currentRow.width = offset.getWidth();
+  }
+
+  /**
+    Ends current paragraph, specifying the alignment of the next one.
+    <h3>Remarks</h3>
+    <p>This functionality allows higher-level features such as paragraph indentation and margin.</p>
+    @param alignmentX Horizontal alignment.
+  */
+  public void showBreak(
+    AlignmentXEnum alignmentX
+    )
+  {
+    showBreak();
+
+    this.alignmentX = alignmentX;
+  }
+
+  /**
+    Ends current paragraph, specifying the offset and alignment of the next one.
+    <h3>Remarks</h3>
+    <p>This functionality allows higher-level features such as paragraph indentation and margin.</p>
+    @param offset Relative location of the next paragraph.
+    @param alignmentX Horizontal alignment.
+  */
+  public void showBreak(
+    Dimension2D offset,
+    AlignmentXEnum alignmentX
+    )
+  {
+    showBreak(offset);
+
+    this.alignmentX = alignmentX;
+  }
+
+  /**
+    Shows text.
+    @return Last shown character index.
+  */
+  public int showText(
+    String text
+    )
+  {
+    if(currentRow == null
+      || text == null)
+      return 0;
+
+    ContentScanner.GraphicsState state = context.getState();
+    Font font = state.font;
+    double fontSize = state.fontSize;
+    double lineHeight = font.getLineHeight(fontSize);
+
+    TextFitter textFitter = new TextFitter(
+      text,
+      0,
+      font,
+      fontSize,
+      hyphenation
+      );
+    int textLength = text.length();
+    int index = 0;
+
+textShowing:
+    while(true)
+    {
+      // Beginning of current row?
+      if(currentRow.width == 0)
+      {
+        // Removing leading spaces...
+        while(true)
+        {
+          // Did we reach the text end?
+          if(index == textLength)
+            break textShowing;
+
+          if(text.charAt(index) != ' ')
+            break;
+
+          index++;
+        }
+      }
+
+      // Text height: exceeds current row's height?
+      if(lineHeight > currentRow.height)
+      {
+        // Text height: exceeds block's remaining vertical space?
+        if(lineHeight > frame.getHeight() - currentRow.y) // Text exceeds.
+        {
+          // Terminate the current row!
+          endRow(false);
+          break textShowing;
+        }
+        else // Text doesn't exceed.
+        {
+          // Adapt current row's height!
+          currentRow.height = lineHeight;
+        }
+      }
+
+      // Does the text fit?
+      if(textFitter.fit(
+        index,
+        frame.getWidth() - currentRow.width // Remaining row width.
+        ))
+      {
+        // Get the fitting text!
+        String textChunk = textFitter.getFittedText();
+        double textChunkWidth = textFitter.getFittedWidth();
+        Point2D textChunkLocation = new Point2D.Double(
+          currentRow.width,
+          currentRow.y
+          );
+
+        // Render the fitting text:
+        // - open the row object's local state!
+        /*
+          NOTE: This device allows a fine-grained control over the row object's representation.
+          It MUST be coupled with a closing statement on row object's end.
+        */
+        RowObject object = new RowObject(
+          context.beginLocalState(),
+          lineHeight,
+          textChunkWidth,
+          countOccurrence(' ',textChunk)
+          );
+        currentRow.objects.add(object);
+        currentRow.spaceCount += object.spaceCount;
+        // - show the text chunk!
+        context.showText(
+          textChunk,
+          textChunkLocation
+          );
+        // - close the row object's local state!
+        context.end();
+
+        // Update ancillary parameters:
+        // - update row width!
+        currentRow.width += textChunkWidth;
+        // - update cursor position!
+        index = textFitter.getEndIndex();
+      }
+
+      // Evaluating trailing text...
+trailParsing:
+      while(true)
+      {
+        // Did we reach the text end?
+        if(index == textLength)
+          break textShowing;
+
+        switch(text.charAt(index))
+        {
+          case '\r':
+            break;
+          case '\n':
+            // New paragraph!
+            index++;
+            showBreak();
+            break trailParsing;
+          default:
+            // New row (within the same paragraph)!
+            endRow(false); beginRow();
+            break trailParsing;
+        }
+
+        index++;
+      }
+    }
+
+    return index;
+  }
+  // </public>
+
+  // <private>
+  /**
+    Begins a content row.
+  */
+  private void beginRow(
+    )
+  {
+    rowEnded = false;
+
+    currentRow = new Row(
+      (ContentPlaceholder)context.add(new ContentPlaceholder()),
+      boundBox.height
+      );
+  }
+
+  private int countOccurrence(
+    char value,
+    String text
+    )
+  {
+    int count = 0;
+    int fromIndex = 0;
+    do
+    {
+      int foundIndex = text.indexOf(value,fromIndex);
+      if(foundIndex == -1)
+        return count;
+
+      count++;
+
+      fromIndex = foundIndex + 1;
+    }
+    while(true);
+  }
+
+  /**
+    Ends the content row.
+    @param broken Indicates whether this is the end of a paragraph.
+  */
+  private void endRow(
+    boolean broken
+    )
+  {
+    if(rowEnded)
+      return;
+
+    rowEnded = true;
+
+    double objectXOffsets[] = new double[currentRow.objects.size()]; // Horizontal object displacements.
+    double wordSpace = 0; // Exceeding space among words.
+    double rowXOffset = 0; // Horizontal row offset.
+
+    List<RowObject> objects = currentRow.objects;
+
+    // Horizontal alignment.
+    AlignmentXEnum alignmentX = this.alignmentX;
+    switch(alignmentX)
+    {
+      case Left:
+      {break;}
+      case Right:
+        rowXOffset = frame.getWidth() - currentRow.width;
+        break;
+      case Center:
+        rowXOffset = (frame.getWidth() - currentRow.width) / 2;
+        break;
+      case Justify:
+        // Are there NO spaces?
+        if(currentRow.spaceCount == 0
+          || broken) // NO spaces.
+        {
+          /* NOTE: This situation equals a simple left alignment. */
+          alignmentX = AlignmentXEnum.Left;
+        }
+        else // Spaces exist.
+        {
+          // Calculate the exceeding spacing among the words!
+          wordSpace = (frame.getWidth() - currentRow.width) / currentRow.spaceCount;
+          // Define the horizontal offsets for justified alignment.
+          for(
+            int index = 1,
+              count = objects.size();
+            index < count;
+            index++
+            )
+          {
+            /*
+              NOTE: The offset represents the horizontal justification gap inserted
+              at the left side of each object.
+            */
+            objectXOffsets[index] = objectXOffsets[index - 1] + objects.get(index - 1).spaceCount * wordSpace;
+          }
+        }
+        break;
+    }
+
+    SetWordSpace wordSpaceOperation = new SetWordSpace(wordSpace);
+
+    // Vertical alignment and translation.
+    for(
+      int index = objects.size() - 1;
+      index >= 0;
+      index--
+      )
+    {
+      RowObject object = objects.get(index);
+
+      // Vertical alignment.
+      double objectYOffset = 0;
+//TODO:IMPL image support!!!
+//       switch(object.type)
+//       {
+//         case Text:
+          objectYOffset = -(currentRow.height - object.height); // Linebase-anchored vertical alignment.
+//           break;
+//         case Image:
+//           objectYOffset = -(currentRow.height - object.height) / 2; // Centered vertical alignment.
+//           break;
+//       }
+
+      List<ContentObject> containedGraphics = object.container.getObjects();
+      // Word spacing.
+      containedGraphics.add(0,wordSpaceOperation);
+      // Translation.
+      containedGraphics.add(
+        0,
+        new ModifyCTM(
+          1, 0, 0, 1,
+          objectXOffsets[index] + rowXOffset, // Horizontal alignment.
+          objectYOffset // Vertical alignment.
+          )
+        );
+    }
+
+    // Update the actual block height!
+    boundBox.height = currentRow.y + currentRow.height;
+
+    // Update the actual block vertical location!
+    double xOffset;
+    switch(alignmentY)
+    {
+      case Bottom:
+        xOffset = frame.getHeight() - boundBox.height;
+        break;
+      case Middle:
+        xOffset = (frame.getHeight() - boundBox.height) / 2;
+        break;
+      case Top:
+      default:
+        xOffset = 0;
+        break;
+    }
+    boundBox.y = frame.getY() + xOffset;
+
+    // Discard the current row!
+    currentRow = null;
+  }
+  // </private>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/composition/PrimitiveFilter.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/composition/PrimitiveFilter.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/composition/PrimitiveFilter.java	(revision 23703)
@@ -0,0 +1,1764 @@
+/*
+  Copyright 2007-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.composition;
+
+import it.stefanochizzolini.clown.documents.Page;
+import it.stefanochizzolini.clown.documents.contents.ContentScanner;
+import it.stefanochizzolini.clown.documents.contents.FontResources;
+import it.stefanochizzolini.clown.documents.contents.IContentContext;
+import it.stefanochizzolini.clown.documents.contents.LineCapEnum;
+import it.stefanochizzolini.clown.documents.contents.LineJoinEnum;
+import it.stefanochizzolini.clown.documents.contents.Resources;
+import it.stefanochizzolini.clown.documents.contents.TextRenderModeEnum;
+import it.stefanochizzolini.clown.documents.contents.XObjectResources;
+import it.stefanochizzolini.clown.documents.contents.colorSpaces.Color;
+import it.stefanochizzolini.clown.documents.contents.colorSpaces.ColorSpace;
+import it.stefanochizzolini.clown.documents.contents.colorSpaces.DeviceCMYKColorSpace;
+import it.stefanochizzolini.clown.documents.contents.colorSpaces.DeviceGrayColorSpace;
+import it.stefanochizzolini.clown.documents.contents.colorSpaces.DeviceRGBColorSpace;
+import it.stefanochizzolini.clown.documents.contents.fonts.Font;
+import it.stefanochizzolini.clown.documents.contents.objects.BeginMarkedContent;
+import it.stefanochizzolini.clown.documents.contents.objects.BeginSubpath;
+import it.stefanochizzolini.clown.documents.contents.objects.CloseSubpath;
+import it.stefanochizzolini.clown.documents.contents.objects.CompositeObject;
+import it.stefanochizzolini.clown.documents.contents.objects.ContentObject;
+import it.stefanochizzolini.clown.documents.contents.objects.DrawCurve;
+import it.stefanochizzolini.clown.documents.contents.objects.DrawLine;
+import it.stefanochizzolini.clown.documents.contents.objects.DrawRectangle;
+import it.stefanochizzolini.clown.documents.contents.objects.EndPathNoOp;
+import it.stefanochizzolini.clown.documents.contents.objects.Fill;
+import it.stefanochizzolini.clown.documents.contents.objects.FillStroke;
+import it.stefanochizzolini.clown.documents.contents.objects.LocalGraphicsState;
+import it.stefanochizzolini.clown.documents.contents.objects.MarkedContent;
+import it.stefanochizzolini.clown.documents.contents.objects.ModifyCTM;
+import it.stefanochizzolini.clown.documents.contents.objects.ModifyClipPath;
+import it.stefanochizzolini.clown.documents.contents.objects.PaintXObject;
+import it.stefanochizzolini.clown.documents.contents.objects.SetCharSpace;
+import it.stefanochizzolini.clown.documents.contents.objects.SetFillColor;
+import it.stefanochizzolini.clown.documents.contents.objects.SetFillColorSpace;
+import it.stefanochizzolini.clown.documents.contents.objects.SetFont;
+import it.stefanochizzolini.clown.documents.contents.objects.SetLineCap;
+import it.stefanochizzolini.clown.documents.contents.objects.SetLineDash;
+import it.stefanochizzolini.clown.documents.contents.objects.SetLineJoin;
+import it.stefanochizzolini.clown.documents.contents.objects.SetLineWidth;
+import it.stefanochizzolini.clown.documents.contents.objects.SetMiterLimit;
+import it.stefanochizzolini.clown.documents.contents.objects.SetStrokeColor;
+import it.stefanochizzolini.clown.documents.contents.objects.SetStrokeColorSpace;
+import it.stefanochizzolini.clown.documents.contents.objects.SetTextLead;
+import it.stefanochizzolini.clown.documents.contents.objects.SetTextMatrix;
+import it.stefanochizzolini.clown.documents.contents.objects.SetTextRenderMode;
+import it.stefanochizzolini.clown.documents.contents.objects.SetTextRise;
+import it.stefanochizzolini.clown.documents.contents.objects.SetTextScale;
+import it.stefanochizzolini.clown.documents.contents.objects.SetWordSpace;
+import it.stefanochizzolini.clown.documents.contents.objects.ShowSimpleText;
+import it.stefanochizzolini.clown.documents.contents.objects.Stroke;
+import it.stefanochizzolini.clown.documents.contents.objects.Text;
+import it.stefanochizzolini.clown.documents.contents.objects.TranslateTextRelative;
+import it.stefanochizzolini.clown.documents.contents.objects.TranslateTextToNextLine;
+import it.stefanochizzolini.clown.documents.contents.xObjects.XObject;
+import it.stefanochizzolini.clown.documents.interaction.actions.Action;
+import it.stefanochizzolini.clown.documents.interaction.annotations.Link;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.awt.Dimension;
+import java.awt.geom.Dimension2D;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.awt.geom.RectangularShape;
+
+/**
+  Content stream primitive filter.
+  <p>It provides the basic (primitive) operations described by the PDF specification
+  for graphics content composition.</p>
+  <h3>Remarks</h3>
+  <p>This class leverages the object-oriented content stream modelling infrastructure,
+  which encompasses 1st-level content stream objects (operations),
+  2nd-level content stream objects (graphics objects) and full graphics state support.</p>
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.4
+  @version 0.0.8
+*/
+public class PrimitiveFilter
+{
+  // <class>
+  // <dynamic>
+  // <fields>
+  private ContentScanner scanner;
+  // </fields>
+
+  // <constructors>
+  public PrimitiveFilter(
+    ContentScanner scanner
+    )
+  {setScanner(scanner);}
+
+  public PrimitiveFilter(
+    IContentContext context
+    )
+  {
+    this(
+      new ContentScanner(context.getContents())
+      );
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  /**
+    Adds a content object.
+
+    @return The added content object.
+  */
+  public ContentObject add(
+    ContentObject object
+    )
+  {
+    scanner.insert(object);
+    scanner.moveNext();
+
+    return object;
+  }
+
+  /**
+    Applies a transformation to the coordinate system from user space to device space [PDF:1.6:4.3.3].
+    <h3>Remarks</h3>
+    <p>The transformation is applied to the current transformation matrix (CTM) by concatenation,
+    i.e. it doesn't replace it.</p>
+
+    @see #setMatrix(double,double,double,double,double,double)
+
+    @param a Item 0,0 of the matrix.
+    @param b Item 0,1 of the matrix.
+    @param c Item 1,0 of the matrix.
+    @param d Item 1,1 of the matrix.
+    @param e Item 2,0 of the matrix.
+    @param f Item 2,1 of the matrix.
+  */
+  public void applyMatrix(
+    double a,
+    double b,
+    double c,
+    double d,
+    double e,
+    double f
+    )
+  {add(new ModifyCTM(a,b,c,d,e,f));}
+
+  /**
+    Adds a composite object beginning it.
+
+    @see #end()
+
+    @return The added composite object.
+  */
+  public CompositeObject begin(
+    CompositeObject object
+    )
+  {
+    // Insert the new object at the current level!
+    scanner.insert(object);
+    // The new object's children level is the new current level!
+    scanner = scanner.getChildLevel();
+
+    return object;
+  }
+
+  /**
+    Begins a new nested graphics state context [PDF:1.6:4.3.1].
+
+    @see #end()
+
+    @return The added local graphics state object.
+  */
+  public LocalGraphicsState beginLocalState(
+    )
+  {return (LocalGraphicsState)begin(new LocalGraphicsState());}
+
+  /**
+    Begins a new marked-content sequence [PDF:1.6:10.5].
+
+    @see #end()
+
+    @return The added marked-content sequence.
+  */
+  public MarkedContent beginMarkedContent(
+    PdfName tag
+    )
+  {
+    return (MarkedContent)begin(
+      new MarkedContent(
+        new BeginMarkedContent(tag)
+        )
+      );
+  }
+
+  /**
+    Modifies the current clipping path by intersecting it with the current path [PDF:1.6:4.4.1].
+    <h3>Remarks</h3>
+    <p>It can be validly called only just before painting the current path.</p>
+  */
+  public void clip(
+    )
+  {
+    add(ModifyClipPath.Value);
+    add(EndPathNoOp.Value);
+  }
+
+  /**
+    Closes the current subpath by appending a straight line segment
+    from the current point to the starting point of the subpath [PDF:1.6:4.4.1].
+  */
+  public void closePath(
+    )
+  {add(CloseSubpath.Value);}
+
+  /**
+    Draws a circular arc.
+
+    @see #stroke()
+    @since 0.0.7
+
+    @param location Arc location.
+    @param startAngle Starting angle.
+    @param endAngle Ending angle.
+  */
+  public void drawArc(
+    RectangularShape location,
+    double startAngle,
+    double endAngle
+    )
+  {drawArc(location,startAngle,endAngle,0,1);}
+
+  /**
+    Draws an arc.
+
+    @see #stroke()
+    @since 0.0.7
+
+    @param location Arc location.
+    @param startAngle Starting angle.
+    @param endAngle Ending angle.
+    @param branchWidth Distance between the spiral branches. '0' value degrades to a circular arc.
+    @param branchRatio Linear coefficient applied to the branch width. '1' value degrades to a constant branch width.
+  */
+  public void drawArc(
+    RectangularShape location,
+    double startAngle,
+    double endAngle,
+    double branchWidth,
+    double branchRatio
+    )
+  {drawArc(location,startAngle,endAngle,branchWidth,branchRatio,true);}
+
+  /**
+    Draws a cubic Bezier curve from the current point [PDF:1.6:4.4.1].
+
+    @see #stroke()
+    @since 0.0.7
+
+    @param endPoint Ending point.
+    @param startControl Starting control point.
+    @param endControl Ending control point.
+  */
+  public void drawCurve(
+    Point2D endPoint,
+    Point2D startControl,
+    Point2D endControl
+    )
+  {
+    double contextHeight = scanner.getContentContext().getBox().getHeight();
+    add(
+      new DrawCurve(
+        endPoint.getX(),
+        contextHeight - endPoint.getY(),
+        startControl.getX(),
+        contextHeight - startControl.getY(),
+        endControl.getX(),
+        contextHeight - endControl.getY()
+        )
+      );
+  }
+
+  /**
+    Draws a cubic Bezier curve [PDF:1.6:4.4.1].
+
+    @see #stroke()
+    @since 0.0.7
+
+    @param startPoint Starting point.
+    @param endPoint Ending point.
+    @param startControl Starting control point.
+    @param endControl Ending control point.
+  */
+  public void drawCurve(
+    Point2D startPoint,
+    Point2D endPoint,
+    Point2D startControl,
+    Point2D endControl
+    )
+  {
+    beginSubpath(startPoint);
+    drawCurve(endPoint,startControl,endControl);
+  }
+
+  /**
+    Draws an ellipse.
+    @since 0.0.7
+
+    @see #fill()
+    @see #fillStroke()
+    @see #stroke()
+
+    @param location Ellipse location.
+  */
+  public void drawEllipse(
+    RectangularShape location
+    )
+  {drawArc(location,0,360);}
+
+  /**
+    Draws a line from the current point [PDF:1.6:4.4.1].
+
+    @see #stroke()
+    @since 0.0.7
+
+    @param endPoint Ending point.
+  */
+  public void drawLine(
+    Point2D endPoint
+    )
+  {
+    add(
+      new DrawLine(
+        endPoint.getX(),
+        scanner.getContentContext().getBox().getHeight() - endPoint.getY()
+        )
+      );
+  }
+
+  /**
+    Draws a line [PDF:1.6:4.4.1].
+
+    @see #stroke()
+    @since 0.0.7
+
+    @param startPoint Starting point.
+    @param endPoint Ending point.
+  */
+  public void drawLine(
+    Point2D startPoint,
+    Point2D endPoint
+    )
+  {
+    beginSubpath(startPoint);
+    drawLine(endPoint);
+  }
+
+  /**
+    Draws a polygon.
+    <h3>Remarks</h3>
+    <p>A polygon is the same as a multiple line except that it's a closed path.</p>
+
+    @see #fill()
+    @see #fillStroke()
+    @see #stroke()
+    @since 0.0.7
+
+    @param points Points.
+  */
+  public void drawPolygon(
+    Point2D[] points
+    )
+  {
+    drawPolyline(points);
+    closePath();
+  }
+
+  /**
+    Draws a multiple line.
+
+    @see #stroke()
+    @since 0.0.7
+
+    @param points Points.
+  */
+  public void drawPolyline(
+    Point2D[] points
+    )
+  {
+    beginSubpath(points[0]);
+    for(
+      int index = 1,
+        length = points.length;
+      index < length;
+      index++
+      )
+    {drawLine(points[index]);}
+  }
+
+  /**
+    Draws a rectangle [PDF:1.6:4.4.1].
+
+    @see #fill()
+    @see #fillStroke()
+    @see #stroke()
+
+    @param location Rectangle location.
+  */
+  public void drawRectangle(
+    RectangularShape location
+    )
+  {drawRectangle(location,0);}
+
+  /**
+    Draws a rounded rectangle.
+
+    @see #fill()
+    @see #fillStroke()
+    @see #stroke()
+
+    @param location Rectangle location.
+    @param radius Vertex radius, '0' value degrades to squared vertices.
+  */
+  public void drawRectangle(
+    RectangularShape location,
+    double radius
+    )
+  {
+    if(radius == 0)
+    {
+      add(
+        new DrawRectangle(
+          location.getX(),
+          scanner.getContentContext().getBox().getHeight() - location.getY() - location.getHeight(),
+          location.getWidth(),
+          location.getHeight()
+          )
+        );
+    }
+    else
+    {
+      final double endRadians = Math.PI * 2;
+      final double quadrantRadians = Math.PI / 2;
+      double radians = 0;
+      while(radians < endRadians)
+      {
+        double radians2 = radians + quadrantRadians;
+        int sin2 = (int)Math.sin(radians2);
+        int cos2 = (int)Math.cos(radians2);
+        double x1 = 0, x2 = 0, y1 = 0, y2 = 0;
+        double xArc = 0, yArc = 0;
+        if(cos2 == 0)
+        {
+          if(sin2 == 1)
+          {
+            x1 = x2 = location.getX() + location.getWidth();
+            y1 = location.getY() + location.getHeight() - radius;
+            y2 = location.getY() + radius;
+
+            xArc =- radius * 2;
+            yArc =- radius;
+
+            beginSubpath(new Point2D.Double(x1,y1));
+          }
+          else
+          {
+            x1 = x2 = location.getX();
+            y1 = location.getY() + radius;
+            y2 = location.getY() + location.getHeight() - radius;
+
+            yArc =- radius;
+          }
+        }
+        else if(cos2 == 1)
+        {
+          x1 = location.getX() + radius;
+          x2 = location.getX() + location.getWidth() - radius;
+          y1 = y2 = location.getY() + location.getHeight();
+
+          xArc =- radius;
+          yArc =- radius*2;
+        }
+        else if(cos2 == -1)
+        {
+          x1 = location.getX() + location.getWidth() - radius;
+          x2 = location.getX() + radius;
+          y1 = y2 = location.getY();
+
+          xArc=-radius;
+        }
+        drawLine(
+          new Point2D.Double(x2,y2)
+          );
+        drawArc(
+          new Rectangle2D.Double(x2+xArc, y2+yArc, radius*2, radius*2),
+          Math.toDegrees(radians),
+          Math.toDegrees(radians2),
+          0,
+          1,
+          false
+          );
+
+        radians = radians2;
+      }
+    }
+  }
+
+  /**
+    Draws a spiral.
+
+    @see #stroke()
+    @since 0.0.7
+
+    @param center Spiral center.
+    @param startAngle Starting angle.
+    @param endAngle Ending angle.
+    @param branchWidth Distance between the spiral branches.
+    @param branchRatio Linear coefficient applied to the branch width.
+  */
+  public void drawSpiral(
+    Point2D center,
+    double startAngle,
+    double endAngle,
+    double branchWidth,
+    double branchRatio
+    )
+  {
+    drawArc(
+      new Rectangle2D.Double(center.getX(),center.getY(),0.0001,0.0001),
+      startAngle,
+      endAngle,
+      branchWidth,
+      branchRatio
+      );
+  }
+
+  /**
+    Ends the current (innermostly-nested) composite object.
+
+    @see #begin(CompositeObject)
+  */
+  public void end(
+    )
+  {
+    scanner = scanner.getParentLevel();
+    scanner.moveNext();
+  }
+
+  /**
+    Fills the path using the current color [PDF:1.6:4.4.2].
+
+    @see #setFillColor(Color)
+  */
+  public void fill(
+    )
+  {add(Fill.Value);}
+
+  /**
+    Fills and then strokes the path using the current colors [PDF:1.6:4.4.2].
+
+    @see #setFillColor(Color)
+    @see #setStrokeColor(Color)
+  */
+  public void fillStroke(
+    )
+  {add(FillStroke.Value);}
+
+  /**
+    Serializes the contents into the content stream.
+  */
+  public void flush(
+    )
+  {scanner.getContents().flush();}
+
+  /**
+    Gets the content stream scanner.
+  */
+  public ContentScanner getScanner(
+    )
+  {return scanner;}
+
+  /**
+    Gets the current graphics state [PDF:1.6:4.3].
+  */
+  public ContentScanner.GraphicsState getState(
+    )
+  {return scanner.getState();}
+
+  /**
+    Applies a rotation to the coordinate system from user space to device space [PDF:1.6:4.2.2].
+
+    @see #applyMatrix(double,double,double,double,double,double)
+
+    @param angle Rotational counterclockwise angle.
+  */
+  public void rotate(
+    double angle
+    )
+  {
+    double rad = angle * Math.PI / 180;
+    double cos = Math.cos(rad);
+    double sin = Math.sin(rad);
+
+    applyMatrix(cos, sin, -sin, cos, 0, 0);
+  }
+
+  /**
+    Applies a rotation to the coordinate system from user space to device space [PDF:1.6:4.2.2].
+
+    @see #applyMatrix(double,double,double,double,double,double)
+
+    @param angle Rotational counterclockwise angle.
+    @param origin Rotational pivot point; it becomes the new coordinates origin.
+  */
+  public void rotate(
+    double angle,
+    Point2D origin
+    )
+  {
+    // Center to the new origin!
+    translate(
+      origin.getX(),
+      scanner.getContentContext().getBox().getHeight() - origin.getY()
+      );
+    // Rotate on the new origin!
+    rotate(angle);
+    // Restore the standard vertical coordinates system!
+    translate(
+      0,
+      -scanner.getContentContext().getBox().getHeight()
+      );
+  }
+
+  /**
+    Applies a scaling to the coordinate system from user space to device space [PDF:1.6:4.2.2].
+
+    @see #applyMatrix(double,double,double,double,double,double)
+
+    @param ratioX Horizontal scaling ratio.
+    @param ratioY Vertical scaling ratio.
+  */
+  public void scale(
+    double ratioX,
+    double ratioY
+    )
+  {applyMatrix(ratioX, 0, 0, ratioY, 0, 0);}
+
+  /**
+    Sets the character spacing parameter [PDF:1.6:5.2.1].
+  */
+  public void setCharSpace(
+    double value
+    )
+  {add(new SetCharSpace(value));}
+
+  /**
+    Sets the nonstroking color value [PDF:1.6:4.5.7].
+
+    @see #setStrokeColor(Color)
+  */
+  public void setFillColor(
+    Color value
+    )
+  {
+    if(scanner.getState().fillColorSpace != value.getColorSpace())
+    {
+      // Set filling color space!
+      add(
+        new SetFillColorSpace(
+          getColorSpaceName(
+            value.getColorSpace()
+            )
+          )
+        );
+    }
+
+    add(new SetFillColor(value));
+  }
+
+  /**
+    Sets the font [PDF:1.6:5.2].
+
+    @param name Resource identifier of the font.
+    @param size Scaling factor (points).
+  */
+  public void setFont(
+    PdfName name,
+    double size
+    )
+  {
+    // Doesn't the font exist in the context resources?
+    if(!scanner.getContentContext().getResources().getFonts().containsKey(name))
+      throw new IllegalArgumentException("No font resource associated to the given argument (name:'name'; value:'" + name + "';)");
+
+    add(new SetFont(name,size));
+  }
+
+  /**
+    Sets the font [PDF:1.6:5.2].
+    <h3>Remarks</h3>
+    <p>The <code>value</code> is checked for presence in the current resource
+    dictionary: if it isn't available, it's automatically added. If you need to
+    avoid such a behavior, use {@link #setFont(PdfName,double) setFont(PdfName,double)}.</p>
+
+    @param value Font.
+    @param size Scaling factor (points).
+  */
+  public void setFont(
+    Font value,
+    double size
+    )
+  {setFont(getFontName(value),size);}
+
+  /**
+    Sets the text horizontal scaling [PDF:1.6:5.2.3].
+  */
+  public void setTextScale(
+    double value
+    )
+  {add(new SetTextScale(value));}
+
+  /**
+    Sets the text leading [PDF:1.6:5.2.4].
+  */
+  public void setTextLead(
+    double value
+    )
+  {add(new SetTextLead(value));}
+
+  /**
+    Sets the line cap style [PDF:1.6:4.3.2].
+  */
+  public void setLineCap(
+    LineCapEnum value
+    )
+  {add(new SetLineCap(value));}
+
+  /**
+    Sets the line dash pattern [PDF:1.6:4.3.2].
+
+    @param phase Distance into the dash pattern at which to start the dash.
+    @param unitsOn Length of evenly alternating dashes and gaps.
+  */
+  public void setLineDash(
+    int phase,
+    int unitsOn
+    )
+  {setLineDash(phase,unitsOn,unitsOn);}
+
+  /**
+    Sets the line dash pattern [PDF:1.6:4.3.2].
+
+    @param phase Distance into the dash pattern at which to start the dash.
+    @param unitsOn Length of dashes.
+    @param unitsOff Length of gaps.
+  */
+  public void setLineDash(
+    int phase,
+    int unitsOn,
+    int unitsOff
+    )
+  {add(new SetLineDash(phase,unitsOn,unitsOff));}
+
+  /**
+    Sets the line join style [PDF:1.6:4.3.2].
+  */
+  public void setLineJoin(
+    LineJoinEnum value
+    )
+  {add(new SetLineJoin(value));}
+
+  /**
+    Sets the line width [PDF:1.6:4.3.2].
+  */
+  public void setLineWidth(
+    double value
+    )
+  {add(new SetLineWidth(value));}
+
+  /**
+    Sets the transformation of the coordinate system from user space to device space [PDF:1.6:4.3.3].
+    <h3>Remarks</h3>
+    <p>The transformation replaces the current transformation matrix (CTM).</p>
+
+    @see #applyMatrix(double,double,double,double,double,double)
+
+    @param a Item 0,0 of the matrix.
+    @param b Item 0,1 of the matrix.
+    @param c Item 1,0 of the matrix.
+    @param d Item 1,1 of the matrix.
+    @param e Item 2,0 of the matrix.
+    @param f Item 2,1 of the matrix.
+  */
+  public void setMatrix(
+    double a,
+    double b,
+    double c,
+    double d,
+    double e,
+    double f
+    )
+  {
+    // Reset the CTM!
+    add(
+      ModifyCTM.getResetCTM(
+        scanner.getState().ctm
+        )
+      );
+    // Apply the transformation!
+    add(new ModifyCTM(a,b,c,d,e,f));
+  }
+
+  /**
+    Sets the miter limit [PDF:1.6:4.3.2].
+  */
+  public void setMiterLimit(
+    double value
+    )
+  {add(new SetMiterLimit(value));}
+
+  /**
+    @see #getScanner()
+  */
+  public void setScanner(
+    ContentScanner value
+    )
+  {scanner = value;}
+
+  /**
+    Sets the stroking color value [PDF:1.6:4.5.7].
+
+    @see #setFillColor(Color)
+  */
+  public void setStrokeColor(
+    Color value
+    )
+  {
+    if(scanner.getState().strokeColorSpace != value.getColorSpace())
+    {
+      // Set stroking color space!
+      add(
+        new SetStrokeColorSpace(
+          getColorSpaceName(
+            value.getColorSpace()
+            )
+          )
+        );
+    }
+
+    add(new SetStrokeColor(value));
+  }
+
+  /**
+    Sets the text rendering mode [PDF:1.6:5.2.5].
+  */
+  public void setTextRenderMode(
+    TextRenderModeEnum value
+    )
+  {add(new SetTextRenderMode(value));}
+
+  /**
+    Sets the text rise [PDF:1.6:5.2.6].
+  */
+  public void setTextRise(
+    double value
+    )
+  {add(new SetTextRise(value));}
+
+  /**
+    Sets the word spacing [PDF:1.6:5.2.2].
+  */
+  public void setWordSpace(
+    double value
+    )
+  {add(new SetWordSpace(value));}
+
+  /**
+    Shows the specified text on the page at the current location [PDF:1.6:5.3.2].
+
+    @param value Text to show.
+    @return Bounding box vertices in default user space units.
+  */
+  public Point2D[] showText(
+    String value
+    )
+  {
+    return showText(
+      value,
+      new Point2D.Double(0,0)
+      );
+  }
+
+  /**
+    Shows the link associated to the specified text on the page at the current location.
+
+    @since 0.0.7
+
+    @param value Text to show.
+    @param action Action to apply when the link is activated.
+    @return Link.
+  */
+  public Link showText(
+    String value,
+    Action action
+    )
+  {
+    return showText(
+      value,
+      new Point2D.Double(0,0),
+      action
+      );
+  }
+
+  /**
+    Shows the specified text on the page at the specified location [PDF:1.6:5.3.2].
+
+    @param value Text to show.
+    @param location Position at which showing the text.
+    @return Bounding box vertices in default user space units.
+  */
+  public Point2D[] showText(
+    String value,
+    Point2D location
+    )
+  {
+    return showText(
+      value,
+      location,
+      AlignmentXEnum.Left,
+      AlignmentYEnum.Top,
+      0
+      );
+  }
+
+  /**
+    Shows the link associated to the specified text on the page at the specified location.
+
+    @since 0.0.7
+
+    @param value Text to show.
+    @param location Position at which showing the text.
+    @param action Action to apply when the link is activated.
+    @return Link.
+  */
+  public Link showText(
+    String value,
+    Point2D location,
+    Action action
+    )
+  {
+    return showText(
+      value,
+      location,
+      AlignmentXEnum.Left,
+      AlignmentYEnum.Top,
+      0,
+      action
+      );
+  }
+
+  /**
+    Shows the specified text on the page at the specified location [PDF:1.6:5.3.2].
+
+    @param value Text to show.
+    @param location Anchor position at which showing the text.
+    @param alignmentX Horizontal alignment.
+    @param alignmentY Vertical alignment.
+    @param rotation Rotational counterclockwise angle.
+    @return Bounding box vertices in default user space units.
+  */
+  public Point2D[] showText(
+    String value,
+    Point2D location,
+    AlignmentXEnum alignmentX,
+    AlignmentYEnum alignmentY,
+    double rotation
+    )
+  {
+    ContentScanner.GraphicsState state = scanner.getState();
+    Font font = state.font;
+    double fontSize = state.fontSize;
+    double x = location.getX();
+    double y = location.getY();
+    double width = font.getKernedWidth(value,fontSize);
+    double height = font.getLineHeight(fontSize);
+    double descent = font.getDescent(fontSize);
+
+    Point2D[] frame = new Point2D[4];
+
+    if(alignmentX == AlignmentXEnum.Left
+      && alignmentY == AlignmentYEnum.Top)
+    {
+      beginText();
+      try
+      {
+        if(rotation == 0)
+        {
+          translateText(
+            x,
+            scanner.getContentContext().getBox().getHeight() - y - font.getAscent(fontSize)
+            );
+        }
+        else
+        {
+          double rad = rotation * Math.PI / 180.0;
+          double cos = Math.cos(rad);
+          double sin = Math.sin(rad);
+
+          setTextMatrix(
+            cos,
+            sin,
+            -sin,
+            cos,
+            x,
+            scanner.getContentContext().getBox().getHeight() - y - font.getAscent(fontSize)
+            );
+        }
+
+        state = scanner.getState();
+        frame[0] = state.textToDeviceSpace(new Point2D.Double(0,descent));
+        frame[1] = state.textToDeviceSpace(new Point2D.Double(width,descent));
+        frame[2] = state.textToDeviceSpace(new Point2D.Double(width,height+descent));
+        frame[3] = state.textToDeviceSpace(new Point2D.Double(0,height+descent));
+
+        // Add the text!
+        add(new ShowSimpleText(font.encode(value)));
+      }
+      catch(Exception e)
+      {throw new RuntimeException("Failed to show text.", e);}
+      finally
+      {end(); /* Ends the text object. */}
+    }
+    else
+    {
+      beginLocalState();
+      try
+      {
+        // Coordinates transformation.
+        double cos, sin;
+        if(rotation == 0)
+        {
+          cos = 1;
+          sin = 0;
+        }
+        else
+        {
+          double rad = rotation * Math.PI / 180.0;
+          cos = Math.cos(rad);
+          sin = Math.sin(rad);
+        }
+        // Apply the transformation!
+        applyMatrix(
+          cos,
+          sin,
+          -sin,
+          cos,
+          x,
+          scanner.getContentContext().getBox().getHeight() - y
+          );
+
+        beginText();
+        try
+        {
+          // Text coordinates adjustment.
+          switch(alignmentX)
+          {
+            case Left:
+              x = 0;
+              break;
+            case Right:
+              x = -width;
+              break;
+            case Center:
+            case Justify:
+              x = -width / 2;
+              break;
+          }
+          switch(alignmentY)
+          {
+            case Top:
+              y = -font.getAscent(fontSize);
+              break;
+            case Bottom:
+              y = height - font.getAscent(fontSize);
+              break;
+            case Middle:
+              y = height / 2 - font.getAscent(fontSize);
+              break;
+          }
+          // Apply the text coordinates adjustment!
+          translateText(x,y);
+
+          state = scanner.getState();
+          frame[0] = state.textToDeviceSpace(new Point2D.Double(0,descent));
+          frame[1] = state.textToDeviceSpace(new Point2D.Double(width,descent));
+          frame[2] = state.textToDeviceSpace(new Point2D.Double(width,height+descent));
+          frame[3] = state.textToDeviceSpace(new Point2D.Double(0,height+descent));
+
+          // Add the text!
+          add(new ShowSimpleText(font.encode(value)));
+        }
+        catch(Exception e)
+        {throw new RuntimeException("Failed to show text.", e);}
+        finally
+        {end(); /* Ends the text object. */}
+      }
+      catch(Exception e)
+      {throw new RuntimeException("Failed to show text.", e);}
+      finally
+      {end(); /* Ends the local state. */}
+    }
+
+    return frame;
+  }
+
+  /**
+    Shows the link associated to the specified text on the page at the specified location.
+
+    @since 0.0.7
+
+    @param value Text to show.
+    @param location Anchor position at which showing the text.
+    @param alignmentX Horizontal alignment.
+    @param alignmentY Vertical alignment.
+    @param rotation Rotational counterclockwise angle.
+    @param action Action to apply when the link is activated.
+    @return Link.
+  */
+  public Link showText(
+    String value,
+    Point2D location,
+    AlignmentXEnum alignmentX,
+    AlignmentYEnum alignmentY,
+    double rotation,
+    Action action
+    )
+  {
+    Point2D[] textFrame = showText(
+      value,
+      location,
+      alignmentX,
+      alignmentY,
+      rotation
+      );
+
+    IContentContext contentContext = scanner.getContentContext();
+    if(!(contentContext instanceof Page))
+      throw new RuntimeException("Link can be shown only on page contexts.");
+
+    Page page = (Page)contentContext;
+    Rectangle2D linkBox = new Rectangle2D.Double(textFrame[0].getX(),textFrame[0].getY(),0,0);
+    for(
+      int index = 1,
+        length = textFrame.length;
+      index < length;
+      index++
+      )
+    {linkBox.add(textFrame[index]);}
+
+    return new Link(
+      page,
+      linkBox,
+      action
+      );
+  }
+
+  /**
+    Shows the specified external object [PDF:1.6:4.7].
+
+    @param name Resource identifier of the external object.
+  */
+  public void showXObject(
+    PdfName name
+    )
+  {add(new PaintXObject(name));}
+
+  /**
+    Shows the specified external object [PDF:1.6:4.7].
+    <h3>Remarks</h3>
+    <p>The <code>value</code> is checked for presence in the current resource
+    dictionary: if it isn't available, it's automatically added. If you need to
+    avoid such a behavior, use {@link #showXObject(PdfName) #showXObject(PdfName)}.</p>
+
+    @since 0.0.5
+
+    @param value External object.
+  */
+  public void showXObject(
+    XObject value
+    )
+  {showXObject(getXObjectName(value));}
+
+  /**
+    Shows the specified external object at the specified position [PDF:1.6:4.7].
+
+    @param name Resource identifier of the external object.
+    @param location Position at which showing the external object.
+  */
+  public void showXObject(
+    PdfName name,
+    Point2D location
+    )
+  {
+    showXObject(
+      name,
+      location,
+      new Dimension(0,0)
+      );
+  }
+
+  /**
+    Shows the specified external object at the specified position [PDF:1.6:4.7].
+    <h3>Remarks</h3>
+    <p>The <code>value</code> is checked for presence in the current resource
+    dictionary: if it isn't available, it's automatically added. If you need to
+    avoid such a behavior, use {@link #showXObject(PdfName,Point2D) #showXObject(PdfName,Point2D)}.</p>
+
+    @since 0.0.5
+
+    @param value External object.
+    @param location Position at which showing the external object.
+  */
+  public void showXObject(
+    XObject value,
+    Point2D location
+    )
+  {
+    showXObject(
+      getXObjectName(value),
+      location
+      );
+  }
+
+  /**
+    Shows the specified external object at the specified position [PDF:1.6:4.7].
+
+    @since 0.0.5
+
+    @param name Resource identifier of the external object.
+    @param location Position at which showing the external object.
+    @param size Size of the external object.
+  */
+  public void showXObject(
+    PdfName name,
+    Point2D location,
+    Dimension2D size
+    )
+  {
+    showXObject(
+      name,
+      location,
+      size,
+      AlignmentXEnum.Left,
+      AlignmentYEnum.Top,
+      0
+      );
+  }
+
+  /**
+    Shows the specified external object at the specified position [PDF:1.6:4.7].
+    <h3>Remarks</h3>
+    <p>The <code>value</code> is checked for presence in the current resource
+    dictionary: if it isn't available, it's automatically added. If you need to
+    avoid such a behavior, use {@link #showXObject(PdfName,Point2D,Dimension2D) #showXObject(PdfName,Point2D,Dimension2D)}.</p>
+
+    @since 0.0.5
+
+    @param value External object.
+    @param location Position at which showing the external object.
+    @param size Size of the external object.
+  */
+  public void showXObject(
+    XObject value,
+    Point2D location,
+    Dimension2D size
+    )
+  {
+    showXObject(
+      getXObjectName(value),
+      location,
+      size
+      );
+  }
+
+  /**
+    Shows the specified external object at the specified position [PDF:1.6:4.7].
+
+    @param name Resource identifier of the external object.
+    @param location Position at which showing the external object.
+    @param size Size of the external object.
+    @param alignmentX Horizontal alignment.
+    @param alignmentY Vertical alignment.
+    @param rotation Rotational counterclockwise angle.
+  */
+  public void showXObject(
+    PdfName name,
+    Point2D location,
+    Dimension2D size,
+    AlignmentXEnum alignmentX,
+    AlignmentYEnum alignmentY,
+    double rotation
+    )
+  {
+    XObject xObject = scanner.getContentContext().getResources().getXObjects().get(name);
+
+    // Adjusting default dimensions...
+    /*
+      NOTE: Zero-valued dimensions represent default proportional dimensions.
+    */
+    Dimension2D xObjectSize = xObject.getSize();
+    if(size.getWidth() == 0)
+    {
+      if(size.getHeight() == 0)
+      {size.setSize(xObjectSize);}
+      else
+      {size.setSize(size.getHeight() * xObjectSize.getWidth() / xObjectSize.getHeight(),size.getHeight());}
+    }
+    else if(size.getHeight() == 0)
+    {size.setSize(size.getWidth(),size.getWidth() * xObjectSize.getHeight() / xObjectSize.getWidth());}
+
+    // Scaling.
+    double[] matrix = xObject.getMatrix();
+    double scaleX, scaleY;
+    scaleX = size.getWidth() / (xObjectSize.getWidth() * matrix[0]);
+    scaleY = size.getHeight() / (xObjectSize.getHeight() * matrix[3]);
+
+    // Alignment.
+    double locationOffsetX, locationOffsetY;
+    switch(alignmentX)
+    {
+      case Left: locationOffsetX = 0; break;
+      case Right: locationOffsetX = size.getWidth(); break;
+      case Center:
+      case Justify:
+      default: locationOffsetX = size.getWidth() / 2; break;
+    }
+    switch(alignmentY)
+    {
+      case Top: locationOffsetY = size.getHeight(); break;
+      case Bottom: locationOffsetY = 0; break;
+      case Middle:
+      default: locationOffsetY = size.getHeight() / 2; break;
+    }
+
+    beginLocalState();
+    try
+    {
+      translate(
+        location.getX(),
+        scanner.getContentContext().getBox().getHeight() - location.getY()
+        );
+      if(rotation != 0)
+      {rotate(rotation);}
+      applyMatrix(
+        scaleX, 0, 0,
+        scaleY,
+        -locationOffsetX,
+        -locationOffsetY
+        );
+      showXObject(name);
+    }
+    catch (Exception e)
+    {throw new RuntimeException("Failed to show the xobject.",e);}
+    finally
+    {end(); /* Ends the local state. */}
+  }
+
+  /**
+    Shows the specified external object at the specified position [PDF:1.6:4.7].
+    <h3>Remarks</h3>
+    <p>The <code>value</code> is checked for presence in the current resource
+    dictionary: if it isn't available, it's automatically added. If you need to
+    avoid such a behavior, use {@link #showXObject(PdfName,Point2D,Dimension2D,AlignmentXEnum,AlignmentYEnum,double) #showXObject(PdfName,Point2D,Dimension2D,AlignmentXEnum,AlignmentYEnum,double)}.</p>
+
+    @since 0.0.5
+
+    @param value External object.
+    @param location Position at which showing the external object.
+    @param size Size of the external object.
+    @param alignmentX Horizontal alignment.
+    @param alignmentY Vertical alignment.
+    @param rotation Rotational counterclockwise angle.
+  */
+  public void showXObject(
+    XObject value,
+    Point2D location,
+    Dimension2D size,
+    AlignmentXEnum alignmentX,
+    AlignmentYEnum alignmentY,
+    double rotation
+    )
+  {
+    showXObject(
+      getXObjectName(value),
+      location,
+      size,
+      alignmentX,
+      alignmentY,
+      rotation
+      );
+  }
+
+  /**
+    Strokes the path using the current color [PDF:1.6:4.4.2].
+
+    @see #setStrokeColor(Color)
+  */
+  public void stroke(
+    )
+  {add(Stroke.Value);}
+
+  /**
+    Applies a translation to the coordinate system from user space
+    to device space [PDF:1.6:4.2.2].
+
+    @see #applyMatrix(double,double,double,double,double,double)
+
+    @param distanceX Horizontal distance.
+    @param distanceY Vertical distance.
+  */
+  public void translate(
+    double distanceX,
+    double distanceY
+    )
+  {applyMatrix(1, 0, 0, 1, distanceX, distanceY);}
+  // </public>
+
+  // <private>
+  /**
+    Begins a subpath [PDF:1.6:4.4.1].
+
+    @param startPoint Starting point.
+  */
+  private void beginSubpath(
+    Point2D startPoint
+    )
+  {
+    add(
+      new BeginSubpath(
+        startPoint.getX(),
+        scanner.getContentContext().getBox().getHeight() - startPoint.getY()
+        )
+      );
+  }
+
+  /**
+    Begins a text object [PDF:1.6:5.3].
+
+    @see #end()
+  */
+  private Text beginText(
+    )
+  {return (Text)begin(new Text());}
+
+  //TODO: drawArc MUST seamlessly manage already-begun paths.
+  private void drawArc(
+    RectangularShape location,
+    double startAngle,
+    double endAngle,
+    double branchWidth,
+    double branchRatio,
+    boolean beginPath
+    )
+  {
+    /*
+      NOTE: Strictly speaking, arc drawing is NOT a PDF primitive;
+      it leverages the cubic bezier curve operator (thanks to
+      G. Adam Stanislav, whose article was greatly inspirational:
+      see http://www.whizkidtech.redprince.net/bezier/circle/).
+    */
+
+    if(startAngle > endAngle)
+    {
+      double swap = startAngle;
+      startAngle = endAngle;
+      endAngle = swap;
+    }
+
+    double radiusX = location.getWidth() / 2;
+    double radiusY = location.getHeight() / 2;
+
+    final Point2D center = new Point2D.Double(
+      location.getX() + radiusX,
+      location.getY() + radiusY
+      );
+
+    double radians1 = Math.toRadians(startAngle);
+    Point2D point1 = new Point2D.Double(
+      center.getX() + Math.cos(radians1) * radiusX,
+      center.getY() - Math.sin(radians1) * radiusY
+      );
+
+    if(beginPath)
+    {beginSubpath(point1);}
+
+    final double endRadians = Math.toRadians(endAngle);
+    final double quadrantRadians = Math.PI / 2;
+    double radians2 = Math.min(
+      radians1 + quadrantRadians - radians1 % quadrantRadians,
+      endRadians
+      );
+    final double kappa = 0.5522847498;
+    while(true)
+    {
+      double segmentX = radiusX * kappa;
+      double segmentY = radiusY * kappa;
+
+      // Endpoint 2.
+      Point2D point2 = new Point2D.Double(
+        center.getX() + Math.cos(radians2) * radiusX,
+        center.getY() - Math.sin(radians2) * radiusY
+        );
+
+      // Control point 1.
+      double tangentialRadians1 = Math.atan(
+        -(Math.pow(radiusY,2) * (point1.getX()-center.getX()))
+          / (Math.pow(radiusX,2) * (point1.getY()-center.getY()))
+        );
+      double segment1 = (
+        segmentY * (1 - Math.abs(Math.sin(radians1)))
+          + segmentX * (1 - Math.abs(Math.cos(radians1)))
+        ) * (radians2-radians1) / quadrantRadians; // TODO: control segment calculation is still not so accurate as it should -- verify how to improve it!!!
+      Point2D control1 = new Point2D.Double(
+        point1.getX() + Math.abs(Math.cos(tangentialRadians1) * segment1) * Math.signum(-Math.sin(radians1)),
+        point1.getY() + Math.abs(Math.sin(tangentialRadians1) * segment1) * Math.signum(-Math.cos(radians1))
+        );
+
+      // Control point 2.
+      double tangentialRadians2 = Math.atan(
+        -(Math.pow(radiusY,2) * (point2.getX()-center.getX()))
+          / (Math.pow(radiusX,2) * (point2.getY()-center.getY()))
+        );
+      double segment2 = (
+        segmentY * (1 - Math.abs(Math.sin(radians2)))
+          + segmentX * (1 - Math.abs(Math.cos(radians2)))
+        ) * (radians2-radians1) / quadrantRadians; // TODO: control segment calculation is still not so accurate as it should -- verify how to improve it!!!
+      Point2D control2 = new Point2D.Double(
+        point2.getX() + Math.abs(Math.cos(tangentialRadians2) * segment2) * Math.signum(Math.sin(radians2)),
+        point2.getY() + Math.abs(Math.sin(tangentialRadians2) * segment2) * Math.signum(Math.cos(radians2))
+        );
+
+      // Draw the current quadrant curve!
+      drawCurve(
+        point2,
+        control1,
+        control2
+        );
+
+      // Last arc quadrant?
+      if(radians2 == endRadians)
+        break;
+
+      // Preparing the next quadrant iteration...
+      point1 = point2;
+      radians1 = radians2;
+      radians2 += quadrantRadians;
+      if(radians2 > endRadians)
+      {radians2 = endRadians;}
+
+      double quadrantRatio = (radians2 - radians1) / quadrantRadians;
+      radiusX += branchWidth * quadrantRatio;
+      radiusY += branchWidth * quadrantRatio;
+
+      branchWidth *= branchRatio;
+    }
+  }
+
+  private PdfName getFontName(
+    Font value
+    )
+  {
+    // Ensuring that the font exists within the context resources...
+    Resources resources = scanner.getContentContext().getResources();
+    FontResources fonts = resources.getFonts();
+    // No font resources collection?
+    if(fonts == null)
+    {
+      // Create the font resources collection!
+      fonts = new FontResources(scanner.getContents().getDocument());
+      resources.setFonts(fonts); resources.update();
+    }
+    // Get the key associated to the font!
+    PdfName name = fonts.getBaseDataObject().getKey(value.getBaseObject());
+    // No key found?
+    if(name == null)
+    {
+      // Insert the font within the resources!
+      int fontIndex = fonts.size();
+      do
+      {name = new PdfName(String.valueOf(++fontIndex));}
+      while(fonts.containsKey(name));
+      fonts.put(name,value); fonts.update();
+    }
+
+    return name;
+  }
+
+  private PdfName getXObjectName(
+    XObject value
+    )
+  {
+    // Ensuring that the external object exists within the context resources...
+    Resources resources = scanner.getContentContext().getResources();
+    XObjectResources xObjects = resources.getXObjects();
+    // No external object resources collection?
+    if(xObjects == null)
+    {
+      // Create the external object resources collection!
+      xObjects = new XObjectResources(scanner.getContents().getDocument());
+      resources.setXObjects(xObjects); resources.update();
+    }
+    // Get the key associated to the external object!
+    PdfName name = xObjects.getBaseDataObject().getKey(value.getBaseObject());
+    // No key found?
+    if(name == null)
+    {
+      // Insert the external object within the resources!
+      int xObjectIndex = xObjects.size();
+      do
+      {name = new PdfName(String.valueOf(++xObjectIndex));}
+      while(xObjects.containsKey(name));
+      xObjects.put(name,value); xObjects.update();
+    }
+
+    return name;
+  }
+
+  private PdfName getColorSpaceName(
+    ColorSpace value
+    )
+  {
+    if(value instanceof DeviceGrayColorSpace)
+    {return PdfName.DeviceGray;}
+    else if(value instanceof DeviceRGBColorSpace)
+    {return PdfName.DeviceRGB;}
+    else if(value instanceof DeviceCMYKColorSpace)
+    {return PdfName.DeviceCMYK;}
+    else
+      throw new NotImplementedException("colorSpace MUST be converted to its associated name; you need to implement a method in PdfDictionary that, given a PdfDirectObject, returns its associated key.");
+  }
+
+  /**
+    Applies a rotation to the coordinate system from text space to user space [PDF:1.6:4.2.2].
+
+    @param angle Rotational counterclockwise angle.
+  */
+  @SuppressWarnings("unused")
+  private void rotateText(
+    double angle
+    )
+  {
+    double rad = angle * Math.PI / 180;
+    double cos = Math.cos(rad);
+    double sin = Math.sin(rad);
+
+    setTextMatrix(cos, sin, -sin, cos, 0, 0);
+  }
+
+  /**
+    Applies a scaling to the coordinate system from text space to user space
+    [PDF:1.6:4.2.2].
+    @param ratioX Horizontal scaling ratio.
+    @param ratioY Vertical scaling ratio.
+  */
+  @SuppressWarnings("unused")
+  private void scaleText(
+    double ratioX,
+    double ratioY
+    )
+  {setTextMatrix(ratioX, 0, 0, ratioY, 0, 0);}
+
+  /**
+    Sets the transformation of the coordinate system from text space to user space [PDF:1.6:5.3.1].
+    <h3>Remarks</h3>
+    <p>The transformation replaces the current text matrix.</p>
+
+    @param a Item 0,0 of the matrix.
+    @param b Item 0,1 of the matrix.
+    @param c Item 1,0 of the matrix.
+    @param d Item 1,1 of the matrix.
+    @param e Item 2,0 of the matrix.
+    @param f Item 2,1 of the matrix.
+  */
+  private void setTextMatrix(
+    double a,
+    double b,
+    double c,
+    double d,
+    double e,
+    double f
+    )
+  {add(new SetTextMatrix(a,b,c,d,e,f));}
+
+  /**
+    Applies a translation to the coordinate system from text space
+    to user space [PDF:1.6:4.2.2].
+
+    @param distanceX Horizontal distance.
+    @param distanceY Vertical distance.
+  */
+  private void translateText(
+    double distanceX,
+    double distanceY
+    )
+  {setTextMatrix(1, 0, 0, 1, distanceX, distanceY);}
+
+  /**
+    Applies a translation to the coordinate system from text space to user space,
+    relative to the start of the current line [PDF:1.6:5.3.1].
+
+    @param offsetX Horizontal offset.
+    @param offsetY Vertical offset.
+  */
+  @SuppressWarnings("unused")
+  private void translateTextRelative(
+    double offsetX,
+    double offsetY
+    )
+  {
+    add(
+      new TranslateTextRelative(
+        offsetX,
+        -offsetY
+        )
+      );
+  }
+
+  /**
+    Applies a translation to the coordinate system from text space to user space,
+    moving to the start of the next line [PDF:1.6:5.3.1].
+  */
+  @SuppressWarnings("unused")
+  private void translateTextToNextLine(
+    )
+  {add(TranslateTextToNextLine.Value);}
+  // </private>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/composition/TextFitter.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/composition/TextFitter.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/composition/TextFitter.java	(revision 23703)
@@ -0,0 +1,281 @@
+/*
+  Copyright 2007-2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.composition;
+
+import it.stefanochizzolini.clown.documents.contents.fonts.Font;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+  Text fitter.
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.7
+  @since 0.0.3
+*/
+final class TextFitter
+{
+  // <class>
+  // <dynamic>
+  // <fields>
+  private Font font;
+  private double fontSize;
+  private boolean hyphenation;
+  private String text;
+  private double width;
+
+  private int beginIndex = 0;
+  private int endIndex = -1;
+  private String fittedText;
+  private double fittedWidth;
+  // </fields>
+
+  // <constructors>
+  TextFitter(
+    String text,
+    double width,
+    Font font,
+    double fontSize,
+    boolean hyphenation
+    )
+  {
+    this.text = text;
+    this.width = width;
+    this.font = font;
+    this.fontSize = fontSize;
+    this.hyphenation = hyphenation;
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  /**
+    Fits the text inside the specified width.
+    @return Whether the operation was successful.
+  */
+  public boolean fit(
+    )
+  {
+    return fit(
+      endIndex + 1,
+      width
+      );
+    }
+
+  /**
+    Fits the text inside the specified width.
+    @param index Beginning index, inclusive.
+    @param width Available width.
+    @return Whether the operation was successful.
+    @version 0.0.4
+  */
+  public boolean fit(
+    int index,
+    double width
+    )
+  {
+    beginIndex = index;
+    this.width = width;
+
+    fittedText = null;
+    fittedWidth = 0;
+
+    String hyphen = "";
+
+fitting:
+    // Fitting the text within the available width...
+    {
+      Pattern pattern = Pattern.compile("(\\s*)(\\S*)");
+      Matcher matcher = pattern.matcher(text);
+      matcher.region(beginIndex,text.length());
+      while(matcher.find())
+      {
+        // Scanning for the presence of a line break...
+        /*
+          NOTE: This text fitting algorithm returns everytime it finds a line break character,
+          as it's intended to evaluate the width of just a single line of text at a time.
+        */
+        for(
+          int spaceIndex = matcher.start(1),
+            spaceEnd = matcher.end(1);
+          spaceIndex < spaceEnd;
+          spaceIndex++
+          )
+        {
+          switch(text.charAt(spaceIndex))
+          {
+            case '\n':
+            case '\r':
+              index = spaceIndex;
+              break fitting;
+          }
+        }
+
+        // Get the limit of the current word!
+        int wordEndIndex = matcher.end(0);
+        // Add the current word!
+        double wordWidth = font.getKernedWidth(
+          matcher.group(0),
+          fontSize
+          ); // Current word's width.
+        fittedWidth += wordWidth;
+        // Does the fitted text's width exceed the available width?
+        if(fittedWidth > width)
+        {
+          // Remove the current (unfitting) word!
+          fittedWidth -= wordWidth;
+          wordEndIndex = index;
+          if(wordEndIndex == 0 // Fitted text is empty.
+            || !hyphenation) // No hyphenation.
+            break fitting;
+
+          /*
+            NOTE: We need to hyphenate the current (unfitting) word.
+          */
+          /*
+            TODO: This hyphenation algorithm is quite primitive (to improve!).
+          */
+hyphenating:
+          while(true)
+          {
+            // Add the current character!
+            char textChar = text.charAt(wordEndIndex); // Current character.
+            wordWidth = (font.getKerning(text.charAt(wordEndIndex - 1),textChar) + font.getWidth(textChar)) * Font.getScalingFactor(fontSize); // Current character's width.
+            wordEndIndex++;
+            fittedWidth += wordWidth;
+            // Does fitted text's width exceed the available width?
+            if(fittedWidth > width)
+            {
+              // Remove the current character!
+              fittedWidth -= wordWidth;
+              wordEndIndex--;
+              // Is hyphenation to be applied?
+              if(wordEndIndex > index + 4) // Long-enough word chunk.
+              {
+                // Make room for the hyphen character!
+                wordEndIndex--;
+                index = wordEndIndex;
+                textChar = text.charAt(wordEndIndex);
+                fittedWidth -= (font.getKerning(text.charAt(wordEndIndex - 1),textChar) + font.getWidth(textChar)) * Font.getScalingFactor(fontSize);
+
+                // Add the hyphen character!
+                textChar = '-'; // hyphen.
+                fittedWidth += (font.getKerning(text.charAt(wordEndIndex - 1),textChar) + font.getWidth(textChar)) * Font.getScalingFactor(fontSize);
+
+                hyphen = String.valueOf(textChar);
+              }
+              else // No hyphenation.
+              {
+                // Removing the current word chunk...
+                while(wordEndIndex > index)
+                {
+                  wordEndIndex--;
+                  textChar = text.charAt(wordEndIndex);
+                  fittedWidth -= (font.getKerning(text.charAt(wordEndIndex - 1),textChar) + font.getWidth(textChar)) * Font.getScalingFactor(fontSize);
+                }
+              }
+              break hyphenating;
+            }
+          }
+          break fitting;
+        }
+        index = wordEndIndex;
+      }
+    }
+    fittedText = text.substring(beginIndex,index) + hyphen;
+    endIndex = index;
+
+    return (fittedWidth > 0);
+  }
+
+  /**
+    Gets the begin index of the fitted text inside the available text.
+  */
+  public int getBeginIndex(
+    )
+  {return beginIndex;}
+
+  /**
+    Gets the end index of the fitted text inside the available text.
+  */
+  public int getEndIndex(
+    )
+  {return endIndex;}
+
+  /**
+    Gets the fitted text.
+  */
+  public String getFittedText(
+    )
+  {return fittedText;}
+
+  /**
+    Gets the fitted text's width.
+  */
+  public double getFittedWidth(
+    )
+  {return fittedWidth;}
+
+  /**
+    Gets the font used to fit the text.
+  */
+  public Font getFont(
+    )
+  {return font;}
+
+  /**
+    Gets the size of the font used to fit the text.
+  */
+  public double getFontSize(
+    )
+  {return fontSize;}
+
+  /**
+    Gets the available text.
+  */
+  public String getText(
+    )
+  {return text;}
+
+  /**
+    Gets the available width.
+  */
+  public double getWidth(
+    )
+  {return width;}
+
+  /**
+    Gets whether the hyphenation algorithm has to be applied.
+  */
+  public boolean isHyphenation(
+    )
+  {return hyphenation;}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/composition/package.html
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/composition/package.html	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/composition/package.html	(revision 23703)
@@ -0,0 +1,37 @@
+<html>
+<head>
+<!--
+  Copyright 2007-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+-->
+</head>
+<body>
+<p>Typographic composition.</p>
+
+<h2>Related Documentation</h2>
+<p>For overviews, tutorials, examples, guides, and tool documentation, please see:</p>
+<ul>
+  <li><a href="http://clown.stefanochizzolini.it">PDF Clown Home Page</a>
+</ul>
+</body>
+</html>
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/entities/Barcode.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/entities/Barcode.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/entities/Barcode.java	(revision 23703)
@@ -0,0 +1,63 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.entities;
+
+/**
+  Abstract <a href="http://en.wikipedia.org/wiki/Barcode">barcode</a> object.
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.6
+  @since 0.0.6
+*/
+public abstract class Barcode
+  extends Entity
+{
+  // <class>
+  // <dynamic>
+  // <fields>
+  protected String code;
+  // </fields>
+
+  // <constructors>
+  protected Barcode(
+    String code
+    )
+  {this.code = code;}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  /**
+    Gets the code to represent.
+  */
+  public String getCode(
+    )
+  {return code;}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/entities/EAN13Barcode.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/entities/EAN13Barcode.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/entities/EAN13Barcode.java	(revision 23703)
@@ -0,0 +1,407 @@
+/*
+  Copyright 2008-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.entities;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.contents.composition.PrimitiveFilter;
+import it.stefanochizzolini.clown.documents.contents.fonts.Font;
+import it.stefanochizzolini.clown.documents.contents.fonts.StandardType1Font;
+import it.stefanochizzolini.clown.documents.contents.objects.ContentObject;
+import it.stefanochizzolini.clown.documents.contents.xObjects.FormXObject;
+import it.stefanochizzolini.clown.documents.contents.xObjects.XObject;
+
+import java.awt.Dimension;
+import java.awt.geom.Dimension2D;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.util.Arrays;
+
+/**
+  <a href="http://en.wikipedia.org/wiki/EAN13">EAN-13 Bar Code</a> object [GS1:7.1:5.1.1.3.1].
+
+  <p>The EAN-13 Bar Code Symbol shall be made up as follows, reading from left to right:</p>
+  <ol>
+    <li>A left Quiet Zone</li>
+    <li>A normal Guard Bar Pattern (Left Guard)</li>
+    <li>Six symbol characters from number sets A and B (Left Half)</li>
+    <li>A center Guard Bar Pattern (Center Guard)</li>
+    <li>Six symbol characters from number set C (Right Half)</li>
+    <li>A normal Guard Bar Pattern (Right Guard)</li>
+    <li>A right Quiet Zone</li>
+  </ol>
+  <p>The rightmost symbol character shall encode the Check Digit.</p>
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+  @since 0.0.6
+*/
+public class EAN13Barcode
+  extends Barcode
+{
+  /*
+    NOTE: Conventional terms used within this implementation:
+      * module: smallest encoding unit (either a bar (dark module) or a space (light module);
+      * element: sequence of omogeneous modules (either all bars or all spaces);
+      * symbol character: code digit, whose encoding is made up of 4 elements encompassing 7 modules;
+      * number set: symbol character encoding, representing the codomain of the digit domain
+        (i.e. [0-9]).
+  */
+  // <class>
+  // <static>
+  // <fields>
+  /**
+    Symbol Character Encodation (Number Set A, odd parity) [GS1:7.1:5.1.1.2.1].
+    NOTE: Number Set B uses the same patterns (though at inverted parity, i.e. even),
+    whilst Number Set C (even parity) mirrors Number Set B.
+  */
+  private static final int[][] DigitElementWidths =
+  {
+    new int[]{3, 2, 1, 1}, // 0
+    new int[]{2, 2, 2, 1}, // 1
+    new int[]{2, 1, 2, 2}, // 2
+    new int[]{1, 4, 1, 1}, // 3
+    new int[]{1, 1, 3, 2}, // 4
+    new int[]{1, 2, 3, 1}, // 5
+    new int[]{1, 1, 1, 4}, // 6
+    new int[]{1, 3, 1, 2}, // 7
+    new int[]{1, 2, 1, 3}, // 8
+    new int[]{3, 1, 1, 2}  // 9
+  };
+
+  /** Bar elements count. */
+  private static int ElementCount;
+
+  /** Digit box height. */
+  private static final int DigitHeight;
+  /** Digit box width. */
+  private static final int DigitWidth;
+
+  /** Bar full height. */
+  private static final int BarHeight;
+
+  /** Digit glyph width. */
+  private static final int DigitGlyphWidth;
+  /** Digit glyph horizontal positions. */
+  private static final float[] DigitGlyphXs;
+
+  /** Guard bar index positions. */
+  private static int[] GuardBarIndexes =
+  {
+    0, 2, // Left Guard.
+    28, 30, // Center Guard.
+    56, 58 // Right Guard.
+  };
+
+  private static final int NumberSet_A = 0;
+  private static final int NumberSet_B = 1;
+  /**
+    Left Half of an EAN-13 Bar Code Symbol.
+    Since the EAN-13 Bar Code Symbol comprises only 12 symbol characters
+    but encodes 13 digits of data (including the Check Digit),
+    the value of the additional digit (leading digit, implicitly encoded),
+    which is the character in the leftmost position in the data string,
+    shall be encoded by the variable parity mix of number sets A and B
+    for the six symbol characters in the left half of the symbol.
+  */
+  private static final int[][] LeftHalfNumberSets =
+  {
+    new int[]{NumberSet_A,NumberSet_A,NumberSet_A,NumberSet_A,NumberSet_A,NumberSet_A}, // 0
+    new int[]{NumberSet_A,NumberSet_A,NumberSet_B,NumberSet_A,NumberSet_B,NumberSet_B}, // 1
+    new int[]{NumberSet_A,NumberSet_A,NumberSet_B,NumberSet_B,NumberSet_A,NumberSet_B}, // 2
+    new int[]{NumberSet_A,NumberSet_A,NumberSet_B,NumberSet_B,NumberSet_B,NumberSet_A}, // 3
+    new int[]{NumberSet_A,NumberSet_B,NumberSet_A,NumberSet_A,NumberSet_B,NumberSet_B}, // 4
+    new int[]{NumberSet_A,NumberSet_B,NumberSet_B,NumberSet_A,NumberSet_A,NumberSet_B}, // 5
+    new int[]{NumberSet_A,NumberSet_B,NumberSet_B,NumberSet_B,NumberSet_A,NumberSet_A}, // 6
+    new int[]{NumberSet_A,NumberSet_B,NumberSet_A,NumberSet_B,NumberSet_A,NumberSet_B}, // 7
+    new int[]{NumberSet_A,NumberSet_B,NumberSet_A,NumberSet_B,NumberSet_B,NumberSet_A}, // 8
+    new int[]{NumberSet_A,NumberSet_B,NumberSet_B,NumberSet_A,NumberSet_B,NumberSet_A}  // 9
+  };
+  // </fields>
+
+  // <constructors>
+  static
+  {
+    /*
+      Digit metrics.
+    */
+    {
+      int[] digitElementWidths = DigitElementWidths[0];
+
+      ElementCount
+        = 3 // Left Guard.
+          + digitElementWidths.length*6 // Left Half.
+          + 5 // Center Guard.
+          + digitElementWidths.length*6 // Right Half.
+          + 3; // Right Guard.
+
+      int digitWidth = 0;
+      for(int digitElementWidth : digitElementWidths)
+      {digitWidth += digitElementWidth;}
+      DigitWidth = digitWidth;
+      DigitHeight = DigitWidth + 2;
+      DigitGlyphWidth = DigitWidth - 1;
+      BarHeight = DigitHeight * 4;
+    }
+
+    /*
+      Digit glyph horizontal positions.
+    */
+    {
+      float[] elementWidths =
+      {
+        DigitWidth,
+        3,
+        DigitWidth, DigitWidth, DigitWidth, DigitWidth, DigitWidth, DigitWidth,
+        5,
+        DigitWidth, DigitWidth, DigitWidth, DigitWidth, DigitWidth, DigitWidth,
+        3
+      };
+      int[] digitIndexes = {0,2,3,4,5,6,7,9,10,11,12,13,14};
+      DigitGlyphXs = new float[13];
+      int digitXIndex = 0;
+      for(
+        int index = 0,
+          length = elementWidths.length;
+        index < length;
+        index++
+        )
+      {
+        if(index < digitIndexes[digitXIndex])
+        {DigitGlyphXs[digitXIndex] += elementWidths[index];}
+        else
+        {
+          DigitGlyphXs[digitXIndex] += elementWidths[index] / 2;
+          digitXIndex++;
+          if(digitXIndex >= DigitGlyphXs.length)
+            break;
+
+          DigitGlyphXs[digitXIndex] = DigitGlyphXs[digitXIndex-1] + elementWidths[index] / 2;
+        }
+      }
+    }
+  }
+  // </constructors>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  public EAN13Barcode(
+    String code
+    )
+  {super(code);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public ContentObject toInlineObject(
+    PrimitiveFilter context
+    )
+  {
+    ContentObject barcodeObject = context.beginLocalState();
+    {
+      Font font = new StandardType1Font(
+        context.getScanner().getContents().getDocument(),
+        StandardType1Font.FamilyEnum.Helvetica,
+        false,
+        false
+        );
+      float fontSize = (float)(DigitGlyphWidth / font.getWidth(code.substring(0,1), 1));
+
+      // 1. Bars.
+      {
+        float elementX = DigitWidth;
+        int[] elementWidths = getElementWidths();
+
+        float guardBarIndentY = DigitHeight / 2;
+        boolean isBar = true;
+        for(
+          int elementIndex = 0;
+          elementIndex < elementWidths.length;
+          elementIndex++
+          )
+        {
+          float elementWidth = elementWidths[elementIndex];
+          // Dark element?
+          /*
+            NOTE: EAN symbol elements alternate bars to spaces.
+          */
+          if(isBar)
+          {
+            context.drawRectangle(
+              new Rectangle2D.Double(
+                elementX,
+                0,
+                elementWidth,
+                BarHeight + (
+                  // Guard bar?
+                  Arrays.binarySearch(GuardBarIndexes, elementIndex) >= 0
+                    ? guardBarIndentY // Guard bar.
+                    : 0 // Symbol character.
+                  )
+                )
+              );
+          }
+
+          elementX += elementWidth;
+          isBar = !isBar;
+        }
+        context.fill();
+      }
+
+      // 2. Digits.
+      {
+        context.setFont(font,fontSize);
+        float digitY = BarHeight + (DigitHeight - ((float)font.getAscent(fontSize))) / 2;
+        // Showing the digits...
+        for(
+          int digitIndex = 0;
+          digitIndex < 13;
+          digitIndex++
+          )
+        {
+          String digit = code.substring(digitIndex, digitIndex+1);
+          float pX = DigitGlyphXs[digitIndex] // Digit position.
+            - (float)font.getWidth(digit,fontSize) / 2; // Centering.
+          // Show the current digit!
+          context.showText(
+            digit,
+            new Point2D.Double(pX,digitY)
+            );
+        }
+      }
+    }
+    context.end();
+
+    return barcodeObject;
+  }
+
+  @Override
+  public XObject toXObject(
+    Document context
+    )
+  {
+    FormXObject xObject = new FormXObject(context);
+    xObject.setSize(getSize());
+    PrimitiveFilter builder = new PrimitiveFilter(xObject);
+    this.toInlineObject(builder);
+    builder.flush();
+
+    return xObject;
+  }
+  // </public>
+
+  // <private>
+  /**
+    Gets the code elements widths.
+  */
+  private int[] getElementWidths(
+    )
+  {
+    // 1. Digit-codes-to-digit-IDs transformation.
+    /* NOTE: Leveraging the ASCII charset sequence. */
+    int[] digits = new int[code.length()];
+    for(int index = 0; index < digits.length; index++)
+    {digits[index] = code.charAt(index) - '0';}
+
+    // 2. Element widths calculation.
+    int[] elementWidths = new int[ElementCount];
+    int elementIndex = 0;
+
+    // Left Guard Bar Pattern (3 elements).
+    elementWidths[elementIndex++] = 1;
+    elementWidths[elementIndex++] = 1;
+    elementWidths[elementIndex++] = 1;
+
+    int digitIndex = 0;
+
+    // Left Half (6 digits, 4 elements each).
+    int[] leftHalfNumberSets = LeftHalfNumberSets[digits[digitIndex++]]; // Gets the left-half number set encoding sequence based on the leading digit.
+    do
+    {
+      int[] digitElementWidths = DigitElementWidths[digits[digitIndex]];
+      // Number Set A encoding to apply?
+      if(leftHalfNumberSets[digitIndex-1] == NumberSet_A) // Number Set A encoding.
+      {
+        elementWidths[elementIndex++] = digitElementWidths[0];
+        elementWidths[elementIndex++] = digitElementWidths[1];
+        elementWidths[elementIndex++] = digitElementWidths[2];
+        elementWidths[elementIndex++] = digitElementWidths[3];
+      }
+      else // Number Set B encoding.
+      {
+        elementWidths[elementIndex++] = digitElementWidths[3];
+        elementWidths[elementIndex++] = digitElementWidths[2];
+        elementWidths[elementIndex++] = digitElementWidths[1];
+        elementWidths[elementIndex++] = digitElementWidths[0];
+      }
+    }while(digitIndex++ < leftHalfNumberSets.length);
+
+    // Center Guard Bar Pattern (5 elements).
+    elementWidths[elementIndex++] = 1;
+    elementWidths[elementIndex++] = 1;
+    elementWidths[elementIndex++] = 1;
+    elementWidths[elementIndex++] = 1;
+    elementWidths[elementIndex++] = 1;
+
+    // Right Half (6 digits, 4 elements each).
+    do
+    {
+      int[] digitElementWidths = DigitElementWidths[digits[digitIndex]];
+      // NOTE: Number Set C encoding.
+      elementWidths[elementIndex++] = digitElementWidths[0];
+      elementWidths[elementIndex++] = digitElementWidths[1];
+      elementWidths[elementIndex++] = digitElementWidths[2];
+      elementWidths[elementIndex++] = digitElementWidths[3];
+    }while(digitIndex++ < 12);
+
+    // Right Guard Bar Pattern (3 elements).
+    elementWidths[elementIndex++] = 1;
+    elementWidths[elementIndex++] = 1;
+    elementWidths[elementIndex++] = 1;
+
+    return elementWidths;
+  }
+
+  /**
+    Gets the barcode's graphical size.
+  */
+  private Dimension2D getSize(
+    )
+  {
+    return new Dimension(
+      DigitWidth * 13 // Digits.
+        + 3*2 // Left and right guards.
+        + 5, // Center guard.
+      BarHeight // Non-guard bar.
+        + DigitHeight // Digit.
+      );
+  }
+  // </private>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/entities/Entity.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/entities/Entity.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/entities/Entity.java	(revision 23703)
@@ -0,0 +1,60 @@
+/*
+  Copyright 2006-2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.entities;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.contents.IContentEntity;
+import it.stefanochizzolini.clown.documents.contents.composition.PrimitiveFilter;
+import it.stefanochizzolini.clown.documents.contents.objects.ContentObject;
+import it.stefanochizzolini.clown.documents.contents.xObjects.XObject;
+
+/**
+  Abstract specialized graphic object.
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.6
+*/
+public abstract class Entity
+  implements IContentEntity
+{
+  // <class>
+  // <dynamic>
+  // <interface>
+  // <public>
+  // <IContentEntity>
+  public abstract ContentObject toInlineObject(
+    PrimitiveFilter context
+    );
+
+  public abstract XObject toXObject(
+    Document context
+    );
+  // </IContentEntity>
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/entities/Image.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/entities/Image.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/entities/Image.java	(revision 23703)
@@ -0,0 +1,167 @@
+/*
+  Copyright 2006-2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.entities;
+
+import it.stefanochizzolini.clown.bytes.FileInputStream;
+import it.stefanochizzolini.clown.bytes.IInputStream;
+
+/**
+  Abstract image object [PDF:1.6:4.8].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.6
+*/
+public abstract class Image
+  extends Entity
+{
+  // <class>
+  // <static>
+  // <interface>
+  // <public>
+  public static Image get(
+    String path
+    )
+  {
+    try
+    {
+      return get(
+        new FileInputStream(
+          new java.io.RandomAccessFile(path,"r")
+          )
+        );
+    }
+    catch(Exception e)
+    {throw new RuntimeException(e);}
+  }
+
+  public static Image get(
+    java.io.File file
+    )
+  {return get(file.getPath());}
+
+  public static Image get(
+    IInputStream stream
+    )
+  {
+    try
+    {
+      // Get the format identifier!
+      byte[] formatMarkerBytes = new byte[2];
+      stream.read(formatMarkerBytes);
+
+      // Is JPEG?
+      /*
+        NOTE: JPEG files are identified by a SOI (Start Of Image) marker [ISO 10918-1].
+      */
+      if(formatMarkerBytes[0] == (byte)0xFF
+        && formatMarkerBytes[1] == (byte)0xD8) // JPEG.
+      {return new JpegImage(stream);}
+      else // Unknown.
+      {return null;}
+    }
+    catch(Exception e)
+    {throw new RuntimeException(e);}
+  }
+  // </public>
+  // </interface>
+  // </static>
+
+  // <dynamic>
+  // <fields>
+  private int bitsPerComponent;
+  private int height;
+  private int width;
+
+  private IInputStream stream;
+  // </fields>
+
+  // <constructors>
+  protected Image(
+    IInputStream stream
+    )
+  {this.stream = stream;}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  /**
+    Gets the number of bits per color component [PDF:1.6:4.8.2].
+  */
+  public int getBitsPerComponent(
+    )
+  {return bitsPerComponent;}
+
+  /**
+    Gets the height of the image in samples [PDF:1.6:4.8.2].
+  */
+  public int getHeight(
+    )
+  {return height;}
+
+  /**
+    Gets the width of the image in samples [PDF:1.6:4.8.2].
+  */
+  public int getWidth(
+    )
+  {return width;}
+  // </public>
+
+  // <protected>
+  /**
+    Gets the underlying stream.
+  */
+  protected IInputStream getStream(
+    )
+  {return stream;}
+
+  /**
+    Sets the number of bits per color component [PDF:1.6:4.8.2].
+  */
+  protected void setBitsPerComponent(
+    int value
+    )
+  {bitsPerComponent = value;}
+
+  /**
+    Sets the height of the image in samples [PDF:1.6:4.8.2].
+  */
+  protected void setHeight(
+    int value
+    )
+  {height = value;}
+
+  /**
+    Sets the width of the image in samples [PDF:1.6:4.8.2].
+  */
+  protected void setWidth(
+    int value
+    )
+  {width = value;}
+  // </protected>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/entities/JpegImage.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/entities/JpegImage.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/entities/JpegImage.java	(revision 23703)
@@ -0,0 +1,176 @@
+/*
+  Copyright 2006-2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.entities;
+
+import it.stefanochizzolini.clown.bytes.Buffer;
+import it.stefanochizzolini.clown.bytes.IInputStream;
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.contents.composition.PrimitiveFilter;
+import it.stefanochizzolini.clown.documents.contents.objects.ContentObject;
+import it.stefanochizzolini.clown.documents.contents.objects.InlineImage;
+import it.stefanochizzolini.clown.documents.contents.objects.InlineImageBody;
+import it.stefanochizzolini.clown.documents.contents.objects.InlineImageHeader;
+import it.stefanochizzolini.clown.documents.contents.xObjects.ImageXObject;
+import it.stefanochizzolini.clown.documents.contents.xObjects.XObject;
+import it.stefanochizzolini.clown.objects.PdfDictionary;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfInteger;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfStream;
+
+import java.nio.ByteOrder;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+  JPEG image object [ISO 10918-1;JFIF:1.02].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.6
+*/
+public class JpegImage
+  extends Image
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  JpegImage(
+    IInputStream stream
+    )
+  {
+    super(stream);
+
+    load();
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  /**
+    @since 0.0.6
+  */
+  @SuppressWarnings("unchecked")
+  @Override
+  public ContentObject toInlineObject(
+    PrimitiveFilter context
+    )
+  {
+    return context.add(
+      new InlineImage(
+        new InlineImageHeader(
+          (List<PdfDirectObject>)(List<? extends PdfDirectObject>)Arrays.asList(
+            PdfName.W, new PdfInteger(getWidth()),
+            PdfName.H, new PdfInteger(getHeight()),
+            PdfName.CS, PdfName.RGB,
+            PdfName.BPC, new PdfInteger(getBitsPerComponent()),
+            PdfName.F, PdfName.DCT
+            )
+          ),
+        new InlineImageBody(
+          new Buffer(getStream().toByteArray())
+          )
+        )
+      );
+  }
+
+  @Override
+  public XObject toXObject(
+    Document context
+    )
+  {
+    return new ImageXObject(
+      context,
+      new PdfStream(
+        new PdfDictionary(
+          new PdfName[]
+          {
+            PdfName.Width,
+            PdfName.Height,
+            PdfName.BitsPerComponent,
+            PdfName.ColorSpace,
+            PdfName.Filter
+          },
+          new PdfDirectObject[]
+          {
+            new PdfInteger(getWidth()),
+            new PdfInteger(getHeight()),
+            new PdfInteger(getBitsPerComponent()),
+            PdfName.DeviceRGB,
+            PdfName.DCTDecode
+          }
+          ),
+        new Buffer(getStream().toByteArray())
+        )
+      );
+  }
+  // </public>
+
+  // <private>
+  private void load(
+    )
+  {
+    /*
+      NOTE: Big-endian data expected.
+    */
+    IInputStream stream = getStream();
+    // Ensure that data is read using the proper endianness!
+    stream.setByteOrder(ByteOrder.BIG_ENDIAN);
+    try
+    {
+      int index = 4;
+      stream.seek(index);
+      byte[] markerBytes = new byte[2];
+      while(true)
+      {
+        index += stream.readUnsignedShort();
+        stream.seek(index);
+
+        stream.read(markerBytes);
+        index += 2;
+
+        // Frame header?
+        if(markerBytes[0] == (byte)0xFF
+          && markerBytes[1] == (byte)0xC0)
+        {
+          stream.skip(2);
+          // Get the image bits per color component (sample precision)!
+          setBitsPerComponent(stream.readUnsignedByte());
+          // Get the image size!
+          setHeight(stream.readUnsignedShort());
+          setWidth(stream.readUnsignedShort());
+
+          break;
+        }
+      }
+    }
+    catch(Exception e)
+    {throw new RuntimeException(e);}
+  }
+  // </private>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/entities/package.html
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/entities/package.html	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/entities/package.html	(revision 23703)
@@ -0,0 +1,37 @@
+<html>
+<head>
+<!--
+  Copyright 2006-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+-->
+</head>
+<body>
+<p>Specialized graphic types.</p>
+
+<h2>Related Documentation</h2>
+<p>For overviews, tutorials, examples, guides, and tool documentation, please see:</p>
+<ul>
+  <li><a href="http://clown.stefanochizzolini.it">PDF Clown Home Page</a>
+</ul>
+</body>
+</html>
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/AfmParser.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/AfmParser.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/AfmParser.java	(revision 23703)
@@ -0,0 +1,266 @@
+/*
+  Copyright 2009-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.fonts;
+
+import java.io.BufferedReader;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+  AFM file format parser [AFM:4.1].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.8
+  @version 0.0.8
+*/
+final class AfmParser
+{
+  // <class>
+  // <classes>
+  /**
+    Font header (Global font information).
+  */
+  static final class FontMetrics
+  {
+    /**
+      Whether the encoding is custom (symbolic font).
+    */
+    public boolean isCustomEncoding;
+    public String fontName;
+    public String weight;
+    public float italicAngle;
+    public boolean isFixedPitch;
+    public short xMin;
+    public short yMin;
+    public short xMax;
+    public short yMax;
+    public short underlinePosition;
+    public short underlineThickness;
+    public short capHeight;
+    public short xHeight;
+    public short ascender;
+    public short descender;
+    public short stemH;
+    public short stemV;
+  }
+  // </classes>
+
+  // <dynamic>
+  // <fields>
+  public FontMetrics metrics;
+
+  public Map<Integer,Integer> glyphIndexes;
+  public Map<Integer,Integer> glyphKernings;
+  public Map<Integer,Integer> glyphWidths;
+
+  public BufferedReader fontData;//TODO: convert to IInputStream
+  // </fields>
+
+  // <constructors>
+  AfmParser(
+    BufferedReader fontData
+    )
+  {
+    this.fontData = fontData;
+
+    load();
+  }
+  // </constructors>
+
+  // <interface>
+  // <private>
+  /**
+    Loads the font data.
+  */
+  private void load(
+    )
+  {
+    metrics = new FontMetrics();
+
+    load_fontHeader();
+    load_charMetrics();
+    load_kerningData();
+  }
+
+  /**
+    Loads the font header [AFM:4.1:3,4,4.1,4.2].
+  */
+  private void load_fontHeader(
+    )
+  {
+    String line;
+    Pattern linePattern = Pattern.compile("(\\S+)\\s+(.+)");
+    try
+    {
+      while((line = fontData.readLine()) != null)
+      {
+        Matcher lineMatcher = linePattern.matcher(line);
+        if(!lineMatcher.find())
+          continue;
+
+        String key = lineMatcher.group(1);
+        if(key.equals("FontName"))
+        {metrics.fontName = lineMatcher.group(2);}
+        else if (key.equals("Weight"))
+        {metrics.weight = lineMatcher.group(2);}
+        else if (key.equals("ItalicAngle"))
+        {metrics.italicAngle = Float.valueOf(lineMatcher.group(2));}
+        else if (key.equals("IsFixedPitch"))
+        {metrics.isFixedPitch = lineMatcher.group(2).equals("true");}
+        else if (key.equals("FontBBox"))
+        {
+          String[] coordinates = lineMatcher.group(2).split("\\s+");
+          metrics.xMin = Short.valueOf(coordinates[0]);
+          metrics.yMin = Short.valueOf(coordinates[1]);
+          metrics.xMax = Short.valueOf(coordinates[2]);
+          metrics.yMax = Short.valueOf(coordinates[3]);
+        }
+        else if (key.equals("UnderlinePosition"))
+        {metrics.underlinePosition = Short.valueOf(lineMatcher.group(2));}
+        else if (key.equals("UnderlineThickness"))
+        {metrics.underlineThickness = Short.valueOf(lineMatcher.group(2));}
+        else if (key.equals("EncodingScheme"))
+        {metrics.isCustomEncoding = lineMatcher.group(2).equals("FontSpecific");}
+        else if (key.equals("CapHeight"))
+        {metrics.capHeight = Short.valueOf(lineMatcher.group(2));}
+        else if (key.equals("XHeight"))
+        {metrics.xHeight = Short.valueOf(lineMatcher.group(2));}
+        else if (key.equals("Ascender"))
+        {metrics.ascender = Short.valueOf(lineMatcher.group(2));}
+        else if (key.equals("Descender"))
+        {metrics.descender = Short.valueOf(lineMatcher.group(2));}
+        else if (key.equals("StdHW"))
+        {metrics.stemH = Short.valueOf(lineMatcher.group(2));}
+        else if (key.equals("StdVW"))
+        {metrics.stemV = Short.valueOf(lineMatcher.group(2));}
+        else if (key.equals("StartCharMetrics"))
+        {break;}
+      }
+      if(metrics.ascender == 0)
+      {metrics.ascender = metrics.yMax;}
+      if(metrics.descender == 0)
+      {metrics.descender = metrics.yMin;}
+    }
+    catch(Exception e)
+    {throw new RuntimeException(e);}
+  }
+
+  /**
+    Loads individual character metrics [AFM:4.1:3,4,4.4,8].
+  */
+  private void load_charMetrics(
+    )
+  {
+    glyphIndexes = new Hashtable<Integer, Integer>();
+    glyphWidths = new Hashtable<Integer,Integer>();
+
+    try
+    {
+      String line;
+      Pattern linePattern = Pattern.compile("C (\\S+) ; WX (\\S+) ; N (\\S+)");
+      while((line = fontData.readLine()) != null)
+      {
+        Matcher lineMatcher = linePattern.matcher(line);
+        if(!lineMatcher.find())
+        {
+          if(line.equals("EndCharMetrics"))
+            break;
+
+          continue;
+        }
+
+        int charCode = Integer.valueOf(lineMatcher.group(1));
+        int width = Integer.valueOf(lineMatcher.group(2));
+        String charName = lineMatcher.group(3);
+
+        if(charCode < 0)
+        {
+          if(charName == null)
+            continue;
+
+          charCode = GlyphMapping.nameToCode(charName);
+        }
+        int code = (
+          charName == null
+              || metrics.isCustomEncoding
+            ? charCode
+            : GlyphMapping.nameToCode(charName)
+          );
+        glyphIndexes.put(code,charCode);
+        glyphWidths.put(charCode,width);
+      }
+    }
+    catch(Exception e)
+    {throw new RuntimeException(e);}
+  }
+
+  /**
+    Loads kerning data [AFM:4.1:3,4,4.5,9].
+  */
+  private void load_kerningData(
+    )
+  {
+    glyphKernings = new Hashtable<Integer,Integer>();
+
+    try
+    {
+      String line;
+      while((line = fontData.readLine()) != null)
+      {
+        if(line.startsWith("StartKernPairs"))
+          break;
+      }
+
+      Pattern linePattern = Pattern.compile("KPX (\\S+) (\\S+) (\\S+)");
+      while((line = fontData.readLine()) != null)
+      {
+        Matcher lineMatcher = linePattern.matcher(line);
+        if(!lineMatcher.find())
+        {
+          if(line.equals("EndKernPairs"))
+            break;
+
+          continue;
+        }
+
+        int code1 = GlyphMapping.nameToCode(lineMatcher.group(1));
+        int code2 = GlyphMapping.nameToCode(lineMatcher.group(2));
+        int pair = code1 << 16 + code2;
+        int value = Integer.valueOf(lineMatcher.group(3));
+
+        glyphKernings.put(pair,value);
+      }
+    }
+    catch(Exception e)
+    {throw new RuntimeException(e);}
+  }
+  // </private>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/CMap.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/CMap.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/CMap.java	(revision 23703)
@@ -0,0 +1,149 @@
+/*
+  Copyright 2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.fonts;
+
+import it.stefanochizzolini.clown.bytes.Buffer;
+import it.stefanochizzolini.clown.bytes.IInputStream;
+import it.stefanochizzolini.clown.objects.PdfDataObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfStream;
+import it.stefanochizzolini.clown.util.ByteArray;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.util.Map;
+
+/**
+  Character map [PDF:1.6:5.6.4].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.8
+  @version 0.0.8
+*/
+final class CMap
+{
+  // <static>
+  // <interface>
+  /**
+    Gets the character map extracted from the given data.
+
+    @param stream Character map data.
+  */
+  public static Map<ByteArray,Integer> get(
+    IInputStream stream
+    )
+  {
+    CMapParser parser = new CMapParser(stream);
+    return parser.parse();
+  }
+
+  /**
+    Gets the character map extracted from the given encoding object.
+  
+    @param encodingObject Encoding object.
+  */
+  public static Map<ByteArray,Integer> get(
+    PdfDataObject encodingObject
+    )
+  {
+    if(encodingObject == null)
+      return null;
+    
+    if(encodingObject instanceof PdfName) // Predefined CMap.
+      return get((PdfName)encodingObject);
+    else if(encodingObject instanceof PdfStream) // Embedded CMap file.
+      return get((PdfStream)encodingObject);
+    else
+      throw new UnsupportedOperationException("Unknown encoding object type: " + encodingObject.getClass().getSimpleName());
+  }
+
+  /**
+    Gets the character map extracted from the given data.
+
+    @param stream Character map data.
+  */
+  public static Map<ByteArray,Integer> get(
+    PdfStream stream
+    )
+  {return get(stream.getBody());}
+
+  /**
+    Gets the character map corresponding to the given name.
+
+    @param name Predefined character map name.
+    @return null, in case no name matching occurs.
+  */
+  public static Map<ByteArray,Integer> get(
+    PdfName name
+    )
+  {return get((String)name.getValue());}
+
+  /**
+    Gets the character map corresponding to the given name.
+
+    @param name Predefined character map name.
+    @return null, in case no name matching occurs.
+  */
+  public static Map<ByteArray,Integer> get(
+    String name
+    )
+  {
+    Map<ByteArray,Integer> cmap = null;
+    {
+      BufferedReader cmapStream = null;
+      try
+      {
+        cmapStream = new BufferedReader(
+          new InputStreamReader(
+            CMap.class.getResourceAsStream("/fonts/cmap/" + name)
+            )
+          );
+        cmap = get(new Buffer(cmapStream));
+      }
+      catch(Exception e)
+      { /* Ignore. */ }
+      finally
+      {
+        try
+        {
+          if(cmapStream != null)
+          {cmapStream.close();}
+        }
+        catch(Exception e)
+        { /* Ignore. */ }
+      }
+    }
+    return cmap;
+  }
+  // </interface>
+  // </static>
+
+  // <constructors>
+  private CMap(
+    )
+  {}
+  // </constructors>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/CMapParser.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/CMapParser.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/CMapParser.java	(revision 23703)
@@ -0,0 +1,699 @@
+/*
+  Copyright 2009-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.fonts;
+
+import it.stefanochizzolini.clown.bytes.Buffer;
+import it.stefanochizzolini.clown.bytes.IInputStream;
+import it.stefanochizzolini.clown.tokens.FileFormatException;
+import it.stefanochizzolini.clown.tokens.TokenTypeEnum;
+import it.stefanochizzolini.clown.util.ByteArray;
+import it.stefanochizzolini.clown.util.ConvertUtils;
+import it.stefanochizzolini.clown.util.math.OperationUtils;
+
+import java.io.EOFException;
+import java.io.InputStream;
+import java.util.Hashtable;
+import java.util.Map;
+
+/**
+  CMap parser [PDF:1.6:5.6.4;CMAP].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+  @since 0.0.8
+*/
+final class CMapParser
+{
+/*
+TODO:IMPL this parser evaluates a subset of the lexical domain of the token parser (clown.tokens.Parser): it should be better to derive both parsers from a common parsing engine in order to avoid unwieldy duplications.
+*/
+  // <class>
+  // <static>
+  // <fields>
+  private static final String BeginBaseFontCharOperator = "beginbfchar";
+  private static final String BeginBaseFontRangeOperator = "beginbfrange";
+  private static final String BeginCIDCharOperator = "begincidchar";
+  private static final String BeginCIDRangeOperator = "begincidrange";
+   // </fields>
+
+  // <interface>
+  // <protected>
+  protected static int getHex(
+    int c
+    )
+  {
+    if(c >= '0' && c <= '9')
+      return (c - '0');
+    else if(c >= 'A' && c <= 'F')
+      return (c - 'A' + 10);
+    else if(c >= 'a' && c <= 'f')
+      return (c - 'a' + 10);
+    else
+      return -1;
+  }
+
+  /**
+    Evaluates whether a character is a delimiter [PDF:1.6:3.1.1].
+  */
+  protected static boolean isDelimiter(
+    int c
+    )
+  {return c == '(' || c == ')' || c == '<' || c == '>' || c == '[' || c == ']' || c == '/' || c == '%';}
+
+  /**
+    Evaluates whether a character is an EOL marker [PDF:1.6:3.1.1].
+  */
+  protected static boolean isEOL(
+    int c
+    )
+  {return c == 10 || c == 13;}
+
+  /**
+    Evaluates whether a character is a white-space [PDF:1.6:3.1.1].
+  */
+  protected static boolean isWhitespace(
+    int c
+    )
+  {return c == 32 || isEOL(c) || c == 0 || c == 9 || c == 12;}
+  // </protected>
+  // </interface>
+  // </static>
+
+  // <dynamic>
+  // <fields>
+  private IInputStream stream;
+  private Object token;
+  private TokenTypeEnum tokenType;
+  // </fields>
+
+  // <constructors>
+  public CMapParser(
+    java.io.BufferedReader stream
+    )
+  {this(new Buffer(stream));}
+
+  public CMapParser(
+    InputStream stream
+    )
+  {this(new Buffer(stream));}
+
+  public CMapParser(
+    IInputStream stream
+    )
+  {this.stream = stream;}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  public long getLength(
+    )
+  {return stream.getLength();}
+
+  public long getPosition(
+    )
+  {return stream.getPosition();}
+
+  /**
+    Gets the stream to be parsed.
+  */
+  public IInputStream getStream(
+    )
+  {return stream;}
+
+  /**
+    Gets the currently-parsed token.
+  */
+  public Object getToken(
+    )
+  {return token;}
+
+  /**
+    Gets the currently-parsed token type.
+  */
+  public TokenTypeEnum getTokenType(
+    )
+  {return tokenType;}
+
+  /**
+    @param offset Number of tokens to be skipped before reaching the intended one.
+  */
+  public boolean moveNext(
+    int offset
+    ) throws FileFormatException
+  {
+    for(
+      int index = 0;
+      index < offset;
+      index++
+      )
+    {
+      if(!moveNext())
+        return false;
+    }
+    return true;
+  }
+
+  /**
+    Parse the next token [PDF:1.6:3.1].
+    <h3>Contract</h3>
+    <ul>
+     <li>Preconditions:
+      <ol>
+       <li>To properly parse the current token, the pointer MUST be just before its starting (leading whitespaces are ignored).</li>
+      </ol>
+     </li>
+     <li>Postconditions:
+      <ol>
+       <li id="moveNext_contract_post[0]">When this method terminates, the pointer IS at the last byte of the current token.</li>
+      </ol>
+     </li>
+     <li>Invariants:
+      <ol>
+       <li>The byte-level position of the pointer IS anytime (during token parsing) at the end of the current token (whereas the 'current token' represents the token-level position of the pointer).</li>
+      </ol>
+     </li>
+     <li>Side-effects:
+      <ol>
+       <li>See <a href="#moveNext_contract_post[0]">Postconditions</a>.</li>
+      </ol>
+     </li>
+    </ul>
+    @return Whether a new token was found.
+  */
+  public boolean moveNext(
+    ) throws FileFormatException
+  {
+    /*
+      TODO: It'd be interesting to evaluate an alternative regular-expression-based
+      implementation...
+    */
+    int c = 0;
+
+    // Skip leading white-space characters [PDF:1.6:3.1.1].
+    try
+    {
+      do
+      {
+        c = stream.readUnsignedByte();
+      } while(isWhitespace(c)); // Keep goin' till there's a white-space character...
+    }
+    catch(EOFException e)
+    {return false;}
+
+    StringBuilder buffer = null;
+    token = null;
+    // Which character is it?
+    switch(c)
+    {
+      case '/': // Name.
+        tokenType = TokenTypeEnum.Name;
+
+        buffer = new StringBuilder();
+        try
+        {
+          while(true)
+          {
+            c = stream.readUnsignedByte();
+            if(isDelimiter(c) || isWhitespace(c))
+              break;
+            // Is it an hexadecimal code [PDF:1.6:3.2.4]?
+            if(c == '#')
+            {
+              try
+              {c = (getHex(stream.readUnsignedByte()) << 4) + getHex(stream.readUnsignedByte());}
+              catch(EOFException e)
+              {throw new FileFormatException("Unexpected EOF (malformed hexadecimal code in name object).",e,stream.getPosition());}
+            }
+
+            buffer.append((char)c);
+          }
+        }
+        catch(EOFException e)
+        {throw new FileFormatException("Unexpected EOF (malformed name object).",e,stream.getPosition());}
+
+        stream.skip(-1); // Recover the first byte after the current token.
+        break;
+      case '0':
+      case '1':
+      case '2':
+      case '3':
+      case '4':
+      case '5':
+      case '6':
+      case '7':
+      case '8':
+      case '9':
+      case '.':
+      case '-':
+      case '+': // Number [PDF:1.6:3.2.2] | Indirect reference.
+        switch(c)
+        {
+          case '.': // Decimal point.
+            tokenType = TokenTypeEnum.Real;
+            break;
+          default: // Digit or signum.
+            tokenType = TokenTypeEnum.Integer; // By default (it may be real).
+            break;
+        }
+
+        // Building the number...
+        buffer = new StringBuilder();
+        try
+        {
+          do
+          {
+            buffer.append((char)c);
+            c = stream.readUnsignedByte();
+            if(c == '.')
+              tokenType = TokenTypeEnum.Real;
+            else if(c < '0' || c > '9')
+              break;
+          } while(true);
+        }
+        catch(EOFException e)
+        {throw new FileFormatException("Unexpected EOF (malformed number object).",e,stream.getPosition());}
+
+        stream.skip(-1); // Recover the first byte after the current token.
+        break;
+      case '[': // Array (begin).
+        tokenType = TokenTypeEnum.ArrayBegin;
+        break;
+      case ']': // Array (end).
+        tokenType = TokenTypeEnum.ArrayEnd;
+        break;
+      case '<': // Dictionary (begin) | Hexadecimal string.
+        try
+        {c = stream.readUnsignedByte();}
+        catch(EOFException e)
+        {throw new FileFormatException("Unexpected EOF (isolated opening angle-bracket character).",e,stream.getPosition());}
+        // Is it a dictionary (2nd angle bracket [PDF:1.6:3.2.6])?
+        if(c == '<')
+        {
+          tokenType = TokenTypeEnum.DictionaryBegin;
+          break;
+        }
+
+        // Hexadecimal string (single angle bracket [PDF:1.6:3.2.3]).
+        tokenType = TokenTypeEnum.Hex;
+
+        // [FIX:0.0.4:4] It skipped after the first hexadecimal character, missing it.
+        buffer = new StringBuilder();
+        try
+        {
+          while(c != '>') // NOT string end.
+          {
+            buffer.append((char)c);
+
+            c = stream.readUnsignedByte();
+          }
+        }
+        catch(EOFException e)
+        {throw new FileFormatException("Unexpected EOF (malformed hex string).",e,stream.getPosition());}
+        break;
+      case '>': // Dictionary (end).
+        try
+        {c = stream.readUnsignedByte();}
+        catch(EOFException e)
+        {throw new FileFormatException("Unexpected EOF (malformed dictionary).",e,stream.getPosition());}
+        if(c != '>')
+          throw new FileFormatException("Malformed dictionary.",stream.getPosition());
+
+        tokenType = TokenTypeEnum.DictionaryEnd;
+        break;
+      case '%': // Comment.
+        tokenType = TokenTypeEnum.Comment;
+        // Skipping comment content...
+        try
+        {
+          do
+          {c = stream.readUnsignedByte();}
+          while(!isEOL(c));
+        }
+        catch(EOFException e)
+        {/* Let it go. */}
+        break;
+      case '(': // Literal string.
+        tokenType = TokenTypeEnum.Literal;
+
+        buffer = new StringBuilder();
+        int level = 0;
+        try
+        {
+          while(true)
+          {
+            c = stream.readUnsignedByte();
+            if(c == '(')
+              level++;
+            else if(c == ')')
+              level--;
+            else if(c == '\\')
+            {
+              boolean lineBreak = false;
+              c = stream.readUnsignedByte();
+              switch(c)
+              {
+                case 'n':
+                  c = '\n';
+                  break;
+                case 'r':
+                  c = '\r';
+                  break;
+                case 't':
+                  c = '\t';
+                  break;
+                case 'b':
+                  c = '\b';
+                  break;
+                case 'f':
+                  c = '\f';
+                  break;
+                case '(':
+                case ')':
+                case '\\':
+                  break;
+                case '\r':
+                  lineBreak = true;
+                  c = stream.readUnsignedByte();
+                  if(c != '\n')
+                    stream.skip(-1);
+                  break;
+                case '\n':
+                  lineBreak = true;
+                  break;
+                default:
+                {
+                  // Is it outside the octal encoding?
+                  if(c < '0' || c > '7')
+                    break;
+
+                  // Octal [PDF:1.6:3.2.3].
+                  int octal = c - '0';
+                  c = stream.readUnsignedByte();
+                  // Octal end?
+                  if(c < '0' || c > '7')
+                  {c = octal; stream.skip(-1); break;}
+                  octal = (octal << 3) + c - '0';
+                  c = stream.readUnsignedByte();
+                  // Octal end?
+                  if(c < '0' || c > '7')
+                  {c = octal; stream.skip(-1); break;}
+                  octal = (octal << 3) + c - '0';
+                  c = octal & 0xff;
+                  break;
+                }
+              }
+              if(lineBreak)
+                continue;
+            }
+            else if(c == '\r')
+            {
+              c = stream.readUnsignedByte();
+              if(c != '\n')
+              {c = '\n'; stream.skip(-1);}
+            }
+            if(level == -1)
+              break;
+
+            buffer.append((char)c);
+          }
+        }
+        catch(EOFException e)
+        {throw new FileFormatException("Unexpected EOF (malformed literal string).",e,stream.getPosition());}
+        break;
+      default: // Keyword.
+        tokenType = TokenTypeEnum.Keyword;
+
+        buffer = new StringBuilder();
+        try
+        {
+          do
+          {
+            buffer.append((char)c);
+            c = stream.readUnsignedByte();
+          } while(!isDelimiter(c) && !isWhitespace(c));
+        }
+        catch(EOFException e)
+        {/* Let it go. */}
+        stream.skip(-1); // Recover the first byte after the current token.
+        break;
+    }
+
+    if(buffer != null)
+    {
+      /*
+        Here we prepare the current token state.
+      */
+      // Which token type?
+      switch(tokenType)
+      {
+        case Keyword:
+          token = buffer.toString();
+          // Late recognition.
+          if(((String)token).equals("false")
+            || ((String)token).equals("true")) // Boolean.
+          {
+            tokenType = TokenTypeEnum.Boolean;
+            token = Boolean.parseBoolean((String)token);
+          }
+          else if(((String)token).equals("null")) // Null.
+          {
+            tokenType = TokenTypeEnum.Null;
+            token = null;
+          }
+          break;
+        case Comment:
+        case Name:
+          token = buffer.toString();
+          break;
+        case Literal:
+          token = buffer.toString();
+          break;
+        case Hex:
+          token = ConvertUtils.hexToByteArray(buffer.toString());
+          break;
+        case Integer:
+          token = Integer.parseInt(buffer.toString());
+          break;
+        case Real:
+          token = Float.parseFloat(buffer.toString());
+          break;
+      }
+    }
+    return true;
+  }
+
+  /**
+    Parses the character-code-to-unicode mapping [PDF:1.6:5.9.1].
+  */
+  public Map<ByteArray,Integer> parse(
+    )
+  {
+    stream.setPosition(0);
+    Hashtable<ByteArray,Integer> codes = new Hashtable<ByteArray,Integer>();
+    {
+      int itemCount = 0;
+      try
+      {
+        while(moveNext())
+        {
+          switch(tokenType)
+          {
+            case Keyword:
+            {
+              String operator = (String)token;
+              if(operator.equals(BeginBaseFontCharOperator)
+                || operator.equals(BeginCIDCharOperator))
+              {
+                /*
+                  NOTE: The first element on each line is the input code of the template font;
+                  the second element is the code or name of the character.
+                */
+                for(
+                  int itemIndex = 0;
+                  itemIndex < itemCount;
+                  itemIndex++
+                  )
+                {
+                  // 1. Input code.
+                  moveNext();
+                  ByteArray inputCode = new ByteArray((byte[])token);
+                  // 2. Character...
+                  moveNext();
+                  switch(tokenType)
+                  {
+                    case Hex: // ...code (hex).
+                      codes.put(inputCode,ConvertUtils.byteArrayToInt((byte[])token));
+                      break;
+                    case Integer: // ...code (plain).
+                      codes.put(inputCode,(Integer)token);
+                      break;
+                    case Name: // ...name.
+                      codes.put(inputCode,GlyphMapping.nameToCode((String)token));
+                      break;
+                    default:
+                      throw new RuntimeException(
+                        operator + " section syntax error: hex string, integer or name expected instead of " + tokenType
+                        );
+                  }
+                }
+              }
+              else if(operator.equals(BeginBaseFontRangeOperator)
+                || operator.equals(BeginCIDRangeOperator))
+              {
+                /*
+                  NOTE: The first and second elements in each line are the beginning and
+                  ending valid input codes for the template font; the third element is
+                  the beginning character code for the range.
+                */
+                for(
+                  int itemIndex = 0;
+                  itemIndex < itemCount;
+                  itemIndex++
+                  )
+                {
+                  // 1. Beginning input code.
+                  moveNext();
+                  byte[] beginInputCode = (byte[])token;
+                  // 2. Ending input code.
+                  moveNext();
+                  byte[] endInputCode = (byte[])token;
+                  // 3. Character codes.
+                  moveNext();
+                  switch(tokenType)
+                  {
+                    case Hex:
+                    case Integer:
+                    {
+                      byte[] inputCode = beginInputCode;
+                      int charCode;
+                      switch(tokenType)
+                      {
+                        case Hex:
+                          charCode = ConvertUtils.byteArrayToInt((byte[])token);
+                          break;
+                        case Integer:
+                          charCode = (Integer)token;
+                          break;
+                        default:
+                          throw new RuntimeException(
+                            operator + " section syntax error: hex string or integer expected instead of " + tokenType
+                            );
+                      }
+                      int endCharCode = charCode + (ConvertUtils.byteArrayToInt(endInputCode) - ConvertUtils.byteArrayToInt(beginInputCode));
+                      while(true)
+                      {
+                        codes.put(new ByteArray(inputCode),charCode);
+                        if(charCode == endCharCode)
+                          break;
+
+                        OperationUtils.increment(inputCode);
+                        charCode++;
+                      }
+                      break;
+                    }
+                    case ArrayBegin:
+                    {
+                      byte[] inputCode = beginInputCode;
+                      while(moveNext()
+                        && tokenType != TokenTypeEnum.ArrayEnd)
+                      {
+                        codes.put(new ByteArray(inputCode),GlyphMapping.nameToCode((String)token));
+                        OperationUtils.increment(inputCode);
+                      }
+                      break;
+                    }
+                    default:
+                      throw new RuntimeException(
+                        operator + " section syntax error: hex string, integer or name array expected instead of " + tokenType
+                        );
+                  }
+                }
+              }
+              break;
+            }
+            case Integer:
+            {
+              itemCount = (Integer)token;
+              break;
+            }
+          }
+        }
+      }
+      catch(FileFormatException fileFormatException)
+      {throw new RuntimeException(fileFormatException);}
+    }
+    return codes;
+  }
+
+  public void seek(
+    long position
+    )
+  {
+    if(position < 0)
+      throw new IllegalArgumentException("The 'position' argument is lower than acceptable.");
+    if(position > stream.getLength())
+      throw new IllegalArgumentException("The 'position' argument is higher than acceptable.");
+
+    stream.seek(position);
+  }
+
+  public void skip(
+    long offset
+    )
+  {
+    long position = stream.getPosition() + offset;
+    if(position < 0)
+      throw new IllegalArgumentException("The 'offset' argument is lower than acceptable.");
+    if(position > stream.getLength())
+      throw new IllegalArgumentException("The 'offset' argument is higher than acceptable.");
+
+    stream.skip(position);
+  }
+
+  /**
+    Moves to the last whitespace after the current position in order to let read
+    the first non-whitespace.
+  */
+  public boolean skipWhitespace(
+    )
+  {
+    int b;
+    try
+    {
+      do
+      {b = stream.readUnsignedByte();} while(isWhitespace(b)); // Keep goin' till there's a white-space character...
+    }
+    catch(EOFException e)
+    {return false;}
+    stream.skip(-1); // Recover the last whitespace position.
+
+    return true;
+  }
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/CompositeFont.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/CompositeFont.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/CompositeFont.java	(revision 23703)
@@ -0,0 +1,624 @@
+/*
+  Copyright 2009-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.fonts;
+
+import it.stefanochizzolini.clown.bytes.Buffer;
+import it.stefanochizzolini.clown.bytes.IInputStream;
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.objects.PdfArray;
+import it.stefanochizzolini.clown.objects.PdfDataObject;
+import it.stefanochizzolini.clown.objects.PdfDictionary;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfInteger;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfReal;
+import it.stefanochizzolini.clown.objects.PdfReference;
+import it.stefanochizzolini.clown.objects.PdfStream;
+import it.stefanochizzolini.clown.objects.PdfTextString;
+import it.stefanochizzolini.clown.objects.Rectangle;
+import it.stefanochizzolini.clown.util.BiMap;
+import it.stefanochizzolini.clown.util.ByteArray;
+import it.stefanochizzolini.clown.util.ConvertUtils;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.awt.geom.Point2D;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+  Composite font [PDF:1.6:5.6], also called Type 0 font.
+  <h3>Remarks</h3>
+  <p>Do not confuse it with 'Type 0 CIDFont': the latter is a composite font descendant
+  describing glyphs based on Adobe Type 1 font format (see Type0Font).</p>
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.8
+  @version 0.0.8
+*/
+public abstract class CompositeFont
+  extends Font
+{
+  // <class>
+  // <static>
+  // <fields>
+  private static final String HexPadding = "0000";
+  // </fields>
+
+  // <interface>
+  // <public>
+  public static CompositeFont get(
+    Document context,
+    IInputStream fontData
+    )
+  {
+    OpenFontParser parser = new OpenFontParser(fontData);
+    switch(parser.outlineFormat)
+    {
+      case CFF:
+        return new Type0Font(context,parser);
+      case TrueType:
+        return new Type2Font(context,parser);
+    }
+    throw new UnsupportedOperationException("Unknown composite font format.");
+  }
+  // </public>
+
+  // <private>
+  private static String getHex(
+    int value
+    )
+  {
+    String hex = Integer.toHexString(value);
+
+    return HexPadding.substring(hex.length()) + hex;
+  }
+  // </private>
+  // </interface>
+  // </static>
+
+  // <dynamic>
+  // <fields>
+  // </fields>
+
+  // <constructors>
+  protected CompositeFont(
+    Document context,
+    OpenFontParser parser
+    )
+  {
+    super(context);
+
+    load(parser);
+  }
+
+  protected CompositeFont(
+    PdfDirectObject baseObject
+    )
+  {super(baseObject);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public CompositeFont clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+  // </public>
+
+  // <protected>
+  /**
+    Gets the CIDFont dictionary that is the descendant of this composite font.
+  */
+  protected PdfDictionary getCIDFontDictionary(
+    )
+  {return (PdfDictionary)((PdfArray)getBaseDataObject().resolve(PdfName.DescendantFonts)).resolve(0);}
+
+  @Override
+  protected PdfDictionary getDescriptor(
+    )
+  {return (PdfDictionary)getCIDFontDictionary().resolve(PdfName.FontDescriptor);}
+
+  protected void loadEncoding(
+    )
+  {
+    PdfDataObject encodingObject = getBaseDataObject().resolve(PdfName.Encoding);
+
+    // CMap [PDF:1.6:5.6.4].
+    Map<ByteArray,Integer> cmap = CMap.get(encodingObject);
+
+    // 1. Unicode.
+    if(codes == null)
+    {
+      codes = new BiMap<ByteArray,Integer>();
+      if(encodingObject instanceof PdfName
+        && !(encodingObject.equals(PdfName.IdentityH)
+          || encodingObject.equals(PdfName.IdentityV)))
+      {
+        /*
+          NOTE: According to [PDF:1.6:5.9.1], the fallback method to retrieve
+          the character-code-to-Unicode mapping implies getting the UCS2 CMap
+          (Unicode value to CID) corresponding to the font's one (character code to CID);
+          CIDs are the bridge from character codes to Unicode values.
+        */
+        BiMap<ByteArray,Integer> ucs2CMap;
+        {
+          PdfDictionary cidSystemInfo = (PdfDictionary)getCIDFontDictionary().resolve(PdfName.CIDSystemInfo);
+          String registry = (String)((PdfTextString)cidSystemInfo.get(PdfName.Registry)).getValue();
+          String ordering = (String)((PdfTextString)cidSystemInfo.get(PdfName.Ordering)).getValue();
+          String ucs2CMapName = registry + "-" + ordering + "-" + "UCS2";
+          ucs2CMap = new BiMap<ByteArray,Integer>(CMap.get(ucs2CMapName));
+        }
+        if(!ucs2CMap.isEmpty())
+        {
+          for(Map.Entry<ByteArray,Integer> cmapEntry : cmap.entrySet())
+          {codes.put(cmapEntry.getKey(),ConvertUtils.byteArrayToInt(ucs2CMap.getKey(cmapEntry.getValue()).data));}
+        }
+      }
+      if(codes.isEmpty())
+      {
+        /*
+          NOTE: In case no clue is available to determine the Unicode resolution map,
+          the font is considered symbolic and an identity map is synthesized instead.
+         */
+        symbolic = true;
+        for(Map.Entry<ByteArray,Integer> cmapEntry : cmap.entrySet())
+        {codes.put(cmapEntry.getKey(),ConvertUtils.byteArrayToInt(cmapEntry.getKey().data));}
+      }
+    }
+
+    // 2. Glyph indexes.
+    /*
+    TODO: gids map for glyph indexes as glyphIndexes is used to map cids!!!
+    */
+    // Character-code-to-CID mapping [PDF:1.6:5.6.4,5].
+    glyphIndexes = new Hashtable<Integer,Integer>();
+    for(Map.Entry<ByteArray,Integer> cmapEntry : cmap.entrySet())
+    {
+      if(!codes.containsKey(cmapEntry.getKey()))
+        continue;
+
+      glyphIndexes.put(codes.get(cmapEntry.getKey()),cmapEntry.getValue());
+    }
+  }
+
+  @Override
+  protected void onLoad(
+    )
+  {
+    loadEncoding();
+
+    // Glyph widths.
+    {
+      glyphWidths = new Hashtable<Integer,Integer>();
+      PdfArray glyphWidthObjects = (PdfArray)getCIDFontDictionary().resolve(PdfName.W);
+      if(glyphWidthObjects != null)
+      {
+        for(Iterator<PdfDirectObject> iterator = glyphWidthObjects.iterator(); iterator.hasNext();)
+        {
+          //TODO: this algorithm is valid only in case cid-to-gid mapping is identity (see cidtogid map)!!
+          /*
+            NOTE: Font widths are grouped in one of the following formats [PDF:1.6:5.6.3]:
+              1. startCID [glyphWidth1 glyphWidth2 ... glyphWidthn]
+              2. startCID endCID glyphWidth
+          */
+          int startCID = ((PdfInteger)iterator.next()).getRawValue();
+          PdfDirectObject glyphWidthObject2 = iterator.next();
+          if(glyphWidthObject2 instanceof PdfArray) // Format 1: startCID [glyphWidth1 glyphWidth2 ... glyphWidthn].
+          {
+            int cID = startCID;
+            for(PdfDirectObject glyphWidthObject : (PdfArray)glyphWidthObject2)
+            {glyphWidths.put(cID++,((PdfInteger)glyphWidthObject).getRawValue());}
+          }
+          else // Format 2: startCID endCID glyphWidth.
+          {
+            int endCID = ((PdfInteger)glyphWidthObject2).getRawValue();
+            int glyphWidth = ((PdfInteger)iterator.next()).getRawValue();
+            for(int cID = startCID; cID <= endCID; cID++)
+            {glyphWidths.put(cID,glyphWidth);}
+          }
+        }
+      }
+    }
+    // Default glyph width.
+    {
+      PdfInteger defaultGlyphWidthObject = (PdfInteger)getBaseDataObject().get(PdfName.W);
+      defaultGlyphWidth = (defaultGlyphWidthObject == null ? 0 : defaultGlyphWidthObject.getRawValue());
+    }
+  }
+  // </protected>
+
+  // <private>
+  /**
+    Loads the font data.
+  */
+  private void load(
+    OpenFontParser parser
+    )
+  {
+    try
+    {
+      glyphIndexes = parser.glyphIndexes;
+      glyphKernings = parser.glyphKernings;
+      glyphWidths = parser.glyphWidths;
+
+      PdfDictionary baseDataObject = getBaseDataObject();
+
+      // BaseFont.
+      baseDataObject.put(PdfName.BaseFont,new PdfName(parser.fontName));
+
+      // Subtype.
+      baseDataObject.put(PdfName.Subtype, PdfName.Type0);
+
+      // Encoding.
+      baseDataObject.put(PdfName.Encoding, PdfName.IdentityH); //TODO: this is a simplification (to refine later).
+
+      // Descendant font.
+      PdfDictionary cidFontDictionary = new PdfDictionary(
+        new PdfName[]{PdfName.Type},
+        new PdfDirectObject[]{PdfName.Font}
+        ); // CIDFont dictionary [PDF:1.6:5.6.3].
+      {
+        // Subtype.
+        PdfName subType;
+        switch(parser.outlineFormat)
+        {
+          case TrueType: subType = PdfName.CIDFontType2; break;
+          case CFF: subType = PdfName.CIDFontType0; break;
+          default: throw new NotImplementedException();
+        }
+        cidFontDictionary.put(PdfName.Subtype,subType);
+
+        // BaseFont.
+        cidFontDictionary.put(
+          PdfName.BaseFont,
+          new PdfName(parser.fontName)
+          );
+
+        // CIDSystemInfo.
+        cidFontDictionary.put(
+          PdfName.CIDSystemInfo,
+          new PdfDictionary(
+            new PdfName[]
+            {
+              PdfName.Registry,
+              PdfName.Ordering,
+              PdfName.Supplement
+            },
+            new PdfDirectObject[]
+            {
+              new PdfTextString("Adobe"),
+              new PdfTextString("Identity"),
+              new PdfInteger(0)
+            }
+            )
+          ); // Generic predefined CMap (Identity-H/V (Adobe-Identity-0)) [PDF:1.6:5.6.4].
+
+        // FontDescriptor.
+        cidFontDictionary.put(
+          PdfName.FontDescriptor,
+          load_createFontDescriptor(parser)
+          );
+
+        // Encoding.
+        load_createEncoding(baseDataObject,cidFontDictionary);
+      }
+      baseDataObject.put(
+        PdfName.DescendantFonts,
+        new PdfArray(new PdfDirectObject[]{getFile().register(cidFontDictionary)})
+        );
+    }
+    catch(Exception e)
+    {throw new RuntimeException(e);}
+
+    load();
+  }
+
+  /**
+    Creates the character code mapping for composite fonts.
+  */
+  private void load_createEncoding(
+    PdfDictionary font,
+    PdfDictionary cidFont
+    )
+  {
+    // CMap [PDF:1.6:5.6.4].
+    Buffer cmapBuffer = new Buffer();
+    cmapBuffer.append(
+      "%!PS-Adobe-3.0 Resource-CMap\n"
+        + "%%DocumentNeededResources: ProcSet (CIDInit)\n"
+        + "%%IncludeResource: ProcSet (CIDInit)\n"
+        + "%%BeginResource: CMap (Adobe-Identity-UCS)\n"
+        + "%%Title: (Adobe-Identity-UCS Adobe Identity 0)\n"
+        + "%%Version: 1\n"
+        + "%%EndComments\n"
+        + "/CIDInit /ProcSet findresource begin\n"
+        + "12 dict begin\n"
+        + "begincmap\n"
+        + "/CIDSystemInfo\n"
+        + "3 dict dup begin\n"
+        + "/Registry (Adobe) def\n"
+        + "/Ordering (Identity) def\n"
+        + "/Supplement 0 def\n"
+        + "end def\n"
+        + "/CMapName /Adobe-Identity-UCS def\n"
+        + "/CMapVersion 1 def\n"
+        + "/CMapType 0 def\n"
+        + "/WMode 0 def\n"
+        + "2 begincodespacerange\n"
+        + "<20> <20>\n"
+        + "<0000> <19FF>\n"
+        + "endcodespacerange\n"
+        + glyphIndexes.size() + " begincidchar\n"
+      );
+    // ToUnicode [PDF:1.6:5.9.2].
+    Buffer toUnicodeBuffer = new Buffer();
+    toUnicodeBuffer.append(
+      "/CIDInit /ProcSet findresource begin\n"
+        + "12 dict begin\n"
+        + "begincmap\n"
+        + "/CIDSystemInfo\n"
+        + "<< /Registry (Adobe)\n"
+        + "/Ordering (UCS)\n"
+        + "/Supplement 0\n"
+        + ">> def\n"
+        + "/CMapName /Adobe-Identity-UCS def\n"
+        + "/CMapVersion 10.001 def\n"
+        + "/CMapType 2 def\n"
+        + "2 begincodespacerange\n"
+        + "<20> <20>\n"
+        + "<0000> <19FF>\n"
+        + "endcodespacerange\n"
+        + glyphIndexes.size() + " beginbfchar\n"
+      );
+    // CIDToGIDMap [PDF:1.6:5.6.3].
+    Buffer gIdBuffer = new Buffer();
+    gIdBuffer.append((byte)0);
+    gIdBuffer.append((byte)0);
+    int code = 0;
+    codes = new BiMap<ByteArray,Integer>(glyphIndexes.size());
+    PdfArray widthsObject = new PdfArray(glyphWidths.size());
+    for(Map.Entry<Integer,Integer> glyphIndexEntry : glyphIndexes.entrySet())
+    {
+      // Character code (codepoint to unicode) entry.
+      code++;
+      byte[] charCode = (glyphIndexEntry.getKey() == 32
+        ? new byte[]{32}
+        : new byte[]
+          {
+            (byte)((code >> 8) & 0xFF),
+            (byte)(code & 0xFF)
+          });
+      codes.put(new ByteArray(charCode),glyphIndexEntry.getKey());
+
+      // CMap entry.
+      cmapBuffer.append("<");
+      toUnicodeBuffer.append("<");
+      for(int charCodeBytesIndex = 0,
+          charCodeBytesLength = charCode.length;
+        charCodeBytesIndex < charCodeBytesLength;
+        charCodeBytesIndex++
+        )
+      {
+        String hex = Integer.toHexString((int)charCode[charCodeBytesIndex]);
+        //TODO:improve hex padding!!!
+        if(hex.length() == 1)
+        {hex = "0" + hex;}
+        else
+        {hex = hex.substring(hex.length()-2,hex.length());}
+        cmapBuffer.append(hex);
+        toUnicodeBuffer.append(hex);
+      }
+      cmapBuffer.append("> " + code + "\n");
+      toUnicodeBuffer.append("> <" + getHex(glyphIndexEntry.getKey()) + ">\n");
+
+      // CID-to-GID entry.
+      int glyphIndex = glyphIndexEntry.getValue();
+      gIdBuffer.append((byte)((glyphIndex >> 8) & 0xFF));
+      gIdBuffer.append((byte)(glyphIndex & 0xFF));
+
+      // Width.
+      int width;
+      try
+      {width = glyphWidths.get(glyphIndex);if(width>1000){width=1000;}}
+      catch(Exception e)
+      {width = 0;}
+      widthsObject.add(new PdfInteger(width));
+    }
+    cmapBuffer.append(
+      "endcidchar\n"
+        + "endcmap\n"
+        + "CMapName currentdict /CMap defineresource pop\n"
+        + "end\n"
+        + "end\n"
+        + "%%EndResource\n"
+        + "%%EOF"
+      );
+    PdfStream cmapStream = new PdfStream(cmapBuffer);
+    PdfDictionary cmapHead = cmapStream.getHeader();
+    cmapHead.put(
+      PdfName.Type,
+      PdfName.CMap
+      );
+    cmapHead.put(
+      PdfName.CMapName,
+      new PdfName("Adobe-Identity-UCS")
+      );
+    cmapHead.put(
+      PdfName.CIDSystemInfo,
+      new PdfDictionary(
+        new PdfName[]
+        {
+          PdfName.Registry,
+          PdfName.Ordering,
+          PdfName.Supplement
+        },
+        new PdfDirectObject[]
+        {
+          new PdfTextString("Adobe"),
+          new PdfTextString("Identity"),
+          new PdfInteger(0)
+        }
+        )
+      ); // Generic predefined CMap (Identity-H/V (Adobe-Identity-0)) [PDF:1.6:5.6.4].
+    font.put(
+      PdfName.Encoding,
+      getFile().register(cmapStream)
+      );
+
+    PdfStream gIdStream = new PdfStream(gIdBuffer);
+    cidFont.put(
+      PdfName.CIDToGIDMap,
+      getFile().register(gIdStream)
+      );
+
+    cidFont.put(
+      PdfName.W,
+      new PdfArray(new PdfDirectObject[]{new PdfInteger(1),widthsObject})
+      );
+
+    toUnicodeBuffer.append(
+      "endbfchar\n"
+        + "endcmap\n"
+        + "CMapName currentdict /CMap defineresource pop\n"
+        + "end\n"
+        + "end\n"
+      );
+    PdfStream toUnicodeStream = new PdfStream(toUnicodeBuffer);
+    font.put(
+      PdfName.ToUnicode,
+      getFile().register(toUnicodeStream)
+      );
+  }
+
+  /**
+    Creates the font descriptor.
+  */
+  private PdfReference load_createFontDescriptor(
+    OpenFontParser parser
+    )
+  {
+    PdfDictionary fontDescriptor = new PdfDictionary();
+    {
+      OpenFontParser.FontMetrics metrics = parser.metrics;
+
+      // Type.
+      fontDescriptor.put(
+        PdfName.Type,
+        PdfName.FontDescriptor
+        );
+      // FontName.
+      fontDescriptor.put(
+        PdfName.FontName,
+        getBaseDataObject().get(PdfName.BaseFont)
+        );
+      // Flags [PDF:1.6:5.7.1].
+      int flags = 0;
+      if(metrics.isFixedPitch)
+      {flags |= FlagsEnum.FixedPitch.getCode();}
+      if(metrics.isCustomEncoding)
+      {flags |= FlagsEnum.Symbolic.getCode();}
+      else
+      {flags |= FlagsEnum.Nonsymbolic.getCode();}
+      fontDescriptor.put(
+        PdfName.Flags,
+        new PdfInteger(flags)
+        );
+      // FontBBox.
+      fontDescriptor.put(
+        PdfName.FontBBox,
+        new Rectangle(
+          new Point2D.Double(metrics.xMin * metrics.unitNorm, metrics.yMin * metrics.unitNorm),
+          new Point2D.Double(metrics.xMax * metrics.unitNorm, metrics.yMax * metrics.unitNorm)
+          ).getBaseDataObject()
+        );
+      // ItalicAngle.
+      fontDescriptor.put(
+        PdfName.ItalicAngle,
+        new PdfReal(metrics.italicAngle)
+        );
+      // Ascent.
+      fontDescriptor.put(
+        PdfName.Ascent,
+        new PdfReal(
+          metrics.ascender == 0
+            ? metrics.sTypoAscender * metrics.unitNorm
+            : metrics.ascender * metrics.unitNorm
+          )
+        );
+      // Descent.
+      fontDescriptor.put(
+        PdfName.Descent,
+        new PdfReal(
+          metrics.descender == 0
+            ? metrics.sTypoDescender * metrics.unitNorm
+            : metrics.descender * metrics.unitNorm
+          )
+        );
+      // Leading.
+      fontDescriptor.put(
+        PdfName.Leading,
+        new PdfReal(metrics.sTypoLineGap * metrics.unitNorm)
+        );
+      // CapHeight.
+      fontDescriptor.put(
+        PdfName.CapHeight,
+        new PdfReal(metrics.sCapHeight * metrics.unitNorm)
+        );
+      // StemV.
+      /*
+        NOTE: '100' is just a rule-of-thumb value, 'cause I've still to solve the
+        'cvt' table puzzle (such a harsh headache!) for TrueType fonts...
+        TODO:IMPL TrueType and CFF stemv real value to extract!!!
+      */
+      fontDescriptor.put(
+        PdfName.StemV,
+        new PdfInteger(100)
+        );
+      // FontFile.
+  //TODO:IMPL distinguish between truetype (FontDescriptor.FontFile2) and opentype (FontDescriptor.FontFile3 and FontStream.subtype=OpenType)!!!
+      PdfReference fontFileReference = getFile().register(
+        new PdfStream(
+          new PdfDictionary(
+            new PdfName[]{PdfName.Subtype},
+            new PdfDirectObject[]{PdfName.OpenType}
+            ),
+          new Buffer(parser.fontData.toByteArray())
+          )
+        );
+      fontDescriptor.put(
+        PdfName.FontFile3,
+        fontFileReference
+        );
+    }
+    return getFile().register(fontDescriptor);
+  }
+  // </private>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/Encoding.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/Encoding.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/Encoding.java	(revision 23703)
@@ -0,0 +1,88 @@
+/*
+  Copyright 2009 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.fonts;
+
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.util.ByteArray;
+
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+
+/**
+  Predefined encodings [PDF:1.6:5.5.5,D].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+  @since 0.0.8
+*/
+class Encoding
+{
+  // <static>
+  // <fields>
+  private static final Map<PdfName,Encoding> Encodings = new HashMap<PdfName,Encoding>();
+  // </fields>
+
+  // <constructors>
+  static
+  {
+  //TODO:this collection MUST be automatically populated looking for Encoding subclasses!
+    Encodings.put(PdfName.StandardEncoding,new StandardEncoding());
+    Encodings.put(PdfName.MacRomanEncoding,new MacRomanEncoding());
+    Encodings.put(PdfName.WinAnsiEncoding,new WinAnsiEncoding());
+  }
+  // </constructors>
+
+  // <interface>
+  public static Encoding get(
+    PdfName name
+    )
+  {return Encodings.get(name);}
+  // </interface>
+  // </static>
+
+  // <dynamic>
+  // <fields>
+  private Hashtable<ByteArray,Integer> codes = new Hashtable<ByteArray,Integer>();
+  // </fields>
+
+  // <interface>
+  // <public>
+  public Map<ByteArray,Integer> getCodes(
+    )
+  {return new Hashtable<ByteArray,Integer>(codes);}
+  // </public>
+
+  // <protected>
+  protected void put(
+    int charCode,
+    String charName
+    )
+  {codes.put(new ByteArray(new byte[]{(byte)charCode}),GlyphMapping.nameToCode(charName));}
+  // </protected>
+  // </interface>
+  // </dynamic>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/Font.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/Font.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/Font.java	(revision 23703)
@@ -0,0 +1,777 @@
+/*
+  Copyright 2006-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.fonts;
+
+import it.stefanochizzolini.clown.bytes.FileInputStream;
+import it.stefanochizzolini.clown.bytes.IInputStream;
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.files.File;
+import it.stefanochizzolini.clown.objects.IPdfNumber;
+import it.stefanochizzolini.clown.objects.PdfArray;
+import it.stefanochizzolini.clown.objects.PdfDictionary;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfInteger;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfObjectWrapper;
+import it.stefanochizzolini.clown.objects.PdfReference;
+import it.stefanochizzolini.clown.objects.PdfStream;
+import it.stefanochizzolini.clown.util.BiMap;
+import it.stefanochizzolini.clown.util.ByteArray;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.io.ByteArrayOutputStream;
+import java.util.EnumSet;
+import java.util.Hashtable;
+import java.util.Map;
+
+/**
+  Abstract font [PDF:1.6:5.4].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+*/
+public abstract class Font
+  extends PdfObjectWrapper<PdfDictionary>
+{
+  // <class>
+  // <classes>
+  /**
+    Font descriptor flags [PDF:1.6:5.7.1].
+  */
+  public enum FlagsEnum
+  {
+    // <class>
+    // <static>
+    // <fields>
+    /**
+      All glyphs have the same width.
+    */
+    FixedPitch(0x1),
+    /**
+      Glyphs have serifs.
+    */
+    Serif(0x2),
+    /**
+      Font contains glyphs outside the Adobe standard Latin character set.
+    */
+    Symbolic(0x4),
+    /**
+      Glyphs resemble cursive handwriting.
+    */
+    Script(0x8),
+    /**
+      Font uses the Adobe standard Latin character set.
+    */
+    Nonsymbolic(0x20),
+    /**
+      Glyphs have dominant vertical strokes that are slanted.
+    */
+    Italic(0x40),
+    /**
+      Font contains no lowercase letters.
+    */
+    AllCap(0x10000),
+    /**
+      Font contains both uppercase and lowercase letters.
+    */
+    SmallCap(0x20000),
+    /**
+      Thicken bold glyphs at small text sizes.
+    */
+    ForceBold(0x40000);
+    // </fields>
+
+    // <interface>
+    // <public>
+    /**
+      Converts an enumeration set into its corresponding bit mask representation.
+    */
+    public static int toInt(
+      EnumSet<FlagsEnum> flags
+      )
+    {
+      int flagsMask = 0;
+      for(FlagsEnum flag : flags)
+      {flagsMask |= flag.getCode();}
+
+      return flagsMask;
+    }
+
+    /**
+      Converts a bit mask into its corresponding enumeration representation.
+    */
+    public static EnumSet<FlagsEnum> toEnumSet(
+      int flagsMask
+      )
+    {
+      EnumSet<FlagsEnum> flags = EnumSet.noneOf(FlagsEnum.class);
+      for(FlagsEnum flag : FlagsEnum.values())
+      {
+        if((flagsMask & flag.getCode()) > 0)
+        {flags.add(flag);}
+      }
+
+      return flags;
+    }
+    // </public>
+    // </interface>
+    // </static>
+
+    // <dynamic>
+    // <fields>
+    /**
+      <h3>Remarks</h3>
+      <p>Bitwise code MUST be explicitly distinct from the ordinal position of the enum constant
+      as they don't coincide.</p>
+    */
+    private final int code;
+    // </fields>
+
+    // <constructors>
+    private FlagsEnum(
+      int code
+      )
+    {this.code = code;}
+    // </constructors>
+
+    // <interface>
+    // <public>
+    public int getCode(
+      )
+    {return code;}
+    // </public>
+    // </interface>
+    // </dynamic>
+    // </class>
+  }
+  // </classes>
+
+  // <static>
+  // <interface>
+  // <public>
+  /**
+   * Creates the representation of a font.
+   */
+  public static Font get(
+    Document context,
+    String path
+    )
+  {
+    try
+    {
+      return get(
+        context,
+        new FileInputStream(
+          new java.io.RandomAccessFile(path,"r")
+          )
+        );
+    }
+    catch(Exception e)
+    {throw new RuntimeException(e);}
+  }
+
+  /**
+   * Creates the representation of a font.
+   */
+  public static Font get(
+    Document context,
+    java.io.File file
+    )
+  {return get(context,file.getPath());}
+
+  /**
+   * Creates the representation of a font.
+   */
+  public static Font get(
+    Document context,
+    IInputStream fontData
+    )
+  {
+    if(OpenFontParser.isOpenFont(fontData))
+      return CompositeFont.get(context,fontData);
+    else
+      throw new NotImplementedException();
+   }
+
+  /**
+    Gets the scaling factor to be applied to unscaled metrics to get actual measures.
+  */
+  public static final double getScalingFactor(
+    double size
+    )
+  {return (0.001 * size);}
+
+  /**
+    Wraps a font reference into a font object.
+
+    @param reference Reference to a font object.
+    @return Font object associated to the reference.
+  */
+  public static final Font wrap(
+    PdfReference reference
+    )
+  {
+    if(reference == null)
+      return null;
+
+    {
+      // Has the font been already instantiated?
+      /*
+        NOTE: Font structures are reified as complex objects, both IO- and CPU-intensive to load.
+        So, it's convenient to retrieve them from a common cache whenever possible.
+      */
+      Hashtable<PdfReference,Object> cache = reference.getIndirectObject().getFile().getDocument().cache;
+      if(cache.containsKey(reference))
+        return (Font)cache.get(reference);
+    }
+
+    PdfDictionary fontDictionary = (PdfDictionary)reference.getDataObject();
+    PdfName fontType = (PdfName)fontDictionary.get(PdfName.Subtype);
+    if(fontType == null)
+      throw new RuntimeException("Font type undefined (reference: " + reference + ")");
+
+    if(fontType.equals(PdfName.Type1)) // Type 1.
+    {
+      if(!fontDictionary.containsKey(PdfName.FontDescriptor)) // Standard Type 1.
+        return new StandardType1Font(reference);
+      else // Custom Type 1.
+      {
+        PdfDictionary fontDescriptor = (PdfDictionary)fontDictionary.resolve(PdfName.FontDescriptor);
+        if(fontDescriptor.containsKey(PdfName.FontFile3)
+            && ((PdfName)((PdfStream)fontDescriptor.resolve(PdfName.FontFile3)).getHeader().resolve(PdfName.Subtype)).equals(PdfName.OpenType)) // OpenFont/CFF.
+          throw new NotImplementedException();
+        else // Non-OpenFont Type 1.
+          return new Type1Font(reference);
+      }
+    }
+    else if(fontType.equals(PdfName.TrueType)) // TrueType.
+      return new TrueTypeFont(reference);
+    else if(fontType.equals(PdfName.Type0)) // OpenFont.
+    {
+      PdfDictionary cidFontDictionary = (PdfDictionary)((PdfArray)fontDictionary.resolve(PdfName.DescendantFonts)).resolve(0);
+      PdfName cidFontType = (PdfName)cidFontDictionary.get(PdfName.Subtype);
+      if(cidFontType.equals(PdfName.CIDFontType0)) // OpenFont/CFF.
+        return new Type0Font(reference);
+      else if(cidFontType.equals(PdfName.CIDFontType2)) // OpenFont/TrueType.
+        return new Type2Font(reference);
+      else
+        throw new NotImplementedException("Type 0 subtype " + cidFontType + " not supported yet.");
+    }
+    else if(fontType.equals(PdfName.Type3)) // Type 3.
+      return new Type3Font(reference);
+    else if(fontType.equals(PdfName.MMType1)) // MMType1.
+      return new MMType1Font(reference);
+    else // Unknown.
+      throw new UnsupportedOperationException("Unknown font type: " + fontType + " (reference: " + reference + ")");
+  }
+  // </public>
+  // </interface>
+  // </static>
+
+  // <dynamic>
+  // <fields>
+  /*
+    NOTE: In order to avoid nomenclature ambiguities, these terms are used consistently within the code:
+    * unicode: character encoded according to the Unicode standard;
+    * character code: codepoint corresponding to a character expressed inside a string object of a content stream;
+    * glyph index: identifier of the graphical representation of a character.
+  */
+  /**
+    Unicodes by character code.
+    <h3>Note</h3>
+    <p>When this map is populated, {@link #symbolic} variable shall accordingly be set.</p>
+  */
+  protected BiMap<ByteArray,Integer> codes;
+  /**
+    Default glyph width.
+  */
+  protected int defaultGlyphWidth;
+  /**
+    Glyph indexes by unicode.
+  */
+  protected Map<Integer,Integer> glyphIndexes;
+  /**
+    Glyph kernings by (left-right) glyph index pairs.
+  */
+  protected Map<Integer,Integer> glyphKernings;
+  /**
+    Glyph widths by glyph index.
+  */
+  protected Map<Integer,Integer> glyphWidths;
+  /**
+    Whether the font encoding is custom (that is non-Unicode).
+  */
+  protected boolean symbolic = true;
+
+  /**
+    Maximum character code byte size.
+  */
+  private int charCodeMaxLength = 0;
+  // </fields>
+
+  // <constructors>
+  /**
+    Creates a new font structure within the given document context.
+  */
+  protected Font(
+    Document context
+    )
+  {
+    super(
+      context.getFile(),
+      new PdfDictionary(
+        new PdfName[]{PdfName.Type},
+        new PdfDirectObject[]{PdfName.Font}
+        )
+      );
+    initialize();
+  }
+
+  /**
+    Loads an existing font structure.
+  */
+  protected Font(
+    PdfDirectObject baseObject
+    )
+  {
+    super(
+      baseObject,
+      null // NO container. NOTE: this is a simplification (the spec [PDF:1.6] doesn't apparently prescribe the use of an indirect object for font dictionary, whilst the general practice is as such. If an exception occurs, you'll need to specify the proper container).
+      );
+    initialize();
+    load();
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  /**
+    Gets the text from the given internal representation.
+
+    @param code Internal representation to decode.
+    @since 0.0.6
+  */
+  public final String decode(
+    byte[] code
+    )
+  {
+    StringBuilder textBuilder = new StringBuilder();
+    {
+      byte[][] codeBuffers = new byte[charCodeMaxLength+1][];
+      for(
+        int codeBufferIndex = 0;
+        codeBufferIndex <= charCodeMaxLength;
+        codeBufferIndex++
+        )
+      {codeBuffers[codeBufferIndex] = new byte[codeBufferIndex];}
+      int position = 0;
+      int codeLength = code.length;
+      int codeBufferSize = 1;
+      while(position < codeLength)
+      {
+        byte[] codeBuffer = codeBuffers[codeBufferSize];
+        System.arraycopy(code,position,codeBuffer,0,codeBufferSize);
+        Integer textChar = codes.get(new ByteArray(codeBuffer));
+        if(textChar == null)
+        {
+          if(codeBufferSize < charCodeMaxLength)
+          {
+            codeBufferSize++;
+            continue;
+          }
+          /*
+            NOTE: In case no valid code entry is found, a default space is resiliantely
+            applied instead of throwing an exception.
+            This is potentially risky as failing to determine the actual code length
+            may result in a "code shifting" which could affect following characters.
+           */
+          textChar = (int)' ';
+        }
+        textBuilder.append((char)(int)textChar);
+        position += codeBufferSize;
+        codeBufferSize = 1;
+      }
+    }
+    return textBuilder.toString();
+  }
+
+  /**
+    Gets the internal representation of the given text.
+
+    @param text Text to encode.
+    @since 0.0.6
+  */
+  public final byte[] encode(
+    String text
+    )
+  {
+    ByteArrayOutputStream encodedStream = new ByteArrayOutputStream();
+    try
+    {
+      for(char textChar : text.toCharArray())
+      {
+        byte[] charCode = codes.getKey((int)textChar).data;
+        encodedStream.write(charCode);
+      }
+      encodedStream.close();
+    }
+    catch(Exception exception)
+    {throw new RuntimeException(exception);}
+
+    return encodedStream.toByteArray();
+  }
+
+  public final boolean equals(
+    Font object
+    )
+  {
+    return (getType().equals(object.getType())
+      && getName().equals(object.getName()));
+  }
+
+  /**
+    Gets the unscaled vertical offset from the baseline to the ascender line (ascent).
+    The value is a positive number.
+  */
+  public double getAscent(
+    )
+  {return ((IPdfNumber)getDescriptor().get(PdfName.Ascent)).getNumberValue();}
+
+  /**
+    Gets the vertical offset from the baseline to the ascender line (ascent),
+    scaled to the given font size.
+    The value is a positive number.
+
+    @param size Font size.
+  */
+  public final double getAscent(
+    double size
+    )
+  {return getAscent() * getScalingFactor(size);}
+
+  /**
+    Gets the unscaled vertical offset from the baseline to the descender line (descent).
+    The value is a negative number.
+  */
+  public double getDescent(
+    )
+  {return ((IPdfNumber)getDescriptor().get(PdfName.Descent)).getNumberValue();}
+
+  /**
+    Gets the vertical offset from the baseline to the descender line (descent), scaled to the given font size.
+    The value is a negative number.
+
+    @param size Font size.
+  */
+  public final double getDescent(
+    double size
+    )
+  {return getDescent() * getScalingFactor(size);}
+
+  /**
+    Gets the font descriptor flags.
+  */
+  public EnumSet<FlagsEnum> getFlags(
+    )
+  {
+    PdfInteger flagsObject = (PdfInteger)File.resolve(
+      getDescriptor().get(PdfName.Flags)
+      );
+    if(flagsObject == null)
+      return EnumSet.noneOf(FlagsEnum.class);
+
+    return FlagsEnum.toEnumSet(flagsObject.getRawValue());
+  }
+
+  /**
+    Gets the unscaled height of the given character.
+
+    @param textChar Character whose height has to be calculated.
+  */
+  public final double getHeight(
+    char textChar
+    )
+  {return getLineHeight();}
+
+  /**
+    Gets the height of the given character, scaled to the given font size.
+
+    @param textChar Character whose height has to be calculated.
+    @param size Font size.
+  */
+  public final double getHeight(
+    char textChar,
+    double size
+    )
+  {return getHeight(textChar) * getScalingFactor(size);}
+
+  /**
+    Gets the unscaled height of the given text.
+
+    @param text Text whose height has to be calculated.
+  */
+  public final double getHeight(
+    String text
+    )
+  {return getLineHeight();}
+
+  /**
+    Gets the height of the given text, scaled to the given font size.
+
+    @param text Text whose height has to be calculated.
+    @param size Font size.
+  */
+  public final double getHeight(
+    String text,
+    double size
+    )
+  {return getHeight(text) * getScalingFactor(size);}
+
+  /**
+    Gets the width (kerning inclusive) of the given text, scaled to the given font size.
+
+    @param text Text whose width has to be calculated.
+    @param size Font size.
+  */
+  public final double getKernedWidth(
+    String text,
+    double size
+    )
+  {return (getWidth(text) + getKerning(text)) * getScalingFactor(size);}
+
+  /**
+    Gets the unscaled kerning width between two given characters.
+
+    @param textChar1 Left character.
+    @param textChar2 Right character,
+  */
+  public final int getKerning(
+    char textChar1,
+    char textChar2
+    )
+  {
+    try
+    {
+      return glyphKernings.get(
+        glyphIndexes.get((int)textChar1) << 16 // Left-hand glyph index.
+          + glyphIndexes.get((int)textChar2) // Right-hand glyph index.
+        );
+    }
+    catch(Exception e)
+    {return 0;}
+  }
+
+  /**
+    Gets the unscaled kerning width inside the given text.
+
+    @param text Text whose kerning has to be calculated.
+  */
+  public final int getKerning(
+    String text
+    )
+  {
+    int kerning = 0;
+    // Are kerning pairs available?
+    if(glyphKernings != null)
+    {
+      char textChars[] = text.toCharArray();
+      for(
+        int index = 0,
+          length = text.length() - 1;
+        index < length;
+        index++
+        )
+      {
+        kerning += getKerning(
+          textChars[index],
+          textChars[index + 1]
+          );
+      }
+    }
+    return kerning;
+  }
+
+  /**
+    Gets the kerning width inside the given text, scaled to the given font size.
+
+    @param text Text whose kerning has to be calculated.
+    @param size Font size.
+  */
+  public final double getKerning(
+    String text,
+    double size
+    )
+  {return getKerning(text) * getScalingFactor(size);}
+
+  /**
+    Gets the unscaled line height.
+  */
+  public double getLineHeight(
+    )
+  {return getAscent() - getDescent();}
+
+  /**
+    Gets the line height, scaled to the given font size.
+
+    @param size Font size.
+  */
+  public final double getLineHeight(
+    double size
+    )
+  {return getLineHeight() * getScalingFactor(size);}
+
+  /**
+    Gets the PostScript name of the font.
+  */
+  public final String getName(
+    )
+  {return ((PdfName)getBaseDataObject().get(PdfName.BaseFont)).toString();}
+
+  /**
+    Gets the font type.
+  */
+  public final String getType(
+    )
+  {return ((PdfName)getBaseDataObject().get(PdfName.Subtype)).toString();}
+
+  /**
+    Gets the unscaled width of the given character.
+
+    @param textChar Character whose width has to be calculated.
+  */
+  public int getWidth(
+    char textChar
+    )
+  {
+    Integer glyphWidth = glyphWidths.get(glyphIndexes.get((int)textChar));
+    if(glyphWidth == null)
+      return defaultGlyphWidth;
+    else
+      return glyphWidth;
+  }
+
+  /**
+    Gets the width of the given character, scaled to the given font size.
+
+    @param textChar Character whose height has to be calculated.
+    @param size Font size.
+  */
+  public final double getWidth(
+    char textChar,
+    double size
+    )
+  {return getWidth(textChar) * getScalingFactor(size);}
+
+  /**
+    Gets the unscaled width (kerning exclusive) of the given text.
+
+    @param text Text whose width has to be calculated.
+  */
+  public int getWidth(
+    String text
+    )
+  {
+    int width = 0;
+    for(char textChar : text.toCharArray())
+    {width += getWidth(textChar);}
+
+    return width;
+  }
+
+  /**
+    Gets the width (kerning exclusive) of the given text, scaled to the given font size.
+
+    @param text Text whose width has to be calculated.
+    @param size Font size.
+  */
+  public final double getWidth(
+    String text,
+    double size
+    )
+  {return getWidth(text) * getScalingFactor(size);}
+
+  /**
+    Gets whether the font encoding is custom (that is non-Unicode).
+  */
+  public boolean isSymbolic(
+    )
+  {return symbolic;}
+  // </public>
+
+  // <protected>
+  /**
+    Gets the font descriptor.
+  */
+  protected abstract PdfDictionary getDescriptor(
+    );
+
+  /**
+    Loads font information from existing PDF font structure.
+  */
+  protected void load(
+    )
+  {
+    if(getBaseDataObject().containsKey(PdfName.ToUnicode)) // To-Unicode explicit mapping.
+    {
+      PdfStream toUnicodeStream = (PdfStream)getBaseDataObject().resolve(PdfName.ToUnicode);
+      CMapParser parser = new CMapParser(toUnicodeStream.getBody());
+      codes = new BiMap<ByteArray,Integer>(parser.parse());
+      symbolic = false;
+    }
+
+    onLoad();
+
+    // Maximum character code length.
+    for(ByteArray charCode : codes.keySet())
+    {
+      if(charCode.data.length > charCodeMaxLength)
+      {charCodeMaxLength = charCode.data.length;}
+    }
+  }
+
+  /**
+    Notifies the loading of font information from an existing PDF font structure.
+   */
+  protected abstract void onLoad(
+    );
+  // </protected>
+
+  // <private>
+  private void initialize(
+    )
+  {
+    // Put the newly instantiated font into the common cache!
+    /*
+      NOTE: Font structures are reified as complex objects, both IO- and CPU-intensive to load.
+      So, it's convenient to put them into a common cache for later reuse.
+    */
+    getDocument().cache.put((PdfReference)getBaseObject(),this);
+  }
+  // </private>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/FontFileFormatException.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/FontFileFormatException.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/FontFileFormatException.java	(revision 23703)
@@ -0,0 +1,63 @@
+/*
+  Copyright 2007 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.fonts;
+
+import it.stefanochizzolini.clown.tokens.FileFormatException;
+
+/**
+  Exception thrown in case of bad file format detection.
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+*/
+public class FontFileFormatException
+  extends FileFormatException
+{
+  private static final long serialVersionUID = 1L;
+
+  // <class>
+  // <dynamic>
+  // <constructors>
+  public FontFileFormatException(
+    String message
+    )
+  {this(message,0);}
+
+  public FontFileFormatException(
+    String message,
+    long position
+    )
+  {super(message,position);}
+
+  public FontFileFormatException(
+    String message,
+    Throwable cause,
+    long position
+    )
+  {super(message,cause,position);}
+  // </constructors>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/GlyphMapping.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/GlyphMapping.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/GlyphMapping.java	(revision 23703)
@@ -0,0 +1,103 @@
+/*
+  Copyright 2009 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.fonts;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.util.Hashtable;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+  Adobe standard glyph mapping (unicode-encoding against glyph-naming) [PDF:1.6:D;AGL:2.0].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+  @since 0.0.8
+*/
+final class GlyphMapping
+{
+  private static Hashtable<String,Integer> codes = new Hashtable<String,Integer>();
+
+  static
+  {load();}
+
+  public static int nameToCode(
+    String name
+    )
+  {return codes.get(name);}
+
+  /**
+    Loads the glyph list mapping character names to character codes (unicode encoding).
+  */
+  private static void load(
+    )
+  {
+    BufferedReader glyphListStream = null;
+    try
+    {
+      // Open the glyph list!
+      /*
+        NOTE: The Adobe Glyph List [AGL:2.0] represents the reference name-to-unicode map
+        for consumer applications.
+      */
+      glyphListStream = new BufferedReader(
+        new InputStreamReader(
+          GlyphMapping.class.getResourceAsStream("/fonts/AGL20.scsv")
+          )
+        );
+
+      // Parsing the glyph list...
+      String line;
+      Pattern linePattern = Pattern.compile("^(\\w+);([A-F0-9]+)$");
+      while((line = glyphListStream.readLine()) != null)
+      {
+        Matcher lineMatcher = linePattern.matcher(line);
+        if(!lineMatcher.find())
+          continue;
+
+        String name = lineMatcher.group(1);
+        int code = Integer.parseInt(lineMatcher.group(2),16);
+
+        // Associate the character name with its corresponding character code!
+        codes.put(name,code);
+      }
+    }
+    catch(Exception e)
+    {throw new RuntimeException(e);}
+    finally
+    {
+      try
+      {
+        // Close the glyph list!
+        if(glyphListStream != null)
+        {glyphListStream.close();}
+      }
+      catch(Exception e)
+      {throw new RuntimeException(e);}
+    }
+  }
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/MMType1Font.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/MMType1Font.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/MMType1Font.java	(revision 23703)
@@ -0,0 +1,47 @@
+/*
+  Copyright 2009 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.fonts;
+
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+
+/**
+  Multiple Master Type 1 font [PDF:1.6:5.5.1].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.8
+  @version 0.0.8
+*/
+public class MMType1Font
+  extends Type1Font
+{
+//TODO
+  // <constructors>
+  MMType1Font(
+    PdfDirectObject baseObject
+    )
+  {super(baseObject);}
+  // </constructors>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/MacRomanEncoding.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/MacRomanEncoding.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/MacRomanEncoding.java	(revision 23703)
@@ -0,0 +1,249 @@
+/*
+  Copyright 2009 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.fonts;
+
+/**
+  Mac OS standard latin encoding [PDF:1.6:D].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+  @since 0.0.8
+*/
+class MacRomanEncoding
+  extends Encoding
+{
+  public MacRomanEncoding(
+    )
+  {
+    put(0101,"A");
+    put(0256,"AE");
+    put(0347,"Aacute");
+    put(0345,"Acircumflex");
+    put(0200,"Adieresis");
+    put(0313,"Agrave");
+    put(0201,"Aring");
+    put(0314,"Atilde");
+    put(0102,"B");
+    put(0103,"C");
+    put(0202,"Ccedilla");
+    put(0104,"D");
+    put(0105,"E");
+    put(0203,"Eacute");
+    put(0346,"Ecircumflex");
+    put(0350,"Edieresis");
+    put(0351,"Egrave");
+    put(0106,"F");
+    put(0107,"G");
+    put(0110,"H");
+    put(0111,"I");
+    put(0352,"Iacute");
+    put(0353,"Icircumflex");
+    put(0354,"Idieresis");
+    put(0355,"Igrave");
+    put(0112,"J");
+    put(0113,"K");
+    put(0114,"L");
+    put(0115,"M");
+    put(0116,"N");
+    put(0204,"Ntilde");
+    put(0117,"O");
+    put(0316,"OE");
+    put(0356,"Oacute");
+    put(0357,"Ocircumflex");
+    put(0205,"Odieresis");
+    put(0361,"Ograve");
+    put(0257,"Oslash");
+    put(0315,"Otilde");
+    put(0120,"P");
+    put(0121,"Q");
+    put(0122,"R");
+    put(0123,"S");
+    put(0124,"T");
+    put(0125,"U");
+    put(0362,"Uacute");
+    put(0363,"Ucircumflex");
+    put(0206,"Udieresis");
+    put(0364,"Ugrave");
+    put(0126,"V");
+    put(0127,"W");
+    put(0130,"X");
+    put(0131,"Y");
+    put(0331,"Ydieresis");
+    put(0132,"Z");
+    put(0141,"a");
+    put(0207,"aacute");
+    put(0211,"acircumflex");
+    put(0253,"acute");
+    put(0212,"adieresis");
+    put(0276,"ae");
+    put(0210,"agrave");
+    put(046,"ampersand");
+    put(0214,"aring");
+    put(0136,"asciicircum");
+    put(0176,"asciitilde");
+    put(052,"asterisk");
+    put(0100,"at");
+    put(0213,"atilde");
+    put(0142,"b");
+    put(0134,"backslash");
+    put(0174,"bar");
+    put(0173,"braceleft");
+    put(0175,"braceright");
+    put(0133,"bracketleft");
+    put(0135,"bracketright");
+    put(0371,"breve");
+    put(0245,"bullet");
+    put(0143,"c");
+    put(0377,"caron");
+    put(0215,"ccedilla");
+    put(0374,"cedilla");
+    put(0242,"cent");
+    put(0366,"circumflex");
+    put(072,"colon");
+    put(054,"comma");
+    put(0251,"copyright");
+    put(0333,"currency");
+    put(0144,"d");
+    put(0240,"dagger");
+    put(0340,"daggerdbl");
+    put(0241,"degree");
+    put(0254,"dieresis");
+    put(0326,"divide");
+    put(044,"dollar");
+    put(0372,"dotaccent");
+    put(0365,"dotlessi");
+    put(0145,"e");
+    put(0216,"eacute");
+    put(0220,"ecircumflex");
+    put(0221,"edieresis");
+    put(0217,"egrave");
+    put(070,"eight");
+    put(0311,"ellipsis");
+    put(0321,"emdash");
+    put(0320,"endash");
+    put(075,"equal");
+    put(041,"exclam");
+    put(0301,"exclamdown");
+    put(0146,"f");
+    put(0336,"fi");
+    put(065,"five");
+    put(0337,"fl");
+    put(0304,"florin");
+    put(064,"four");
+    put(0332,"fraction");
+    put(0147,"g");
+    put(0247,"germandbls");
+    put(0140,"grave");
+    put(076,"greater");
+    put(0307,"guillemotleft");
+    put(0310,"guillemotright");
+    put(0334,"guilsinglleft");
+    put(0335,"guilsinglright");
+    put(0150,"h");
+    put(0375,"hungarumlaut");
+    put(055,"hyphen");
+    put(0151,"i");
+    put(0222,"iacute");
+    put(0224,"icircumflex");
+    put(0225,"idieresis");
+    put(0223,"igrave");
+    put(0152,"j");
+    put(0153,"k");
+    put(0154,"l");
+    put(074,"less");
+    put(0302,"logicalnot");
+    put(0155,"m");
+    put(0370,"macron");
+    put(0265,"mu");
+    put(0156,"n");
+    put(071,"nine");
+    put(0226,"ntilde");
+    put(043,"numbersign");
+    put(0157,"o");
+    put(0227,"oacute");
+    put(0231,"ocircumflex");
+    put(0232,"odieresis");
+    put(0317,"oe");
+    put(0376,"ogonek");
+    put(0230,"ograve");
+    put(061,"one");
+    put(0273,"ordfeminine");
+    put(0274,"ordmasculine");
+    put(0277,"oslash");
+    put(0233,"otilde");
+    put(0160,"p");
+    put(0246,"paragraph");
+    put(050,"parenleft");
+    put(051,"parenright");
+    put(045,"percent");
+    put(056,"period");
+    put(0341,"periodcentered");
+    put(0344,"perthousand");
+    put(053,"plus");
+    put(0261,"plusminus");
+    put(0161,"q");
+    put(077,"question");
+    put(0300,"questiondown");
+    put(042,"quotedbl");
+    put(0343,"quotedblbase");
+    put(0322,"quotedblleft");
+    put(0323,"quotedblright");
+    put(0324,"quoteleft");
+    put(0325,"quoteright");
+    put(0342,"quotesinglbase");
+    put(047,"quotesingle");
+    put(0162,"r");
+    put(0250,"registered");
+    put(0373,"ring");
+    put(0163,"s");
+    put(0244,"section");
+    put(073,"semicolon");
+    put(067,"seven");
+    put(066,"six");
+    put(057,"slash");
+    put(040,"space");
+    put(0243,"sterling");
+    put(0164,"t");
+    put(063,"three");
+    put(0367,"tilde");
+    put(0252,"trademark");
+    put(062,"two");
+    put(0165,"u");
+    put(0234,"uacute");
+    put(0236,"ucircumflex");
+    put(0237,"udieresis");
+    put(0235,"ugrave");
+    put(0137,"underscore");
+    put(0166,"v");
+    put(0167,"w");
+    put(0170,"x");
+    put(0171,"y");
+    put(0330,"ydieresis");
+    put(0264,"yen");
+    put(0172,"z");
+    put(060,"zero");
+  }
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/OpenFontParser.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/OpenFontParser.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/OpenFontParser.java	(revision 23703)
@@ -0,0 +1,931 @@
+/*
+  Copyright 2009-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.fonts;
+
+import it.stefanochizzolini.clown.bytes.IInputStream;
+
+import java.util.Hashtable;
+import java.util.Map;
+
+/**
+  Open Font Format parser [OFF:2009].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.8
+  @version 0.0.8
+*/
+final class OpenFontParser
+{
+  // <class>
+  // <classes>
+  /**
+    Font metrics.
+  */
+  static final class FontMetrics
+  {
+    /**
+      Whether the encoding is custom (symbolic font).
+    */
+    public boolean isCustomEncoding;//TODO:verify whether it can be replaced by the 'symbolic' variable!!!
+    /**
+      Unit normalization coefficient.
+    */
+    public float unitNorm;
+    /*
+      Font Header ('head' table).
+    */
+    public int flags; // USHORT.
+    public int unitsPerEm; // USHORT.
+    public short xMin;
+    public short yMin;
+    public short xMax;
+    public short yMax;
+    public int macStyle; // USHORT.
+    /*
+      Horizontal Header ('hhea' table).
+    */
+    public short ascender;
+    public short descender;
+    public short lineGap;
+    public int advanceWidthMax; // UFWORD.
+    public short minLeftSideBearing;
+    public short minRightSideBearing;
+    public short xMaxExtent;
+    public short caretSlopeRise;
+    public short caretSlopeRun;
+    public int numberOfHMetrics; // USHORT.
+    /*
+      OS/2 table ('OS/2' table).
+    */
+    public short sTypoAscender;
+    public short sTypoDescender;
+    public short sTypoLineGap;
+    public short sxHeight;
+    public short sCapHeight;
+    /*
+      PostScript table ('post' table).
+    */
+    public float italicAngle;
+    public short underlinePosition;
+    public short underlineThickness;
+    public boolean isFixedPitch;
+  }
+
+  /**
+    Outline format.
+  */
+  enum OutlineFormatEnum
+  {
+    /**
+      TrueType format outlines.
+    */
+    TrueType,
+    /**
+      Compact Font Format outlines.
+    */
+    CFF;
+  }
+  // </classes>
+
+  // <static>
+  // <fields>
+  private static final String Encoding_Latin1 = "ISO-8859-1";
+  private static final String Encoding_Unicode = "UTF-16";
+
+  private static final int MicrosoftLanguage_UsEnglish = 0x409;
+  private static final int NameID_FontPostscriptName = 6;
+
+  private static final int PlatformID_Unicode = 0;
+  private static final int PlatformID_Macintosh = 1;
+  private static final int PlatformID_Microsoft = 3;
+  // </fields>
+
+  // <interface>
+  // <public>
+  /**
+   * Gets whether the given data represents a valid Open Font.
+   */
+  public static boolean isOpenFont(
+    IInputStream fontData
+    )
+  {
+    long position = fontData.getPosition();
+    try
+    {
+      fontData.setPosition(0);
+      getOutlineFormat(fontData.readInt()); // NOTE: An exception is expected to be thrown in case of wrong file format.
+      return true;
+    }
+    catch(Exception e)
+    {return false;}
+    finally
+    {fontData.setPosition(position);}
+  }
+  // </public>
+
+  // <private>
+  private static OutlineFormatEnum getOutlineFormat(
+    int versionCode
+    )
+  {
+    // Which font file format ('sfnt') version?
+    switch(versionCode)
+    {
+      case(0x00010000): // TrueType (standard/Windows).
+      case(0x74727565): // TrueType (legacy/Apple).
+        return OutlineFormatEnum.TrueType;
+      case(0x4F54544F): // CFF (Type 1).
+        return OutlineFormatEnum.CFF;
+      default:
+        throw new UnsupportedOperationException("Unknown OpenFont format version.");
+    }
+  }
+  // </private>
+  // </interface>
+  // </static>
+
+  // <dynamic>
+  // <fields>
+  public FontMetrics metrics;
+
+  public String fontName;
+  public OutlineFormatEnum outlineFormat;
+  /**
+    Whether glyphs are indexed by custom (non-Unicode) encoding.
+  */
+  public boolean symbolic;
+
+  public Map<Integer,Integer> glyphIndexes;
+  public Map<Integer,Integer> glyphKernings;
+  public Map<Integer,Integer> glyphWidths;
+
+  public IInputStream fontData;
+
+  private Map<String,Integer> tableOffsets;
+  // </fields>
+
+  // <constructors>
+  OpenFontParser(
+    IInputStream fontData
+    )
+  {
+    this.fontData = fontData;
+
+    load();
+  }
+  // </constructors>
+
+  // <interface>
+  // <private>
+  /**
+    Loads the font data.
+  */
+  private void load(
+    )
+  {
+    metrics = new FontMetrics();
+
+    try
+    {
+      // 1. Offset Table.
+      fontData.seek(0);
+      // Get the outline format!
+      this.outlineFormat = getOutlineFormat(fontData.readInt());
+      // Get the number of tables!
+      int tableCount = fontData.readUnsignedShort();
+      this.tableOffsets = new Hashtable<String,Integer>(tableCount);
+
+      // 2. Table Directory.
+      // Skip to the beginning of the table directory!
+      fontData.skip(6);
+      // Collecting the table offsets...
+      for(
+        int index = 0;
+        index < tableCount;
+        index++
+        )
+      {
+        // Get the table tag!
+        String tag = readString_ascii(4);
+        // Skip to the table offset!
+        fontData.skip(4);
+        // Get the table offset!
+        int offset = fontData.readInt();
+        // Collect the table offset!
+        tableOffsets.put(tag,offset);
+
+        // Skip to the next entry!
+        fontData.skip(4);
+      }
+
+      this.fontName = load_getName(NameID_FontPostscriptName);
+
+      // Loading font metrics...
+      load_tables();
+      load_cMap();
+      load_glyphWidths();
+      load_glyphKerning();
+    }
+    catch(Exception e)
+    {throw new RuntimeException(e);}
+  }
+
+  /**
+    Loads the character to glyph index mapping table.
+  */
+  private void load_cMap(
+    ) throws FontFileFormatException
+  {
+    /*
+      NOTE: A 'cmap' table may contain one or more subtables that represent multiple encodings
+      intended for use on different platforms (such as Mac OS and Windows).
+      Each subtable is identified by the two numbers, such as (3,1), that represent a combination
+      of a platform ID and a platform-specific encoding ID, respectively.
+      A symbolic font (used to display glyphs that do not use standard encodings, i.e. neither
+      MacRomanEncoding nor WinAnsiEncoding) program's "cmap" table should contain a (1,0) subtable.
+      It may also contain a (3,0) subtable; if present, this subtable should map from character
+      codes in the range 0xF000 to 0xF0FF by prepending the single-byte codes in the (1,0) subtable
+      with 0xF0 and mapping to the corresponding glyph descriptions.
+    */
+    // Character To Glyph Index Mapping Table ('cmap' table).
+    // Retrieve the location info!
+    Integer tableOffset = tableOffsets.get("cmap");
+    if(tableOffset == null)
+      throw new FontFileFormatException("'cmap' table does NOT exist.");
+
+    int cmap10Offset = 0;
+    int cmap31Offset = 0;
+    try
+    {
+      // Header.
+      // Go to the number of tables!
+      fontData.seek(tableOffset + 2);
+      int tableCount = fontData.readUnsignedShort();
+
+      // Encoding entries.
+      for(
+        int tableIndex = 0;
+        tableIndex < tableCount;
+        tableIndex++
+        )
+      {
+        // Platform ID.
+        int platformID = fontData.readUnsignedShort();
+        // Encoding ID.
+        int encodingID = fontData.readUnsignedShort();
+        // Subtable offset.
+        int offset = fontData.readInt();
+        switch(platformID)
+        {
+          case PlatformID_Macintosh:
+            switch(encodingID)
+            {
+              case 0: // Symbolic font.
+                cmap10Offset = offset;
+                break;
+            }
+            break;
+          case PlatformID_Microsoft:
+            switch(encodingID)
+            {
+              case 0: // Symbolic font.
+                break;
+              case 1: // Nonsymbolic font.
+                cmap31Offset = offset;
+                break;
+            }
+            break;
+        }
+      }
+    }
+    catch(Exception e)
+    {throw new RuntimeException(e);}
+
+    /*
+      NOTE: Symbolic fonts use specific (non-standard, i.e. neither Unicode nor
+      platform-standard) font encodings.
+    */
+    if(cmap31Offset > 0) // Nonsymbolic.
+    {
+      metrics.isCustomEncoding = false;
+      // Go to the beginning of the subtable!
+      fontData.seek(tableOffset + cmap31Offset);
+    }
+    else if(cmap10Offset > 0) // Symbolic.
+    {
+      metrics.isCustomEncoding = true;
+      // Go to the beginning of the subtable!
+      fontData.seek(tableOffset + cmap10Offset);
+    }
+    else
+      throw new FontFileFormatException("CMAP table unavailable.");
+
+    int format;
+    try
+    {format = fontData.readUnsignedShort();}
+    catch(Exception e)
+    {throw new FontFileFormatException("Cmap table format not found.",e,fontData.getPosition());}
+    // Which cmap table format?
+    switch(format)
+    {
+      case 0: // Byte encoding table.
+        load_cMap_format0(); break;
+      case 4: // Segment mapping to delta values.
+        load_cMap_format4(); break;
+      case 6: // Trimmed table mapping.
+        load_cMap_format6(); break;
+      default:
+        throw new FontFileFormatException("Cmap table format " + format + " NOT supported.");
+    }
+  }
+
+  /**
+    Loads format-0 cmap subtable (Byte encoding table, that is Apple standard
+    character-to-glyph index mapping table).
+  */
+  private void load_cMap_format0(
+    ) throws FontFileFormatException
+  {
+    /*
+      NOTE: This is a simple 1-to-1 mapping of character codes to glyph indices.
+      The glyph collection is limited to 256 entries.
+    */
+    symbolic = true;
+    glyphIndexes = new Hashtable<Integer,Integer>(256);
+
+    try
+    {
+      // Skip to the mapping array!
+      fontData.skip(4);
+      // Glyph index array.
+      // Iterating through the glyph indexes...
+      for(
+        int code = 0;
+        code < 256;
+        code++
+        )
+      {
+        glyphIndexes.put(
+          code, // Character code.
+          fontData.readUnsignedByte() // Glyph index.
+          );
+      }
+    }
+    catch(Exception e)
+    {throw new FontFileFormatException("Cmap data retrieval failed.",e,fontData.getPosition());}
+  }
+
+  /**
+    Loads format-4 cmap subtable (Segment mapping to delta values, that is Microsoft standard
+    character to glyph index mapping table for fonts that support Unicode ranges other than the
+    range [U+D800 - U+DFFF] (defined as Surrogates Area, in Unicode v 3.0)).
+  */
+  private void load_cMap_format4(
+    ) throws FontFileFormatException
+  {
+    /*
+      NOTE: This format is used when the character codes for the characters represented by a font
+      fall into several contiguous ranges, possibly with holes in some or all of the ranges (i.e.
+      some of the codes in a range may not have a representation in the font).
+      The format-dependent data is divided into three parts, which must occur in the following
+      order:
+        1. A header gives parameters for an optimized search of the segment list;
+        2. Four parallel arrays (end characters, start characters, deltas and range offsets)
+        describe the segments (one segment for each contiguous range of codes);
+        3. A variable-length array of glyph IDs.
+    */
+    symbolic = false;
+    try
+    {
+      // 1. Header.
+      // Get the table length!
+      int tableLength = fontData.readUnsignedShort(); // USHORT.
+
+      // Skip to the segment count!
+      fontData.skip(2);
+      // Get the segment count!
+      int segmentCount = fontData.readUnsignedShort() / 2;
+
+      // 2. Arrays describing the segments.
+      // Skip to the array of end character code for each segment!
+      fontData.skip(6);
+      // End character code for each segment.
+      int[] endCodes = new int[segmentCount]; // USHORT.
+      for(
+        int index = 0;
+        index < segmentCount;
+        index++
+        )
+      {endCodes[index] = fontData.readUnsignedShort();}
+
+      // Skip to the array of start character code for each segment!
+      fontData.skip(2);
+      // Start character code for each segment.
+      int[] startCodes = new int[segmentCount]; // USHORT.
+      for(
+        int index = 0;
+        index < segmentCount;
+        index++
+        )
+      {startCodes[index] = fontData.readUnsignedShort();}
+
+      // Delta for all character codes in segment.
+      short[] deltas = new short[segmentCount];
+      for(
+        int index = 0;
+        index < segmentCount;
+        index++
+        )
+      {deltas[index] = fontData.readShort();}
+
+      // Offsets into glyph index array.
+      int[] rangeOffsets = new int[segmentCount]; // USHORT.
+      for(
+        int index = 0;
+        index < segmentCount;
+        index++
+        )
+      {rangeOffsets[index] = fontData.readUnsignedShort();}
+
+      // 3. Glyph ID array.
+      /*
+        NOTE: There's no explicit field defining the array length;
+        it must be inferred from the space left by the known fields.
+      */
+      int glyphIndexCount = tableLength / 2 // Number of 16-bit words inside the table.
+        - 8 // Number of single-word header fields (8 fields: format, length, language, segCountX2, searchRange, entrySelector, rangeShift, reservedPad).
+        - segmentCount * 4; // Number of single-word items in the arrays describing the segments (4 arrays of segmentCount items).
+      int[] glyphIds = new int[glyphIndexCount]; // USHORT.
+      for(
+        int index = 0;
+        index < glyphIds.length;
+        index++
+        )
+      {glyphIds[index] = fontData.readUnsignedShort();}
+
+      glyphIndexes = new Hashtable<Integer,Integer>(glyphIndexCount);
+      // Iterating through the segments...
+      for(
+        int segmentIndex = 0;
+        segmentIndex < segmentCount;
+        segmentIndex++
+        )
+      {
+        int endCode = endCodes[segmentIndex];
+        // Is it NOT the last end character code?
+        /*
+          NOTE: The final segment's endCode MUST be 0xFFFF. This segment need not (but MAY)
+          contain any valid mappings (it can just map the single character code 0xFFFF to
+          missing glyph). However, the segment MUST be present.
+        */
+        if(endCode < 0xFFFF)
+        {endCode++;}
+        // Iterating inside the current segment...
+        for(
+          int code = startCodes[segmentIndex];
+          code < endCode;
+          code++
+          )
+        {
+          int glyphIndex;
+          // Doesn't the mapping of character codes rely on glyph ID?
+          if(rangeOffsets[segmentIndex] == 0) // No glyph-ID reliance.
+          {
+            /*
+              NOTE: If the range offset is 0, the delta value is added directly to the character
+              code to get the corresponding glyph index. The delta arithmetic is modulo 65536.
+            */
+            glyphIndex = (code + deltas[segmentIndex]) & 0xFFFF;
+          }
+          else // Glyph-ID reliance.
+          {
+            /*
+              NOTE: If the range offset is NOT 0, the mapping of character codes relies on glyph ID.
+              The character code offset from start code is added to the range offset. This sum is
+              used as an offset from the current location within range offset itself to index out
+              the correct glyph ID. This obscure indexing trick (sic!) works because glyph ID
+              immediately follows range offset in the font file. The C expression that yields the
+              address to the glyph ID is:
+                *(rangeOffsets[segmentIndex]/2
+                + (code - startCodes[segmentIndex])
+                + &idRangeOffset[segmentIndex])
+              As Java language semantics don't deal directly with pointers, we have to further
+              exploit such a trick reasoning with 16-bit displacements in order to yield an index
+              instead of an address (sooo-good!).
+            */
+            // Retrieve the glyph index!
+            int glyphIdIndex = rangeOffsets[segmentIndex] / 2 // 16-bit word range offset.
+              + (code - startCodes[segmentIndex]) // Character code offset from start code.
+              - (segmentCount - segmentIndex); // Physical offset between the offsets into glyph index array and the glyph index array.
+
+            /*
+              NOTE: The delta value is added to the glyph ID to get the corresponding glyph index.
+              The delta arithmetic is modulo 65536.
+            */
+            glyphIndex = (glyphIds[glyphIdIndex] + deltas[segmentIndex]) & 0xFFFF;
+          }
+
+          glyphIndexes.put(
+            code, // Character code.
+            glyphIndex // Glyph index.
+            );
+        }
+      }
+    }
+    catch(Exception e)
+    {throw new FontFileFormatException("Cmap data retrieval failed.",e,fontData.getPosition());}
+  }
+
+  /**
+    Loads format-6 cmap subtable (Trimmed table mapping).
+  */
+  private void load_cMap_format6(
+    ) throws FontFileFormatException
+  {
+    symbolic = true;
+    try
+    {
+      // Skip to the first character code!
+      fontData.skip(4);
+      int firstCode = fontData.readUnsignedShort();
+      int codeCount = fontData.readUnsignedShort();
+      glyphIndexes = new Hashtable<Integer,Integer>(codeCount);
+      for(
+        int code = firstCode,
+          lastCode = firstCode + codeCount;
+        code < lastCode;
+        code++
+        )
+      {
+        glyphIndexes.put(
+          code, // Character code.
+          fontData.readUnsignedShort() // Glyph index.
+          );
+      }
+    }
+    catch(Exception e)
+    {throw new FontFileFormatException("Cmap data retrieval failed.",e,fontData.getPosition());}
+  }
+
+  /**
+    Gets a name.
+
+    @param id Name identifier.
+  */
+  private String load_getName(
+    int id
+    ) throws FontFileFormatException
+  {
+    // Naming Table ('name' table).
+    Integer tableOffset = tableOffsets.get("name");
+    if(tableOffset == null)
+      throw new FontFileFormatException("'name' table does NOT exist.");
+
+    try
+    {
+      // Go to the number of name records!
+      fontData.seek(tableOffset + 2);
+
+      int recordCount = fontData.readUnsignedShort(); // USHORT.
+      int storageOffset = fontData.readUnsignedShort(); // USHORT.
+      // Iterating through the name records...
+      for(
+        int recordIndex = 0;
+        recordIndex < recordCount;
+        recordIndex++
+        )
+      {
+        int platformID = fontData.readUnsignedShort(); // USHORT.
+        // Is it the default platform?
+        if(platformID == PlatformID_Microsoft)
+        {
+          fontData.skip(2);
+          int languageID = fontData.readUnsignedShort(); // USHORT.
+          // Is it the default language?
+          if(languageID == MicrosoftLanguage_UsEnglish)
+          {
+            int nameID = fontData.readUnsignedShort(); // USHORT.
+            // Does the name ID equal the searched one?
+            if(nameID == id)
+            {
+              int length = fontData.readUnsignedShort(); // USHORT.
+              int offset = fontData.readUnsignedShort(); // USHORT.
+
+              // Go to the name string!
+              fontData.seek(tableOffset + storageOffset + offset);
+
+              return readString(length,platformID);
+            }
+            else
+            {fontData.skip(4);}
+          }
+          else
+          {fontData.skip(6);}
+        }
+        else
+        {fontData.skip(10);}
+      }
+
+      return null; // Not found.
+    }
+    catch(Exception e)
+    {throw new FontFileFormatException("Name '" + id + "' not found.",e,fontData.getPosition());}
+  }
+
+  /**
+    Loads the glyph kerning.
+  */
+  private void load_glyphKerning(
+    ) throws FontFileFormatException
+  {
+    // Kerning ('kern' table).
+    Integer tableOffset = tableOffsets.get("kern");
+    if(tableOffset == null)
+      return;
+
+    try
+    {
+      // Go to the table count!
+      fontData.seek(tableOffset + 2);
+      int subtableCount = fontData.readUnsignedShort(); // USHORT.
+
+      glyphKernings = new Hashtable<Integer,Integer>();
+      int subtableOffset = (int)fontData.getPosition();
+      // Iterating through the subtables...
+      for(
+        int subtableIndex = 0;
+        subtableIndex < subtableCount;
+        subtableIndex++
+        )
+      {
+        // Go to the subtable length!
+        fontData.seek(subtableOffset + 2);
+        // Get the subtable length!
+        int length = fontData.readUnsignedShort(); // USHORT.
+
+        // Get the type of information contained in the subtable!
+        int coverage = fontData.readUnsignedShort(); // USHORT.
+        // Is it a format-0 subtable?
+        /*
+          NOTE: coverage bits 8-15 (format of the subtable) MUST be all zeros
+          (representing format 0).
+        */
+        //
+        if((coverage & 0xff00) == 0x0000)
+        {
+          int pairCount = fontData.readUnsignedShort(); // USHORT.
+
+          // Skip to the beginning of the list!
+          fontData.skip(6);
+          // List of kerning pairs and values.
+          for(
+            int pairIndex = 0;
+            pairIndex < pairCount;
+            pairIndex++
+            )
+          {
+            // Get the glyph index pair (left-hand and right-hand)!
+            int pair = fontData.readInt(); // USHORT USHORT.
+            // Get the normalized kerning value!
+            int value = (int)(fontData.readShort() * metrics.unitNorm);
+
+            glyphKernings.put(pair,value);
+          }
+        }
+
+        subtableOffset += length;
+      }
+    }
+    catch(Exception e)
+    {throw new FontFileFormatException("Glyph kernings retrieval failed.",e,fontData.getPosition());}
+  }
+
+  /**
+    Loads the glyph widths.
+  */
+  private void load_glyphWidths(
+    ) throws FontFileFormatException
+  {
+    // Horizontal Metrics ('hmtx' table).
+    Integer tableOffset = tableOffsets.get("hmtx");
+    if(tableOffset == null)
+      throw new FontFileFormatException("'hmtx' table does NOT exist.");
+
+    try
+    {
+      // Go to the glyph horizontal-metrics entries!
+      fontData.seek(tableOffset);
+      glyphWidths = new Hashtable<Integer,Integer>(metrics.numberOfHMetrics);
+      for(
+        int index = 0;
+        index < metrics.numberOfHMetrics;
+        index++
+        )
+      {
+        // Get the glyph width!
+        glyphWidths.put(index,(int)(fontData.readUnsignedShort() * metrics.unitNorm));
+        // Skip the left side bearing!
+        fontData.skip(2);
+      }
+    }
+    catch(Exception e)
+    {throw new FontFileFormatException("Glyph widths retrieval failed.",e,fontData.getPosition());}
+  }
+
+  /**
+    Loads general tables.
+  */
+  private void load_tables(
+    ) throws FontFileFormatException
+  {
+    // Font Header ('head' table).
+    Integer tableOffset = tableOffsets.get("head");
+    if(tableOffset == null)
+      throw new FontFileFormatException("'head' table does NOT exist.");
+
+    try
+    {
+      // Go to the font flags!
+      fontData.seek(tableOffset + 16);
+      metrics.flags = fontData.readUnsignedShort();
+      metrics.unitsPerEm = fontData.readUnsignedShort();
+      metrics.unitNorm = 1000f / metrics.unitsPerEm;
+      // Go to the bounding box limits!
+      fontData.skip(16);
+      metrics.xMin = fontData.readShort();
+      metrics.yMin = fontData.readShort();
+      metrics.xMax = fontData.readShort();
+      metrics.yMax = fontData.readShort();
+      metrics.macStyle = fontData.readUnsignedShort();
+    }
+    catch(Exception e)
+    {throw new FontFileFormatException("'head' metrics retrieval failed.",e,fontData.getPosition());}
+
+    // Font Header ('OS/2' table).
+    tableOffset = tableOffsets.get("OS/2");
+    if(tableOffset != null)
+    {
+      try
+      {
+        fontData.seek(tableOffset);
+        int version = fontData.readUnsignedShort();
+        // Go to the ascender!
+        fontData.skip(66);
+        metrics.sTypoAscender = fontData.readShort();
+        metrics.sTypoDescender = fontData.readShort();
+        metrics.sTypoLineGap = fontData.readShort();
+        if(version >= 2)
+        {
+          fontData.skip(12);
+          metrics.sxHeight = fontData.readShort();
+          metrics.sCapHeight = fontData.readShort();
+        }
+        else
+        {
+          /*
+            NOTE: These are just rule-of-thumb values,
+            in case the xHeight and CapHeight fields aren't available.
+          */
+          metrics.sxHeight = (short)(.5 * metrics.unitsPerEm);
+          metrics.sCapHeight = (short)(.7 * metrics.unitsPerEm);
+        }
+      }
+      catch(Exception e)
+      {throw new FontFileFormatException("'OS/2' metrics retrieval failed.",e,fontData.getPosition());}
+    }
+
+    // Horizontal Header ('hhea' table).
+    tableOffset = tableOffsets.get("hhea");
+    if(tableOffset == null)
+      throw new FontFileFormatException("'hhea' table does NOT exist.");
+
+    try
+    {
+      // Go to the ascender!
+      fontData.seek(tableOffset + 4);
+      metrics.ascender = fontData.readShort();
+      metrics.descender = fontData.readShort();
+      metrics.lineGap = fontData.readShort();
+      metrics.advanceWidthMax = fontData.readUnsignedShort();
+      metrics.minLeftSideBearing = fontData.readShort();
+      metrics.minRightSideBearing = fontData.readShort();
+      metrics.xMaxExtent = fontData.readShort();
+      metrics.caretSlopeRise = fontData.readShort();
+      metrics.caretSlopeRun = fontData.readShort();
+      // Go to the horizontal metrics count!
+      fontData.skip(12);
+      metrics.numberOfHMetrics = fontData.readUnsignedShort();
+    }
+    catch(Exception e)
+    {throw new FontFileFormatException("'hhea' metrics retrieval failed.",e,fontData.getPosition());}
+
+    // PostScript ('post' table).
+    tableOffset = tableOffsets.get("post");
+    if(tableOffset == null)
+      throw new FontFileFormatException("'post' table does NOT exist.");
+
+    try
+    {
+      // Go to the italic angle!
+      fontData.seek(tableOffset + 4);
+      metrics.italicAngle =
+        fontData.readShort() // Fixed-point mantissa (16 bits).
+        + (float)fontData.readUnsignedShort() / 16384; // Fixed-point fraction (16 bits).
+      metrics.underlinePosition = fontData.readShort();
+      metrics.underlineThickness = fontData.readShort();
+      metrics.isFixedPitch = (fontData.readInt() != 0);
+    }
+    catch(Exception e)
+    {throw new FontFileFormatException("'post' metrics retrieval failed.",e,fontData.getPosition());}
+  }
+
+  /**
+    Reads a string.
+  */
+  private String readString(
+    int length,
+    int platformID
+    )
+  {
+    // Which platform?
+    switch(platformID)
+    {
+      case PlatformID_Unicode:
+      case PlatformID_Microsoft:
+        return readString_unicode(length);
+      default:
+        return readString_ascii(length);
+    }
+  }
+
+  /**
+    Reads a string from the font file using the extended ASCII encoding.
+  */
+  private String readString_ascii(
+    int length
+    )
+  {
+    /*
+      NOTE: Extended ASCII (Latin1) is a single-byte encoding
+      (I know you already knew that!).
+    */
+    try
+    {
+      byte[] data = new byte[length];
+      fontData.read(data);
+
+      return new String(data,Encoding_Latin1);
+    }
+    catch(Exception e)
+    {throw new RuntimeException(e);}
+  }
+
+  /**
+    Reads a string from the font file using the Unicode encoding.
+  */
+  private String readString_unicode(
+    int length
+    )
+  {
+    /*
+      NOTE: Unicode is a double-byte encoding
+      (I know you already knew that!).
+    */
+    try
+    {
+      byte[] data = new byte[length];
+      fontData.read(data);
+
+      return new String(data,Encoding_Unicode);
+    }
+    catch(Exception e)
+    {throw new RuntimeException(e);}
+  }
+  // </private>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/PfbParser.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/PfbParser.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/PfbParser.java	(revision 23703)
@@ -0,0 +1,99 @@
+/*
+  Copyright 2009 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.fonts;
+
+import it.stefanochizzolini.clown.bytes.IInputStream;
+import it.stefanochizzolini.clown.util.ByteArray;
+
+import java.io.EOFException;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+  Type 1 font parser.
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+  @since 0.0.8
+*/
+final class PfbParser
+{
+  private IInputStream stream;
+
+  PfbParser(
+    IInputStream stream
+    )
+  {this.stream = stream;}
+
+  /**
+    Parses the character-code-to-unicode mapping [PDF:1.6:5.9.1].
+  */
+  public Map<ByteArray,Integer> parse(
+    )
+  {
+    Hashtable<ByteArray,Integer> codes = new Hashtable<ByteArray,Integer>();
+
+    String line;
+    Pattern linePattern = Pattern.compile("(\\S+)\\s+(.+)");
+    try
+    {
+      while((line = stream.readLine()) != null)
+      {
+        Matcher lineMatcher = linePattern.matcher(line);
+        if(!lineMatcher.find())
+          continue;
+
+        String key = lineMatcher.group(1);
+        if(key.equals("/Encoding"))
+        {
+          // Skip to the encoding array entries!
+          stream.readLine();
+          String encodingLine;
+          Pattern encodingLinePattern = Pattern.compile("dup (\\S+) (\\S+) put");
+          while((encodingLine = stream.readLine()) != null)
+          {
+            Matcher encodingLineMatcher = encodingLinePattern.matcher(encodingLine);
+            if(!encodingLineMatcher.find())
+              break;
+
+            byte[] inputCode = new byte[]{(byte)Integer.parseInt(encodingLineMatcher.group(1))};
+            String name = encodingLineMatcher.group(2).substring(1);
+            codes.put(new ByteArray(inputCode),GlyphMapping.nameToCode(name));
+          }
+          break;
+        }
+      }
+    }
+    catch(EOFException e)
+    {/* TODO: eof on readline? consider readline==null!!! */}
+    catch(Exception e)
+    {throw new RuntimeException(e);}
+
+    return codes;
+  }
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/SimpleFont.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/SimpleFont.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/SimpleFont.java	(revision 23703)
@@ -0,0 +1,158 @@
+/*
+  Copyright 2009-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.fonts;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.objects.IPdfNumber;
+import it.stefanochizzolini.clown.objects.PdfArray;
+import it.stefanochizzolini.clown.objects.PdfDictionary;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfInteger;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.util.ByteArray;
+
+import java.util.Hashtable;
+import java.util.Map;
+
+/**
+  Simple font [PDF:1.6:5.5].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.8
+  @version 0.0.8
+*/
+public abstract class SimpleFont
+  extends Font
+{
+  // <constructors>
+  protected SimpleFont(
+    Document context
+    )
+  {super(context);}
+
+  protected SimpleFont(
+    PdfDirectObject baseObject
+    )
+  {super(baseObject);}
+  // </constructors>
+
+  @Override
+  protected PdfDictionary getDescriptor(
+    )
+  {return (PdfDictionary)getBaseDataObject().resolve(PdfName.FontDescriptor);}
+
+  protected abstract void loadEncoding();
+  
+  /**
+    Loads the encoding differences into the given collection.
+    
+    @param encodingDictionary Encoding dictionary.
+    @param codes Encoding to alter applying differences.
+   */
+  protected void loadEncodingDifferences(
+    PdfDictionary encodingDictionary,
+    Map<ByteArray,Integer> codes
+    )
+  {
+    PdfArray differenceObjects = (PdfArray)encodingDictionary.resolve(PdfName.Differences);
+    if(differenceObjects == null)
+      return;
+  
+    /*
+      NOTE: Each code is the first index in a sequence of character codes to be changed.
+      The first character name after the code becomes the name corresponding to that code.
+      Subsequent names replace consecutive code indices until the next code appears
+      in the array or the array ends.
+    */
+    byte[] charCodeData = new byte[1];
+    for(PdfDirectObject differenceObject : differenceObjects)
+    {
+      if(differenceObject instanceof PdfInteger)
+      {charCodeData[0] = (byte)(((Integer)((PdfInteger)differenceObject).getValue()) & 0xFF);}
+      else // NOTE: MUST be PdfName.
+      {
+        ByteArray charCode = new ByteArray(charCodeData);
+        String charName = (String)((PdfName)differenceObject).getValue();
+        if(charName.equals(".notdef"))
+        {codes.remove(charCode);}
+        else
+        {
+          try
+          {codes.put(charCode,GlyphMapping.nameToCode(charName));}
+          catch (Exception e)
+          {codes.put(charCode,(int)charCodeData[0]);} // NOTE: This is an extreme remedy to non-standard character name lookups.
+        }
+        charCodeData[0]++;
+      }
+    }
+  }
+
+  @Override
+  protected void onLoad(
+    )
+  {
+    loadEncoding();
+
+    // Glyph widths.
+    if(glyphWidths == null)
+    {
+      glyphWidths = new Hashtable<Integer,Integer>();
+      PdfArray glyphWidthObjects = (PdfArray)getBaseDataObject().resolve(PdfName.Widths);
+      if(glyphWidthObjects != null)
+      {
+        ByteArray charCode = new ByteArray(
+          new byte[]
+          {(byte)(int)((PdfInteger)getBaseDataObject().get(PdfName.FirstChar)).getRawValue()}
+          );
+        for(PdfDirectObject glyphWidthObject : glyphWidthObjects)
+        {
+          int glyphWidth = ((PdfInteger)glyphWidthObject).getRawValue();
+          if(glyphWidth > 0)
+          {
+            Integer code = codes.get(charCode);
+            if(code != null)
+            {
+              glyphWidths.put(
+                glyphIndexes.get(code),
+                glyphWidth
+                );
+            }
+          }
+          charCode.data[0]++;
+        }
+      }
+    }
+    // Default glyph width.
+    {
+      PdfDictionary descriptor = getDescriptor();
+      if(descriptor != null)
+      {
+        IPdfNumber defaultGlyphWidthObject = (IPdfNumber)descriptor.get(PdfName.MissingWidth);
+        defaultGlyphWidth = (defaultGlyphWidthObject == null ? 0 : (int)Math.round(defaultGlyphWidthObject.getNumberValue()));
+      }
+    }
+  }
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/StandardEncoding.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/StandardEncoding.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/StandardEncoding.java	(revision 23703)
@@ -0,0 +1,191 @@
+/*
+  Copyright 2009 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.fonts;
+
+/**
+  Adobe standard Latin-text encoding [PDF:1.6:D].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+  @since 0.0.8
+*/
+class StandardEncoding
+  extends Encoding
+{
+  public StandardEncoding(
+    )
+  {
+    put(0101,"A");
+    put(0341,"AE");
+    put(0102,"B");
+    put(0103,"C");
+    put(0104,"D");
+    put(0105,"E");
+    put(0106,"F");
+    put(0107,"G");
+    put(0110,"H");
+    put(0111,"I");
+    put(0112,"J");
+    put(0113,"K");
+    put(0114,"L");
+    put(0350,"Lslash");
+    put(0115,"M");
+    put(0116,"N");
+    put(0117,"O");
+    put(0352,"OE");
+    put(0351,"Oslash");
+    put(0120,"P");
+    put(0121,"Q");
+    put(0122,"R");
+    put(0123,"S");
+    put(0124,"T");
+    put(0125,"U");
+    put(0126,"V");
+    put(0127,"W");
+    put(0130,"X");
+    put(0131,"Y");
+    put(0132,"Z");
+    put(0141,"a");
+    put(0302,"acute");
+    put(0361,"ae");
+    put(046,"ampersand");
+    put(0136,"asciicircum");
+    put(0176,"asciitilde");
+    put(052,"asterisk");
+    put(0100,"at");
+    put(0142,"b");
+    put(0134,"backslash");
+    put(0174,"bar");
+    put(0173,"braceleft");
+    put(0175,"braceright");
+    put(0133,"bracketleft");
+    put(0135,"bracketright");
+    put(0306,"breve");
+    put(0267,"bullet");
+    put(0143,"c");
+    put(0317,"caron");
+    put(0313,"cedilla");
+    put(0242,"cent");
+    put(0303,"circumflex");
+    put(072,"colon");
+    put(054,"comma");
+    put(0250,"currency");
+    put(0144,"d");
+    put(0262,"dagger");
+    put(0263,"daggerdbl");
+    put(0310,"dieresis");
+    put(044,"dollar");
+    put(0307,"dotaccent");
+    put(0365,"dotlessi");
+    put(0145,"e");
+    put(070,"eight");
+    put(0274,"ellipsis");
+    put(0320,"emdash");
+    put(0261,"endash");
+    put(075,"equal");
+    put(041,"exclam");
+    put(0241,"exclamdown");
+    put(0146,"f");
+    put(0256,"fi");
+    put(065,"five");
+    put(0257,"fl");
+    put(0246,"florin");
+    put(064,"four");
+    put(0244,"fraction");
+    put(0147,"g");
+    put(0373,"germandbls");
+    put(0301,"grave");
+    put(076,"greater");
+    put(0253,"guillemotleft");
+    put(0273,"guillemotright");
+    put(0254,"guilsinglleft");
+    put(0255,"guilsinglright");
+    put(0150,"h");
+    put(0315,"hungarumlaut");
+    put(055,"hyphen");
+    put(0151,"i");
+    put(0152,"j");
+    put(0153,"k");
+    put(0154,"l");
+    put(074,"less");
+    put(0370,"lslash");
+    put(0155,"m");
+    put(0305,"macron");
+    put(0156,"n");
+    put(071,"nine");
+    put(043,"numbersign");
+    put(0157,"o");
+    put(0372,"oe");
+    put(0316,"ogonek");
+    put(061,"one");
+    put(0343,"ordfeminine");
+    put(0353,"ordmasculine");
+    put(0371,"oslash");
+    put(0160,"p");
+    put(0266,"paragraph");
+    put(050,"parenleft");
+    put(051,"parenright");
+    put(045,"percent");
+    put(056,"period");
+    put(0264,"periodcentered");
+    put(0275,"perthousand");
+    put(053,"plus");
+    put(0161,"q");
+    put(077,"question");
+    put(0277,"questiondown");
+    put(042,"quotedbl");
+    put(0271,"quotedblbase");
+    put(0252,"quotedblleft");
+    put(0272,"quotedblright");
+    put(0140,"quoteleft");
+    put(047,"quoteright");
+    put(0270,"quotesinglbase");
+    put(0251,"quotesingle");
+    put(0162,"r");
+    put(0312,"ring");
+    put(0163,"s");
+    put(0247,"section");
+    put(073,"semicolon");
+    put(067,"seven");
+    put(066,"six");
+    put(057,"slash");
+    put(040,"space");
+    put(0243,"sterling");
+    put(0164,"t");
+    put(063,"three");
+    put(0304,"tilde");
+    put(062,"two");
+    put(0165,"u");
+    put(0137,"underscore");
+    put(0166,"v");
+    put(0167,"w");
+    put(0170,"x");
+    put(0171,"y");
+    put(0245,"yen");
+    put(0172,"z");
+    put(060,"zero");
+  }
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/StandardType1Font.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/StandardType1Font.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/StandardType1Font.java	(revision 23703)
@@ -0,0 +1,257 @@
+/*
+  Copyright 2006-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.fonts;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.util.ByteArray;
+import it.stefanochizzolini.clown.util.ConvertUtils;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.util.EnumSet;
+import java.util.Hashtable;
+import java.util.Map;
+
+/**
+  Standard Type 1 font [PDF:1.6:5.5.1].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+*/
+public class StandardType1Font
+  extends Type1Font
+{
+  // <class>
+  // <classes>
+  public enum FamilyEnum
+  {
+    Courier(false),
+    Helvetica(false),
+    Times(false),
+    Symbol(true),
+    ZapfDingbats(true);
+
+    private boolean symbolic;
+
+    FamilyEnum(
+      boolean symbolic
+      )
+    {this.symbolic = symbolic;}
+
+    public boolean isSymbolic(
+      )
+    {return symbolic;}
+  };
+  // </classes>
+
+  // <dynamic>
+  // <constructors>
+  public StandardType1Font(
+    Document context,
+    FamilyEnum family,
+    boolean bold,
+    boolean italic
+    )
+  {
+    super(context);
+
+    String fontName = family.name();
+    switch(family)
+    {
+      case Symbol:
+      case ZapfDingbats:
+        break;
+      case Times:
+        if(bold)
+        {
+          fontName += "-Bold";
+          if(italic)
+          {fontName += "Italic";}
+        }
+        else if(italic)
+        {fontName += "-Italic";}
+        else
+        {fontName += "-Roman";}
+        break;
+      default:
+        if(bold)
+        {
+          fontName += "-Bold";
+          if(italic)
+          {fontName += "Oblique";}
+        }
+        else if(italic)
+        {fontName += "-Oblique";}
+        break;
+    }
+    PdfName encodingName = (family.isSymbolic() ? null : PdfName.WinAnsiEncoding);
+
+    create(fontName,encodingName);
+  }
+
+  /**
+    For internal use only.
+  */
+  public StandardType1Font(
+    PdfDirectObject baseObject
+    )
+  {super(baseObject);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public double getAscent(
+    )
+  {return metrics.ascender;}
+
+  @Override
+  public double getDescent(
+    )
+  {return metrics.descender;}
+
+  @Override
+  public EnumSet<FlagsEnum> getFlags(
+    )
+  {
+    //TODO:IMPL!!!
+    return EnumSet.noneOf(FlagsEnum.class);
+  }
+  // </public>
+
+  // <protected>
+  @Override
+  protected Map<ByteArray,Integer> getNativeEncoding(
+    )
+  {
+    if(symbolic) // Symbolic font.
+    {
+      Map<ByteArray,Integer> codes = new Hashtable<ByteArray,Integer>();
+      for(Map.Entry<Integer,Integer> glyphIndexEntry : glyphIndexes.entrySet())
+      {
+        codes.put(
+          new ByteArray(new byte[]{ConvertUtils.intToByteArray(glyphIndexEntry.getValue())[3]}),
+          glyphIndexEntry.getKey()
+          );
+      }
+      return codes;
+    }
+    else // Nonsymbolic font.
+      return Encoding.get(PdfName.StandardEncoding).getCodes();
+  }
+
+  @Override
+  protected void onLoad(
+    )
+  {
+    /*
+      NOTE: Standard Type 1 fonts ordinarily omit their descriptor;
+      otherwise, when overridden they degrade to a common Type 1 font.
+      Metrics of non-overridden Standard Type 1 fonts MUST be loaded from resources.
+    */
+    load((String)((PdfName)getBaseDataObject().get(PdfName.BaseFont)).getValue());
+
+    super.onLoad();
+  }
+  // </protected>
+
+  // <private>
+  /**
+    Creates the font structures.
+  */
+  private void create(
+    String fontName,
+    PdfName encodingName
+    )
+  {
+    /*
+      NOTE: Standard Type 1 fonts SHOULD omit extended font descriptions [PDF:1.6:5.5.1].
+    */
+    // Subtype.
+    getBaseDataObject().put(
+      PdfName.Subtype,
+      PdfName.Type1
+      );
+    // BaseFont.
+    getBaseDataObject().put(
+      PdfName.BaseFont,
+      new PdfName(fontName)
+      );
+    // Encoding.
+    if(encodingName != null)
+    {
+      getBaseDataObject().put(
+        PdfName.Encoding,
+        encodingName
+        );
+    }
+
+    load();
+  }
+
+  /**
+    Loads the font metrics.
+  */
+  private void load(
+    String fontName
+    )
+  {
+    BufferedReader fontMetricsStream = null;
+    try
+    {
+      fontMetricsStream = new BufferedReader(
+        new InputStreamReader(
+          getClass().getResourceAsStream("/fonts/afm/" + fontName + ".afm")
+          )
+        );
+
+      AfmParser parser = new AfmParser(fontMetricsStream);
+      metrics = parser.metrics;
+      symbolic = metrics.isCustomEncoding;
+      glyphIndexes = parser.glyphIndexes;
+      glyphKernings = parser.glyphKernings;
+      glyphWidths = parser.glyphWidths;
+    }
+    catch(Exception e)
+    {throw new RuntimeException("Failed to load '" + fontName + "'.",e);}
+    finally
+    {
+      try
+      {
+        if(fontMetricsStream != null)
+        {fontMetricsStream.close();}
+      }
+      catch(Exception e)
+      { /* Ignore */}
+    }
+  }
+  // </private>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/TrueTypeFont.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/TrueTypeFont.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/TrueTypeFont.java	(revision 23703)
@@ -0,0 +1,232 @@
+/*
+  Copyright 2009-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.fonts;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.objects.PdfArray;
+import it.stefanochizzolini.clown.objects.PdfDataObject;
+import it.stefanochizzolini.clown.objects.PdfDictionary;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfInteger;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfStream;
+import it.stefanochizzolini.clown.util.BiMap;
+import it.stefanochizzolini.clown.util.ByteArray;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+
+/**
+  TrueType font [PDF:1.6:5;OFF:2009].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+*/
+public class TrueTypeFont
+  extends SimpleFont
+{
+  // <class>
+  // <classes>
+  // </classes>
+
+  // <dynamic>
+  // <fields>
+  // </fields>
+
+  // <constructors>
+  TrueTypeFont(
+    PdfDirectObject baseObject
+    )
+  {super(baseObject);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public TrueTypeFont clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+  // </public>
+
+  // <protected>
+  @Override
+  protected void loadEncoding(
+    )
+  {
+    OpenFontParser parser;
+    {
+      PdfDictionary descriptor = getDescriptor();
+      if(descriptor.containsKey(PdfName.FontFile2)) // Embedded TrueType font file (without 'glyf' table).
+      {
+        PdfStream fontFileStream = (PdfStream)descriptor.resolve(PdfName.FontFile2);
+        parser = new OpenFontParser(fontFileStream.getBody());
+      }
+      else if(descriptor.containsKey(PdfName.FontFile3))
+      {
+        PdfStream fontFileStream = (PdfStream)descriptor.resolve(PdfName.FontFile3);
+        PdfName fontFileSubtype = (PdfName)fontFileStream.getHeader().get(PdfName.Subtype);
+        if(fontFileSubtype.equals(PdfName.OpenType)) // Embedded OpenFont/TrueType font file (with 'glyf' table).
+        {parser = new OpenFontParser(fontFileStream.getBody());}
+        else // Unknown.
+          throw new UnsupportedOperationException("Unknown embedded font file format: " + fontFileSubtype);
+      }
+      else
+      {parser = null;}
+    }
+    if(parser != null) // Embedded font file.
+    {
+      // Glyph indexes.
+      glyphIndexes = parser.glyphIndexes;
+      if(codes != null
+        && parser.metrics.isCustomEncoding)
+      {
+        /*
+          NOTE: In case of symbolic font,
+          glyph indices are natively mapped to character codes,
+          so they must be remapped to Unicode whenever possible
+          (i.e. when ToUnicode stream is available).
+        */
+        Map<Integer,Integer> unicodeGlyphIndexes = new Hashtable<Integer,Integer>();
+        for(Map.Entry<Integer,Integer> glyphIndexEntry : glyphIndexes.entrySet())
+        {
+          Integer code = codes.get(new ByteArray(new byte[]{(byte)(int)glyphIndexEntry.getKey()}));
+          if(code == null)
+            continue;
+
+          unicodeGlyphIndexes.put(code,glyphIndexEntry.getValue());
+        }
+        glyphIndexes = unicodeGlyphIndexes;
+      }
+    }
+
+    PdfDataObject encodingObject = getBaseDataObject().resolve(PdfName.Encoding);
+    EnumSet<FlagsEnum> flags = getFlags();
+    if(flags.contains(FlagsEnum.Symbolic)
+      || (!flags.contains(FlagsEnum.Nonsymbolic) && encodingObject == null)) // Symbolic.
+    {
+      symbolic = true;
+
+      if(glyphIndexes == null)
+      {
+        /*
+          NOTE: In case no font file is available, we have to synthesize its metrics
+          from existing entries.
+        */
+        glyphIndexes = new Hashtable<Integer,Integer>();
+        PdfArray glyphWidthObjects = (PdfArray)getBaseDataObject().resolve(PdfName.Widths);
+        if(glyphWidthObjects != null)
+        {
+          int code = ((PdfInteger)getBaseDataObject().get(PdfName.FirstChar)).getRawValue();
+          for(PdfDirectObject glyphWidthObject : glyphWidthObjects)
+          {
+            if(((PdfInteger)glyphWidthObject).getRawValue() > 0)
+            {glyphIndexes.put(code,code);}
+
+            code++;
+          }
+        }
+      }
+
+      if(codes == null)
+      {
+        Map<ByteArray,Integer> codes = new HashMap<ByteArray,Integer>();
+        for(Map.Entry<Integer,Integer> glyphIndexEntry : glyphIndexes.entrySet())
+        {
+          if(glyphIndexEntry.getValue() > 0)
+          {
+            int glyphCharCode = glyphIndexEntry.getKey();
+            byte[] charCode = new byte[]{(byte)glyphCharCode};
+            codes.put(new ByteArray(charCode),glyphCharCode);
+          }
+        }
+        this.codes = new BiMap<ByteArray,Integer>(codes);
+      }
+    }
+    else // Nonsymbolic.
+    {
+      symbolic = false;
+
+      if(codes == null)
+      {
+        Map<ByteArray,Integer> codes;
+        if(encodingObject == null) // Default encoding.
+        {codes = Encoding.get(PdfName.StandardEncoding).getCodes();}
+        else if(encodingObject instanceof PdfName) // Predefined encoding.
+        {codes = Encoding.get((PdfName)encodingObject).getCodes();}
+        else // Custom encoding.
+        {
+          PdfDictionary encodingDictionary = (PdfDictionary)encodingObject;
+
+          // 1. Base encoding.
+          PdfName baseEncodingName = (PdfName)encodingDictionary.get(PdfName.BaseEncoding);
+          if(baseEncodingName == null) // Default base encoding.
+          {codes = Encoding.get(PdfName.StandardEncoding).getCodes();}
+          else // Predefined base encoding.
+          {codes = Encoding.get(baseEncodingName).getCodes();}
+
+          // 2. Differences.
+          loadEncodingDifferences(encodingDictionary, codes);
+        }
+        this.codes = new BiMap<ByteArray,Integer>(codes);
+      }
+
+      if(glyphIndexes == null)
+      {
+        /*
+          NOTE: In case no font file is available, we have to synthesize its metrics
+          from existing entries.
+        */
+        glyphIndexes = new Hashtable<Integer,Integer>();
+        PdfArray glyphWidthObjects = (PdfArray)getBaseDataObject().resolve(PdfName.Widths);
+        if(glyphWidthObjects != null)
+        {
+          ByteArray charCode = new ByteArray(
+            new byte[]
+            {(byte)(int)((PdfInteger)getBaseDataObject().get(PdfName.FirstChar)).getRawValue()}
+            );
+          for(PdfDirectObject glyphWidthObject : glyphWidthObjects)
+          {
+            if(((PdfInteger)glyphWidthObject).getRawValue() > 0)
+            {
+              Integer code = codes.get(charCode);
+              if(code != null)
+              {glyphIndexes.put(code,(int)charCode.data[0]);}
+            }
+            charCode.data[0]++;
+          }
+        }
+      }
+    }
+  }
+  // </protected>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/Type0Font.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/Type0Font.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/Type0Font.java	(revision 23703)
@@ -0,0 +1,59 @@
+/*
+  Copyright 2009 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.fonts;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+
+/**
+  Composite font associated to a Type 0 CIDFont [PDF:1.6:5.6.3],
+  containing glyph descriptions based on the Adobe Type 1 font format.
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.8
+  @version 0.0.8
+*/
+/*
+  NOTE: Type 0 CIDFonts encompass several formats:
+  * CFF;
+  * OpenFont/CFF (in case "CFF" table's Top DICT has CIDFont operators).
+*/
+public class Type0Font
+  extends CompositeFont
+{
+  // <constructors>
+  Type0Font(
+    Document context,
+    OpenFontParser parser
+    )
+  {super(context,parser);}
+
+  Type0Font(
+    PdfDirectObject baseObject
+    )
+  {super(baseObject);}
+  // </constructors>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/Type1Font.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/Type1Font.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/Type1Font.java	(revision 23703)
@@ -0,0 +1,152 @@
+/*
+  Copyright 2007-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.fonts;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.objects.PdfDataObject;
+import it.stefanochizzolini.clown.objects.PdfDictionary;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfStream;
+import it.stefanochizzolini.clown.util.BiMap;
+import it.stefanochizzolini.clown.util.ByteArray;
+import it.stefanochizzolini.clown.util.ConvertUtils;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.util.Hashtable;
+import java.util.Map;
+
+/**
+  Type 1 font [PDF:1.6:5.5.1;AFM:4.1].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+*/
+/*
+  NOTE: Type 1 fonts encompass several formats:
+  * AFM+PFB;
+  * CFF;
+  * OpenFont/CFF (in case "CFF" table's Top DICT has no CIDFont operators).
+*/
+public class Type1Font
+  extends SimpleFont
+{
+  // <class>
+  // <dynamic>
+  // <fields>
+  protected AfmParser.FontMetrics metrics;
+  // </fields>
+
+  // <constructors>
+  Type1Font(
+    Document context
+    )
+  {super(context);}
+
+  Type1Font(
+    PdfDirectObject baseObject
+    )
+  {super(baseObject);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public Type1Font clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+  // </public>
+
+  // <protected>
+  protected Map<ByteArray,Integer> getNativeEncoding(
+    )
+  {
+    PdfDictionary descriptor = getDescriptor();
+    if(descriptor.containsKey(PdfName.FontFile)) // Embedded noncompact Type 1 font.
+    {
+      PdfStream fontFileStream = (PdfStream)descriptor.resolve(PdfName.FontFile);
+      PfbParser parser = new PfbParser(fontFileStream.getBody());
+      return parser.parse();
+    }
+    else if(descriptor.containsKey(PdfName.FontFile3)) // Embedded compact Type 1 font.
+    {
+      PdfStream fontFileStream = (PdfStream)descriptor.resolve(PdfName.FontFile3);
+      PdfName fontFileSubtype = (PdfName)fontFileStream.getHeader().get(PdfName.Subtype);
+      if(fontFileSubtype.equals(PdfName.Type1C)) // CFF.
+      {throw new NotImplementedException("Embedded CFF font file.");}
+      else if(fontFileSubtype.equals(PdfName.OpenType)) // OpenFont/CFF.
+      {throw new NotImplementedException("Embedded OpenFont/CFF font file.");}
+      else
+      {throw new UnsupportedOperationException("Unsupported embedded font file format: " + fontFileSubtype);}
+    }
+    else // Non-embedded font.
+    {return Encoding.get(PdfName.StandardEncoding).getCodes();}
+  }
+
+  @Override
+  protected void loadEncoding(
+    )
+  {//TODO: set symbolic = true/false; depending on the actual encoding!!!
+    // Encoding.
+    if(codes == null)
+    {
+      Map<ByteArray,Integer> codes;
+      PdfDataObject encodingObject = getBaseDataObject().resolve(PdfName.Encoding);
+      if(encodingObject == null) // Native encoding.
+      {codes = getNativeEncoding();}
+      else if(encodingObject instanceof PdfName) // Predefined encoding.
+      {codes = Encoding.get((PdfName)encodingObject).getCodes();}
+      else // Custom encoding.
+      {
+        PdfDictionary encodingDictionary = (PdfDictionary)encodingObject;
+
+        // 1. Base encoding.
+        PdfName baseEncodingName = (PdfName)encodingDictionary.get(PdfName.BaseEncoding);
+        if(baseEncodingName == null) // Native base encoding.
+        {codes = getNativeEncoding();}
+        else // Predefined base encoding.
+        {codes = Encoding.get(baseEncodingName).getCodes();}
+
+        // 2. Differences.
+        loadEncodingDifferences(encodingDictionary, codes);
+      }
+      this.codes = new BiMap<ByteArray,Integer>(codes);
+    }
+
+    // Glyph indexes.
+    if(glyphIndexes == null)
+    {
+      glyphIndexes = new Hashtable<Integer,Integer>();
+      for(Map.Entry<ByteArray,Integer> codeEntry : codes.entrySet())
+      {glyphIndexes.put(codeEntry.getValue(),ConvertUtils.byteArrayToInt(codeEntry.getKey().data));}
+    }
+  }
+  // </protected>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/Type2Font.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/Type2Font.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/Type2Font.java	(revision 23703)
@@ -0,0 +1,54 @@
+/*
+  Copyright 2009 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.fonts;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+
+/**
+  Composite font associated to a Type 2 CIDFont [PDF:1.6:5.6.3],
+  containing glyph descriptions based on the TrueType font format.
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.8
+  @version 0.0.8
+*/
+public class Type2Font
+  extends CompositeFont
+{
+  // <constructors>
+  Type2Font(
+    Document context,
+    OpenFontParser parser
+    )
+  {super(context,parser);}
+
+  Type2Font(
+    PdfDirectObject baseObject
+    )
+  {super(baseObject);}
+  // </constructors>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/Type3Font.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/Type3Font.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/Type3Font.java	(revision 23703)
@@ -0,0 +1,63 @@
+/*
+  Copyright 2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.fonts;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+/**
+  Type 3 font [PDF:1.6:5.5.4].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+  @since 0.0.8
+*/
+public class Type3Font
+  extends SimpleFont
+{
+//TODO:IMPL
+  Type3Font(
+    Document context
+    )
+  {super(context);}
+
+  Type3Font(
+    PdfDirectObject baseObject
+    )
+  {super(baseObject);}
+
+  @Override
+  public Type3Font clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  @Override
+  protected void loadEncoding() {
+    // TODO
+  }
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/WinAnsiEncoding.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/WinAnsiEncoding.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/WinAnsiEncoding.java	(revision 23703)
@@ -0,0 +1,258 @@
+/*
+  Copyright 2009 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.fonts;
+
+/**
+  Windows ANSI encoding (Windows Code Page 1252) [PDF:1.6:D].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+  @since 0.0.8
+*/
+class WinAnsiEncoding
+  extends Encoding
+{
+  public WinAnsiEncoding(
+    )
+  {
+    put(0101,"A");
+    put(0306,"AE");
+    put(0301,"Aacute");
+    put(0302,"Acircumflex");
+    put(0304,"Adieresis");
+    put(0300,"Agrave");
+    put(0305,"Aring");
+    put(0303,"Atilde");
+    put(0102,"B");
+    put(0103,"C");
+    put(0307,"Ccedilla");
+    put(0104,"D");
+    put(0105,"E");
+    put(0311,"Eacute");
+    put(0312,"Ecircumflex");
+    put(0313,"Edieresis");
+    put(0310,"Egrave");
+    put(0320,"Eth");
+    put(0200,"Euro");
+    put(0106,"F");
+    put(0107,"G");
+    put(0110,"H");
+    put(0111,"I");
+    put(0315,"Iacute");
+    put(0316,"Icircumflex");
+    put(0317,"Idieresis");
+    put(0314,"Igrave");
+    put(0112,"J");
+    put(0113,"K");
+    put(0114,"L");
+    put(0115,"M");
+    put(0116,"N");
+    put(0321,"Ntilde");
+    put(0117,"O");
+    put(0214,"OE");
+    put(0323,"Oacute");
+    put(0324,"Ocircumflex");
+    put(0326,"Odieresis");
+    put(0322,"Ograve");
+    put(0330,"Oslash");
+    put(0325,"Otilde");
+    put(0120,"P");
+    put(0121,"Q");
+    put(0122,"R");
+    put(0123,"S");
+    put(0212,"Scaron");
+    put(0124,"T");
+    put(0336,"Thorn");
+    put(0125,"U");
+    put(0332,"Uacute");
+    put(0333,"Ucircumflex");
+    put(0334,"Udieresis");
+    put(0331,"Ugrave");
+    put(0126,"V");
+    put(0127,"W");
+    put(0130,"X");
+    put(0131,"Y");
+    put(0335,"Yacute");
+    put(0237,"Ydieresis");
+    put(0132,"Z");
+    put(0216,"Zcaron");
+    put(0141,"a");
+    put(0341,"aacute");
+    put(0342,"acircumflex");
+    put(0264,"acute");
+    put(0344,"adieresis");
+    put(0346,"ae");
+    put(0340,"agrave");
+    put(046,"ampersand");
+    put(0345,"aring");
+    put(0136,"asciicircum");
+    put(0176,"asciitilde");
+    put(052,"asterisk");
+    put(0100,"at");
+    put(0343,"atilde");
+    put(0142,"b");
+    put(0134,"backslash");
+    put(0174,"bar");
+    put(0173,"braceleft");
+    put(0175,"braceright");
+    put(0133,"bracketleft");
+    put(0135,"bracketright");
+    put(0246,"brokenbar");
+    put(0225,"bullet");
+    put(0143,"c");
+    put(0347,"ccedilla");
+    put(0270,"cedilla");
+    put(0242,"cent");
+    put(0210,"circumflex");
+    put(072,"colon");
+    put(054,"comma");
+    put(0251,"copyright");
+    put(0244,"currency");
+    put(0144,"d");
+    put(0206,"dagger");
+    put(0207,"daggerdbl");
+    put(0260,"degree");
+    put(0250,"dieresis");
+    put(0367,"divide");
+    put(044,"dollar");
+    put(0145,"e");
+    put(0351,"eacute");
+    put(0352,"ecircumflex");
+    put(0353,"edieresis");
+    put(0350,"egrave");
+    put(070,"eight");
+    put(0205,"ellipsis");
+    put(0227,"emdash");
+    put(0226,"endash");
+    put(075,"equal");
+    put(0360,"eth");
+    put(041,"exclam");
+    put(0241,"exclamdown");
+    put(0146,"f");
+    put(065,"five");
+    put(0203,"florin");
+    put(064,"four");
+    put(0147,"g");
+    put(0337,"germandbls");
+    put(0140,"grave");
+    put(076,"greater");
+    put(0253,"guillemotleft");
+    put(0273,"guillemotright");
+    put(0213,"guilsinglleft");
+    put(0233,"guilsinglright");
+    put(0150,"h");
+    put(055,"hyphen");
+    put(0151,"i");
+    put(0355,"iacute");
+    put(0356,"icircumflex");
+    put(0357,"idieresis");
+    put(0354,"igrave");
+    put(0152,"j");
+    put(0153,"k");
+    put(0154,"l");
+    put(074,"less");
+    put(0254,"logicalnot");
+    put(0155,"m");
+    put(0257,"macron");
+    put(0265,"mu");
+    put(0327,"multiply");
+    put(0156,"n");
+    put(071,"nine");
+    put(0361,"ntilde");
+    put(043,"numbersign");
+    put(0157,"o");
+    put(0363,"oacute");
+    put(0364,"ocircumflex");
+    put(0366,"odieresis");
+    put(0234,"oe");
+    put(0362,"ograve");
+    put(061,"one");
+    put(0275,"onehalf");
+    put(0274,"onequarter");
+    put(0271,"onesuperior");
+    put(0252,"ordfeminine");
+    put(0272,"ordmasculine");
+    put(0370,"oslash");
+    put(0365,"otilde");
+    put(0160,"p");
+    put(0266,"paragraph");
+    put(050,"parenleft");
+    put(051,"parenright");
+    put(045,"percent");
+    put(056,"period");
+    put(0267,"periodcentered");
+    put(0211,"perthousand");
+    put(053,"plus");
+    put(0261,"plusminus");
+    put(0161,"q");
+    put(077,"question");
+    put(0277,"questiondown");
+    put(042,"quotedbl");
+    put(0204,"quotedblbase");
+    put(0223,"quotedblleft");
+    put(0224,"quotedblright");
+    put(0221,"quoteleft");
+    put(0222,"quoteright");
+    put(0202,"quotesinglbase");
+    put(047,"quotesingle");
+    put(0162,"r");
+    put(0256,"registered");
+    put(0163,"s");
+    put(0232,"scaron");
+    put(0247,"section");
+    put(073,"semicolon");
+    put(067,"seven");
+    put(066,"six");
+    put(057,"slash");
+    put(040,"space");
+    put(0243,"sterling");
+    put(0164,"t");
+    put(0376,"thorn");
+    put(063,"three");
+    put(0276,"threequarters");
+    put(0263,"threesuperior");
+    put(0230,"tilde");
+    put(0231,"trademark");
+    put(062,"two");
+    put(0262,"twosuperior");
+    put(0165,"u");
+    put(0372,"uacute");
+    put(0373,"ucircumflex");
+    put(0374,"udieresis");
+    put(0371,"ugrave");
+    put(0137,"underscore");
+    put(0166,"v");
+    put(0167,"w");
+    put(0170,"x");
+    put(0171,"y");
+    put(0375,"yacute");
+    put(0377,"ydieresis");
+    put(0245,"yen");
+    put(0172,"z");
+    put(0236,"zcaron");
+    put(060,"zero");
+  }
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/package.html
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/package.html	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/fonts/package.html	(revision 23703)
@@ -0,0 +1,37 @@
+<html>
+<head>
+<!--
+  Copyright 2006-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+-->
+</head>
+<body>
+<p>Font type definitions used to draw text inside content streams [PDF:1.6:5].</p>
+
+<h2>Related Documentation</h2>
+<p>For overviews, tutorials, examples, guides, and tool documentation, please see:</p>
+<ul>
+  <li><a href="http://clown.stefanochizzolini.it">PDF Clown Home Page</a>
+</ul>
+</body>
+</html>
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/BeginInlineImage.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/BeginInlineImage.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/BeginInlineImage.java	(revision 23703)
@@ -0,0 +1,55 @@
+/*
+  Copyright 2007 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+/**
+  'Begin inline image object' operation [PDF:1.6:4.8.6].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.4
+  @version 0.0.4
+*/
+public final class BeginInlineImage
+  extends Operation
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final BeginInlineImage Value = new BeginInlineImage();
+
+  public static final String Operator = "BI";
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  private BeginInlineImage(
+    )
+  {super(Operator);}
+  // </constructors>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/BeginMarkedContent.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/BeginMarkedContent.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/BeginMarkedContent.java	(revision 23703)
@@ -0,0 +1,118 @@
+/*
+  Copyright 2008-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+
+/**
+  'Begin marked-content sequence' operation [PDF:1.6:10.5].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.7
+  @version 0.0.8
+*/
+public final class BeginMarkedContent
+  extends Operation
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final String PropertyListOperator = "BDC";
+  public static final String SimpleOperator = "BMC";
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  public BeginMarkedContent(
+    PdfName tag
+    )
+  {
+    super(
+      SimpleOperator,
+      tag
+      );
+  }
+
+  public BeginMarkedContent(
+    PdfName tag,
+    PdfDirectObject properties
+    )
+  {
+    super(
+      PropertyListOperator,
+      tag, properties
+      );
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  /**
+    Gets the private information meaningful to the program (application or plugin extension)
+    creating the marked content.
+  */
+  public PdfDirectObject getProperties(
+    )
+  {return operands.get(1);}
+
+  /**
+    Gets the role or significance of the marked content.
+  */
+  public PdfName getTag(
+    )
+  {return (PdfName)operands.get(0);}
+
+  public void setProperties(
+    PdfDirectObject value
+    )
+  {
+    if(value == null)
+    {
+      operator = SimpleOperator;
+      if(operands.size() > 1)
+      {operands.remove(1);}
+    }
+    else
+    {
+      operator = PropertyListOperator;
+      if(operands.size() > 1)
+      {operands.set(1,value);}
+      else
+      {operands.add(value);}
+    }
+  }
+
+  public void setTag(
+    PdfName value
+    )
+  {operands.set(0,value);}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/BeginSubpath.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/BeginSubpath.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/BeginSubpath.java	(revision 23703)
@@ -0,0 +1,120 @@
+/*
+  Copyright 2008-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+import it.stefanochizzolini.clown.objects.IPdfNumber;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfReal;
+
+import java.awt.geom.Point2D;
+import java.util.List;
+
+/**
+  'Begin a new subpath by moving the current point' operation
+  [PDF:1.6:4.4.1].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.7
+  @version 0.0.8
+*/
+public final class BeginSubpath
+  extends Operation
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final String Operator = "m";
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  /**
+    @param point Current point.
+  */
+  public BeginSubpath(
+    Point2D point
+    )
+  {
+    this(
+      point.getX(),
+      point.getY()
+      );
+  }
+
+  /**
+    @param pointX Current point X.
+    @param pointY Current point Y.
+  */
+  public BeginSubpath(
+    double pointX,
+    double pointY
+    )
+  {
+    super(
+      Operator,
+      new PdfReal(pointX),
+      new PdfReal(pointY)
+      );
+  }
+
+  public BeginSubpath(
+    List<PdfDirectObject> operands
+    )
+  {super(Operator,operands);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  /**
+    Gets the current point.
+  */
+  public Point2D getPoint(
+    )
+  {
+    return new Point2D.Double(
+      ((IPdfNumber)operands.get(0)).getNumberValue(),
+      ((IPdfNumber)operands.get(1)).getNumberValue()
+      );
+  }
+
+  /**
+    Sets the current point.
+
+    @see #getPoint()
+  */
+  public void setPoint(
+    Point2D value
+    )
+  {
+    ((IPdfNumber)operands.get(0)).setNumberValue(value.getX());
+    ((IPdfNumber)operands.get(1)).setNumberValue(value.getY());
+  }
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/BeginText.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/BeginText.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/BeginText.java	(revision 23703)
@@ -0,0 +1,55 @@
+/*
+  Copyright 2007 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+/**
+  'Begin text object' operation [PDF:1.6:5.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.4
+  @version 0.0.4
+*/
+public final class BeginText
+  extends Operation
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final BeginText Value = new BeginText();
+
+  public static final String Operator = "BT";
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  private BeginText(
+    )
+  {super(Operator);}
+  // </constructors>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/CloseFillStroke.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/CloseFillStroke.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/CloseFillStroke.java	(revision 23703)
@@ -0,0 +1,56 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+/**
+  'Close, fill, and then stroke the path, using the nonzero winding number rule to determine
+  the region to fill' operation [PDF:1.6:4.4.2].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.7
+  @version 0.0.7
+*/
+public final class CloseFillStroke
+  extends PaintPath
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final CloseFillStroke Value = new CloseFillStroke();
+
+  public static final String Operator = "b";
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  private CloseFillStroke(
+    )
+  {super(Operator);}
+  // </constructors>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/CloseFillStrokeEvenOdd.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/CloseFillStrokeEvenOdd.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/CloseFillStrokeEvenOdd.java	(revision 23703)
@@ -0,0 +1,56 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+/**
+  'Close, fill, and then stroke the path, using the even-odd rule to determine the region
+  to fill' operation [PDF:1.6:4.4.2].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.7
+  @version 0.0.7
+*/
+public final class CloseFillStrokeEvenOdd
+  extends PaintPath
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final CloseFillStrokeEvenOdd Value = new CloseFillStrokeEvenOdd();
+
+  public static final String Operator = "b*";
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  private CloseFillStrokeEvenOdd(
+    )
+  {super(Operator);}
+  // </constructors>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/CloseStroke.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/CloseStroke.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/CloseStroke.java	(revision 23703)
@@ -0,0 +1,55 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+/**
+  'Close and stroke the path' operation [PDF:1.6:4.4.2].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.7
+  @version 0.0.7
+*/
+public final class CloseStroke
+  extends PaintPath
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final CloseStroke Value = new CloseStroke();
+
+  public static final String Operator = "s";
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  private CloseStroke(
+    )
+  {super(Operator);}
+  // </constructors>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/CloseSubpath.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/CloseSubpath.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/CloseSubpath.java	(revision 23703)
@@ -0,0 +1,57 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+/**
+  'Close the current subpath by appending a straight line segment
+  from the current point to the starting point of the subpath' operation
+  [PDF:1.6:4.4.1].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.7
+  @version 0.0.7
+*/
+public final class CloseSubpath
+  extends Operation
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final CloseSubpath Value = new CloseSubpath();
+
+  public static final String Operator = "h";
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  public CloseSubpath(
+    )
+  {super(Operator);}
+  // </constructors>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/CompositeObject.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/CompositeObject.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/CompositeObject.java	(revision 23703)
@@ -0,0 +1,119 @@
+/*
+  Copyright 2007-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+import it.stefanochizzolini.clown.bytes.IOutputStream;
+import it.stefanochizzolini.clown.documents.contents.ContentScanner;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+  Composite object. It is made up of multiple content objects.
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.4
+  @version 0.0.8
+*/
+public abstract class CompositeObject
+  extends ContentObject
+{
+  // <class>
+  // <dynamic>
+  // <fields>
+  protected List<ContentObject> objects;
+  // </fields>
+
+  // <constructors>
+  protected CompositeObject(
+    )
+  {this.objects = new ArrayList<ContentObject>(2);}
+
+  protected CompositeObject(
+    ContentObject object
+    )
+  {
+    this();    
+    objects.add(object);
+  }
+
+  protected CompositeObject(
+    ContentObject... objects
+    )
+  {
+    this();
+    for(ContentObject object : objects)
+    {this.objects.add(object);}
+  }
+
+  protected CompositeObject(
+    List<ContentObject> objects
+    )
+  {this.objects = objects;}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public void applyTo(
+    ContentScanner.GraphicsState state
+    )
+  {
+    // Update the current level's graphics state according to the current object's final graphics state!
+    ContentScanner childLevel = state.getScanner().getChildLevel();
+    childLevel.moveEnd(); // Forces the current object to its final graphics state.
+    childLevel.getState().copyTo(state); // Copies the current object's final graphics state to the current level's.
+  }
+
+  /**
+    Gets the list of inner objects.
+  */
+  public List<ContentObject> getObjects(
+    )
+  {return objects;}
+  
+  @Override
+  public String toString(
+    )
+  {
+    return "{"
+      + objects.toString()
+      + "}";
+  }
+  
+  @Override
+  public void writeTo(
+    IOutputStream stream
+    )
+  {
+    for(ContentObject object : objects)
+    {object.writeTo(stream);}
+  }
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/ContainerObject.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/ContainerObject.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/ContainerObject.java	(revision 23703)
@@ -0,0 +1,65 @@
+/*
+  Copyright 2007-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+import java.util.List;
+
+/**
+  Container object.
+  It encompasses multiple content objects.
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.4
+  @version 0.0.8
+*/
+public abstract class ContainerObject
+  extends CompositeObject
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  protected ContainerObject(
+    )
+  {super();}
+
+  protected ContainerObject(
+    ContentObject object
+    )
+  {super(object);}
+
+  protected ContainerObject(
+    ContentObject... objects
+    )
+  {super(objects);}
+
+  protected ContainerObject(
+    List<ContentObject> objects
+    )
+  {super(objects);}
+  // </constructors>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/ContentObject.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/ContentObject.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/ContentObject.java	(revision 23703)
@@ -0,0 +1,66 @@
+/*
+  Copyright 2007-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+import it.stefanochizzolini.clown.documents.contents.ContentScanner;
+
+import it.stefanochizzolini.clown.bytes.IOutputStream;
+
+/**
+  Abstract content object [PDF:1.6:4.1].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.4
+  @version 0.0.8
+*/
+public abstract class ContentObject
+{
+  // <class>
+  // <dynamic>
+  // <interface>
+  // <public>
+  /**
+    Applies the object's state to the specified graphics state.
+
+    @param state Content scanner graphics state.
+    @since 0.0.8
+  */
+  public void applyTo(
+    ContentScanner.GraphicsState state
+    )
+  {/* Do nothing by default. */}
+
+  /**
+    Writes PDF representation of the object to the target buffer.
+  */
+  public abstract void writeTo(
+    IOutputStream stream
+    );
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/DrawCurve.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/DrawCurve.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/DrawCurve.java	(revision 23703)
@@ -0,0 +1,246 @@
+/*
+  Copyright 2008-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+import it.stefanochizzolini.clown.objects.IPdfNumber;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfReal;
+
+import java.awt.geom.Point2D;
+import java.util.List;
+
+/**
+  'Append a cubic Bezier curve to the current path' operation
+  [PDF:1.6:4.4.1].
+  <p>Such curves are defined by four points:
+  the two endpoints (the current point and the final point)
+  and two control points (the first control point, associated to the current point,
+  and the second control point, associated to the final point).</p>
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.7
+  @version 0.0.8
+*/
+public final class DrawCurve
+  extends Operation
+{
+  // <class>
+  // <static>
+  // <fields>
+  /**
+    Specifies only the second control point
+    (the first control point coincides with initial point of the curve).
+  */
+  public static final String FinalOperator = "v";
+  /**
+    Specifies both control points explicitly.
+  */
+  public static final String FullOperator = "c";
+  /**
+    Specifies only the first control point
+    (the second control point coincides with final point of the curve).
+  */
+  public static final String InitialOperator = "y";
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  /**
+    Creates a fully-explicit curve.
+
+    @param point Final endpoint.
+    @param control1 First control point.
+    @param control2 Second control point.
+  */
+  public DrawCurve(
+    Point2D point,
+    Point2D control1,
+    Point2D control2
+    )
+  {
+    this(
+      point.getX(),
+      point.getY(),
+      control1.getX(),
+      control1.getY(),
+      control2.getX(),
+      control2.getY()
+      );
+  }
+
+  /**
+    Creates a fully-explicit curve.
+  */
+  public DrawCurve(
+    double pointX,
+    double pointY,
+    double control1X,
+    double control1Y,
+    double control2X,
+    double control2Y
+    )
+  {
+    super(
+      FullOperator,
+      new PdfReal(control1X),
+      new PdfReal(control1Y),
+      new PdfReal(control2X),
+      new PdfReal(control2Y),
+      new PdfReal(pointX),
+      new PdfReal(pointY)
+      );
+  }
+
+  /**
+    Creates a partially-explicit curve.
+
+    @param point Final endpoint.
+    @param control Explicit control point.
+    @param operator Operator (either <code>InitialOperator</code> or <code>FinalOperator</code>). It defines how to interpret the <code>control</code> parameter.
+  */
+  public DrawCurve(
+    Point2D point,
+    Point2D control,
+    String operator
+    )
+  {
+    super(
+      operator.equals(InitialOperator) ? InitialOperator : FinalOperator,
+      new PdfReal(control.getX()),
+      new PdfReal(control.getY()),
+      new PdfReal(point.getX()),
+      new PdfReal(point.getY())
+      );
+  }
+
+  public DrawCurve(
+    String operator,
+    List<PdfDirectObject> operands
+    )
+  {super(operator,operands);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  /**
+    Gets the first control point.
+  */
+  public Point2D getControl1(
+    )
+  {
+    if(operator.equals(FinalOperator))
+      return null;
+
+    return new Point2D.Double(
+      ((IPdfNumber)operands.get(0)).getNumberValue(),
+      ((IPdfNumber)operands.get(1)).getNumberValue()
+      );
+  }
+
+  /**
+    Gets the second control point.
+  */
+  public Point2D getControl2(
+    )
+  {
+    if(operator.equals(InitialOperator))
+      return null;
+    if(operator.equals(FinalOperator))
+      return new Point2D.Double(
+        ((IPdfNumber)operands.get(0)).getNumberValue(),
+        ((IPdfNumber)operands.get(1)).getNumberValue()
+        );
+    // Full operator.
+    return new Point2D.Double(
+      ((IPdfNumber)operands.get(2)).getNumberValue(),
+      ((IPdfNumber)operands.get(3)).getNumberValue()
+      );
+  }
+
+  /**
+    Gets the final endpoint.
+  */
+  public Point2D getPoint(
+    )
+  {
+    return new Point2D.Double(
+      ((IPdfNumber)operands.get(0)).getNumberValue(),
+      ((IPdfNumber)operands.get(1)).getNumberValue()
+      );
+  }
+
+  /**
+    @see #getControl1()
+  */
+  public void setControl1(
+    Point2D value
+    )
+  {
+    if(operator.equals(FinalOperator))
+    {operator = FullOperator;}
+
+    ((IPdfNumber)operands.get(0)).setNumberValue(value.getX());
+    ((IPdfNumber)operands.get(1)).setNumberValue(value.getY());
+  }
+
+  /**
+    @see #getControl2()
+  */
+  public void setControl2(
+    Point2D value
+    )
+  {
+    if(operator.equals(InitialOperator))
+    {operator = FullOperator;}
+
+    if(operator.equals(FinalOperator))
+    {
+      ((IPdfNumber)operands.get(0)).setNumberValue(value.getX());
+      ((IPdfNumber)operands.get(1)).setNumberValue(value.getY());
+    }
+    else // Full operator.
+    {
+      ((IPdfNumber)operands.get(2)).setNumberValue(value.getX());
+      ((IPdfNumber)operands.get(3)).setNumberValue(value.getY());
+    }
+  }
+
+  /**
+    @see #getPoint()
+  */
+  public void setPoint(
+    Point2D value
+    )
+  {
+    ((IPdfNumber)operands.get(0)).setNumberValue(value.getX());
+    ((IPdfNumber)operands.get(1)).setNumberValue(value.getY());
+  }
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/DrawLine.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/DrawLine.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/DrawLine.java	(revision 23703)
@@ -0,0 +1,120 @@
+/*
+  Copyright 2008-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+import it.stefanochizzolini.clown.objects.IPdfNumber;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfReal;
+
+import java.awt.geom.Point2D;
+import java.util.List;
+
+/**
+  'Append a straight line segment from the current point' operation
+  [PDF:1.6:4.4.1].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.7
+  @version 0.0.8
+*/
+public final class DrawLine
+  extends Operation
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final String Operator = "l";
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  /**
+    @param point Final endpoint.
+  */
+  public DrawLine(
+    Point2D point
+    )
+  {
+    this(
+      point.getX(),
+      point.getY()
+      );
+  }
+
+  /**
+    @param pointX Final endpoint X.
+    @param pointY Final endpoint Y.
+  */
+  public DrawLine(
+    double pointX,
+    double pointY
+    )
+  {
+    super(
+      Operator,
+      new PdfReal(pointX),
+      new PdfReal(pointY)
+      );
+  }
+
+  public DrawLine(
+    List<PdfDirectObject> operands
+    )
+  {super(Operator,operands);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  /**
+    Gets the final endpoint.
+  */
+  public Point2D getPoint(
+    )
+  {
+    return new Point2D.Double(
+      ((IPdfNumber)operands.get(0)).getNumberValue(),
+      ((IPdfNumber)operands.get(1)).getNumberValue()
+      );
+  }
+
+  /**
+    Sets the final endpoint.
+
+    @see #getPoint()
+  */
+  public void setPoint(
+    Point2D value
+    )
+  {
+    ((IPdfNumber)operands.get(0)).setNumberValue(value.getX());
+    ((IPdfNumber)operands.get(1)).setNumberValue(value.getY());
+  }
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/DrawRectangle.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/DrawRectangle.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/DrawRectangle.java	(revision 23703)
@@ -0,0 +1,129 @@
+/*
+  Copyright 2007-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+import it.stefanochizzolini.clown.objects.IPdfNumber;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfReal;
+
+import java.util.List;
+
+/**
+  'Append a rectangle to the current path as a complete subpath' operation
+  [PDF:1.6:4.4.1].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.4
+  @version 0.0.8
+*/
+public final class DrawRectangle
+  extends Operation
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final String Operator = "re";
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  public DrawRectangle(
+    double x,
+    double y,
+    double width,
+    double height
+    )
+  {
+    super(
+      Operator,
+      new PdfReal(x),
+      new PdfReal(y),
+      new PdfReal(width),
+      new PdfReal(height)
+      );
+  }
+
+  public DrawRectangle(
+    List<PdfDirectObject> operands
+    )
+  {super(Operator,operands);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  public double getHeight(
+    )
+  {return ((IPdfNumber)operands.get(3)).getNumberValue();}
+
+  public double getWidth(
+    )
+  {return ((IPdfNumber)operands.get(2)).getNumberValue();}
+
+  public double getX(
+    )
+  {return ((IPdfNumber)operands.get(0)).getNumberValue();}
+
+  public double getY(
+    )
+  {return ((IPdfNumber)operands.get(1)).getNumberValue();}
+
+  /**
+    @since 0.0.6
+  */
+  public void setHeight(
+    double value
+    )
+  {((IPdfNumber)operands.get(3)).setNumberValue(value);}
+
+  /**
+    @since 0.0.6
+  */
+  public void setWidth(
+    double value
+    )
+  {((IPdfNumber)operands.get(2)).setNumberValue(value);}
+
+  /**
+    @since 0.0.6
+  */
+  public void setX(
+    double value
+    )
+  {((IPdfNumber)operands.get(0)).setNumberValue(value);}
+
+  /**
+    @since 0.0.6
+  */
+  public void setY(
+    double value
+    )
+  {((IPdfNumber)operands.get(1)).setNumberValue(value);}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/EndInlineImage.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/EndInlineImage.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/EndInlineImage.java	(revision 23703)
@@ -0,0 +1,55 @@
+/*
+  Copyright 2007 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+/**
+  'End inline image object' operation [PDF:1.6:4.8.6].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.4
+  @version 0.0.4
+*/
+public final class EndInlineImage
+  extends Operation
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final EndInlineImage Value = new EndInlineImage();
+
+  public static final String Operator = "EI";
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  private EndInlineImage(
+    )
+  {super(Operator);}
+  // </constructors>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/EndMarkedContent.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/EndMarkedContent.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/EndMarkedContent.java	(revision 23703)
@@ -0,0 +1,55 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+/**
+  'End marked-content sequence' operation [PDF:1.6:10.5].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.7
+  @version 0.0.7
+*/
+public final class EndMarkedContent
+  extends Operation
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final EndMarkedContent Value = new EndMarkedContent();
+
+  public static final String Operator = "EMC";
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  private EndMarkedContent(
+    )
+  {super(Operator);}
+  // </constructors>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/EndPathNoOp.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/EndPathNoOp.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/EndPathNoOp.java	(revision 23703)
@@ -0,0 +1,55 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+/**
+  'End the path object without filling or stroking it' operation [PDF:1.6:4.4.2].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.7
+  @version 0.0.7
+*/
+public final class EndPathNoOp
+  extends PaintPath
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final EndPathNoOp Value = new EndPathNoOp();
+
+  public static final String Operator = "n";
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  private EndPathNoOp(
+    )
+  {super(Operator);}
+  // </constructors>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/EndText.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/EndText.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/EndText.java	(revision 23703)
@@ -0,0 +1,55 @@
+/*
+  Copyright 2007 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+/**
+  'End text object' operation [PDF:1.6:5.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.4
+  @version 0.0.4
+*/
+public final class EndText
+  extends Operation
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final EndText Value = new EndText();
+
+  public static final String Operator = "ET";
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  private EndText(
+    )
+  {super(Operator);}
+  // </constructors>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/Fill.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/Fill.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/Fill.java	(revision 23703)
@@ -0,0 +1,57 @@
+/*
+  Copyright 2007-2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+/**
+  'Fill the path, using the nonzero winding number rule to determine the region to fill' operation
+  [PDF:1.6:4.4.2].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.4
+  @version 0.0.7
+*/
+public final class Fill
+  extends PaintPath
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final Fill Value = new Fill();
+
+  public static final String Operator = "f";
+  public static final String ObsoleteOperator = "F";
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  private Fill(
+    )
+  {super(Operator);}
+  // </constructors>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/FillEvenOdd.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/FillEvenOdd.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/FillEvenOdd.java	(revision 23703)
@@ -0,0 +1,56 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+/**
+  'Fill the path, using the even-odd rule to determine the region to fill' operation
+  [PDF:1.6:4.4.2].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.7
+  @version 0.0.7
+*/
+public final class FillEvenOdd
+  extends PaintPath
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final FillEvenOdd Value = new FillEvenOdd();
+
+  public static final String Operator = "f*";
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  private FillEvenOdd(
+    )
+  {super(Operator);}
+  // </constructors>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/FillStroke.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/FillStroke.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/FillStroke.java	(revision 23703)
@@ -0,0 +1,56 @@
+/*
+  Copyright 2007-2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+/**
+  'Fill and then stroke the path, using the nonzero winding number rule to determine the region to
+  fill' operation [PDF:1.6:4.4.2].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.4
+  @version 0.0.7
+*/
+public final class FillStroke
+  extends PaintPath
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final FillStroke Value = new FillStroke();
+
+  public static final String Operator = "B";
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  private FillStroke(
+    )
+  {super(Operator);}
+  // </constructors>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/FillStrokeEvenOdd.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/FillStrokeEvenOdd.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/FillStrokeEvenOdd.java	(revision 23703)
@@ -0,0 +1,56 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+/**
+  'Fill and then stroke the path, using the even-odd rule to determine the region to fill' operation
+  [PDF:1.6:4.4.2].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.7
+  @version 0.0.7
+*/
+public final class FillStrokeEvenOdd
+  extends PaintPath
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final FillStrokeEvenOdd Value = new FillStrokeEvenOdd();
+
+  public static final String Operator = "B*";
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  private FillStrokeEvenOdd(
+    )
+  {super(Operator);}
+  // </constructors>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/GenericOperation.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/GenericOperation.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/GenericOperation.java	(revision 23703)
@@ -0,0 +1,66 @@
+/*
+  Copyright 2009 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+
+import java.util.List;
+
+/**
+  Weakly-typed operation.
+  <h3>Remarks</h3>
+  <p>This is used to model operations which do not have a dedicated type.</p>
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.8
+  @version 0.0.8
+*/
+public final class GenericOperation
+  extends Operation
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  public GenericOperation(
+    String operator
+    )
+  {super(operator);}
+
+  public GenericOperation(
+    String operator,
+    PdfDirectObject operand
+    )
+  {super(operator,operand);}
+
+  public GenericOperation(
+    String operator,
+    List<PdfDirectObject> operands
+    )
+  {super(operator,operands);}
+  // </constructors>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/GraphicsObject.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/GraphicsObject.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/GraphicsObject.java	(revision 23703)
@@ -0,0 +1,64 @@
+/*
+  Copyright 2007-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+import java.util.List;
+
+/**
+  Graphics object [PDF:1.6:4.1].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.4
+  @version 0.0.8
+*/
+public abstract class GraphicsObject
+  extends CompositeObject
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  protected GraphicsObject(
+    )
+  {super();}
+
+  protected GraphicsObject(
+    ContentObject object
+    )
+  {super(object);}
+
+  protected GraphicsObject(
+    ContentObject... objects
+    )
+  {super(objects);}
+
+  protected GraphicsObject(
+    List<ContentObject> objects
+    )
+  {super(objects);}
+  // </constructors>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/InlineImage.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/InlineImage.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/InlineImage.java	(revision 23703)
@@ -0,0 +1,108 @@
+/*
+  Copyright 2007-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+import it.stefanochizzolini.clown.bytes.IOutputStream;
+import it.stefanochizzolini.clown.objects.IPdfNumber;
+import it.stefanochizzolini.clown.objects.PdfName;
+
+import java.awt.Dimension;
+import java.awt.geom.Dimension2D;
+
+/**
+  Inline image object [PDF:1.6:4.8.6].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.4
+  @version 0.0.8
+*/
+public final class InlineImage
+  extends GraphicsObject
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final String BeginOperator = BeginInlineImage.Operator;
+  public static final String EndOperator = EndInlineImage.Operator;
+
+  private static final String DataOperator = "ID";
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  public InlineImage(
+    InlineImageHeader header,
+    InlineImageBody body
+    )
+  {super(header,body);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  /**
+    Gets the image body.
+   */
+  public InlineImageBody getBody(
+    )
+  {return (InlineImageBody)getObjects().get(1);}
+
+  /**
+    Gets the image header.
+  */
+  public InlineImageHeader getHeader(
+    )
+  {return (InlineImageHeader)getObjects().get(0);}
+
+  /**
+    Gets the image size.
+  */
+  public Dimension2D getSize(
+    )
+  {
+    InlineImageHeader header = getHeader();
+    return new Dimension(
+      (int)((IPdfNumber)header.get(header.containsKey(PdfName.W) ? PdfName.W : PdfName.Width)).getNumberValue(),
+      (int)((IPdfNumber)header.get(header.containsKey(PdfName.H) ? PdfName.H : PdfName.Height)).getNumberValue()
+      );
+  }
+
+  @Override
+  public void writeTo(
+    IOutputStream stream
+    )
+  {
+    stream.write(BeginOperator); stream.write("\n");
+    getHeader().writeTo(stream);
+    stream.write(DataOperator); stream.write("\n");
+    getBody().writeTo(stream); stream.write("\n"); // [FIX:0.0.4:3] Missed new-line symbol.
+    stream.write(EndOperator);
+  }
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/InlineImageBody.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/InlineImageBody.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/InlineImageBody.java	(revision 23703)
@@ -0,0 +1,86 @@
+/*
+  Copyright 2007-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+import it.stefanochizzolini.clown.bytes.IBuffer;
+import it.stefanochizzolini.clown.bytes.IOutputStream;
+
+/**
+  Inline image data (anonymous) operation [PDF:1.6:4.8.6].
+  <h3>Remarks</h3>
+  <p>This is a figurative operation necessary to constrain the inline image data section
+  within the content stream model.</p>
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.4
+  @version 0.0.8
+*/
+public final class InlineImageBody
+  extends Operation
+{
+  // <class>
+  // <static>
+  // <fields>
+  private IBuffer value;
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  public InlineImageBody(
+    IBuffer value
+    )
+  {
+    super(null);
+
+    this.value = value;
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  public IBuffer getValue(
+    )
+  {return value;}
+
+  /**
+    @since 0.0.6
+  */
+  public void setValue(
+    IBuffer value
+    )
+  {this.value = value;}
+
+  @Override
+  public void writeTo(
+    IOutputStream stream
+    )
+  {stream.write(value);}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/InlineImageHeader.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/InlineImageHeader.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/InlineImageHeader.java	(revision 23703)
@@ -0,0 +1,229 @@
+/*
+  Copyright 2007-2009 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+  Inline image entries (anonymous) operation [PDF:1.6:4.8.6].
+  <h3>Remarks</h3>
+  This is a figurative operation necessary to constrain the inline image entries section
+  within the content stream model.
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.4
+  @version 0.0.8
+*/
+public final class InlineImageHeader
+  extends Operation
+  implements Map<PdfName,PdfDirectObject>
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  // [FIX:0.0.4:2] Null operator.
+  public InlineImageHeader(
+    List<PdfDirectObject> operands
+    )
+  {super("",operands);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  // <Map>
+  public void clear(
+    )
+  {operands.clear();}
+
+  public boolean containsKey(
+    Object key
+    )
+  {return getKeyIndex(key) != null;}
+
+  public boolean containsValue(
+    Object value
+    )
+  {
+    for(
+      int index = 1,
+        length = operands.size() - 1;
+      index < length;
+      index += 2
+      )
+    {
+      if(operands.get(index).equals(value))
+        return true;
+    }
+    return false;
+  }
+
+  public Set<Map.Entry<PdfName,PdfDirectObject>> entrySet(
+    )
+  {throw new NotImplementedException();}
+
+  public boolean equals(
+    PdfDirectObject object
+    )
+  {throw new NotImplementedException();}
+
+  public PdfDirectObject get(
+    Object key
+    )
+  {
+    Integer index = getKeyIndex(key);
+    if(index == null)
+      return null;
+
+    return operands.get(index+1);
+  }
+
+  public int hashCode(
+    )
+  {throw new NotImplementedException();}
+
+  public boolean isEmpty(
+    )
+  {return operands.isEmpty();}
+
+  public Set<PdfName> keySet(
+    )
+  {
+    Set<PdfName> keys = new HashSet<PdfName>();
+    for(
+      int index = 0,
+        length = operands.size() - 1;
+      index < length;
+      index += 2
+      )
+    {keys.add((PdfName)operands.get(index));}
+    return keys;
+  }
+
+  public PdfDirectObject put(
+    PdfName key,
+    PdfDirectObject value
+    )
+  {
+    PdfDirectObject oldValue;
+    {
+      Integer index = getKeyIndex(key);
+      if(index == null)
+      {
+        oldValue = null;
+
+        operands.add(key);
+        operands.add(value);
+      }
+      else
+      {
+        oldValue = operands.get(index+1);
+
+        operands.set(index,key);
+        operands.set(index+1,value);
+      }
+    }
+    return oldValue;
+  }
+
+  public void putAll(
+    Map<? extends PdfName,? extends PdfDirectObject> entries
+    )
+  {
+    for(Map.Entry<? extends PdfName,? extends PdfDirectObject> entry : entries.entrySet())
+    {put(entry.getKey(),entry.getValue());}
+  }
+
+  public PdfDirectObject remove(
+    Object key
+    )
+  {
+    PdfDirectObject oldValue;
+    {
+      Integer index = getKeyIndex(key);
+      if(index == null)
+      {oldValue = null;}
+      else
+      {
+        oldValue = operands.get(index+1);
+
+        operands.remove(index);
+        operands.remove(index);
+      }
+    }
+    return oldValue;
+  }
+
+  public int size(
+    )
+  {return operands.size() / 2;}
+
+  public Collection<PdfDirectObject> values(
+    )
+  {
+    Collection<PdfDirectObject> values = new ArrayList<PdfDirectObject>();
+    for(
+      int index = 1,
+        length = operands.size() - 1;
+      index < length;
+      index += 2
+      )
+    {values.add(operands.get(index));}
+    return values;
+  }
+  // </Map>
+  // </public>
+
+  // <private>
+  private Integer getKeyIndex(
+    Object key
+    )
+  {
+    for(
+      int index = 0,
+        length = operands.size() - 1;
+      index < length;
+      index += 2
+      )
+    {
+      if(operands.get(index).equals(key))
+        return index;
+    }
+    return null;
+  }
+  // </private>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/LocalGraphicsState.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/LocalGraphicsState.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/LocalGraphicsState.java	(revision 23703)
@@ -0,0 +1,84 @@
+/*
+  Copyright 2007-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+import it.stefanochizzolini.clown.bytes.IOutputStream;
+import it.stefanochizzolini.clown.documents.contents.ContentScanner;
+
+import java.util.List;
+
+/**
+  Local graphics state [PDF:1.6:4.3.1].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.4
+  @version 0.0.8
+*/
+public final class LocalGraphicsState
+  extends ContainerObject
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final String BeginOperator = SaveGraphicsState.Operator;
+  public static final String EndOperator = RestoreGraphicsState.Operator;
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  public LocalGraphicsState(
+    )
+  {super();}
+
+  public LocalGraphicsState(
+    List<ContentObject> objects
+    )
+  {super(objects);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public void applyTo(
+    ContentScanner.GraphicsState state
+    )
+  {/* NOTE: Local graphics state is purposely isolated from surrounding graphics state. */}
+
+  @Override
+  public void writeTo(
+    IOutputStream stream
+    )
+  {
+    stream.write(BeginOperator); stream.write("\n");
+    super.writeTo(stream);
+    stream.write(EndOperator); stream.write("\n");
+  }
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/MarkedContent.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/MarkedContent.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/MarkedContent.java	(revision 23703)
@@ -0,0 +1,91 @@
+/*
+  Copyright 2008-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+import it.stefanochizzolini.clown.bytes.IOutputStream;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+  Marked-content sequence [PDF:1.6:10.5].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.7
+  @version 0.0.8
+*/
+public final class MarkedContent
+  extends ContainerObject
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final String EndOperator = EndMarkedContent.Operator;
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <fields>
+  private BeginMarkedContent beginOperation;
+  // </fields>
+
+  // <constructors>
+  public MarkedContent(
+    BeginMarkedContent beginOperation
+    )
+  {
+    this(
+      beginOperation,
+      new ArrayList<ContentObject>(2)
+      );
+  }
+
+  public MarkedContent(
+    BeginMarkedContent beginOperation,
+    List<ContentObject> objects
+    )
+  {
+    super(objects);
+    this.beginOperation = beginOperation;
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public void writeTo(
+    IOutputStream stream
+    )
+  {
+    beginOperation.writeTo(stream);
+    super.writeTo(stream);
+    stream.write(EndOperator);
+  }
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/ModifyCTM.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/ModifyCTM.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/ModifyCTM.java	(revision 23703)
@@ -0,0 +1,137 @@
+/*
+  Copyright 2007-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+import it.stefanochizzolini.clown.documents.contents.ContentScanner;
+import it.stefanochizzolini.clown.objects.IPdfNumber;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfReal;
+import it.stefanochizzolini.clown.util.math.SquareMatrix;
+
+import java.util.List;
+
+/**
+  'Modify the current transformation matrix (CTM) by concatenating the specified matrix' operation
+  [PDF:1.6:4.3.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.4
+  @version 0.0.8
+*/
+public final class ModifyCTM
+  extends Operation
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final String Operator = "cm";
+  // </fields>
+
+  // <interface>
+  // <public>
+  public static ModifyCTM getResetCTM(
+    double[] ctm
+    )
+  {
+    double[][] inverseMatrixData = new SquareMatrix(
+      new double[][]
+      {
+        {ctm[0],ctm[1],0},
+        {ctm[2],ctm[3],0},
+        {ctm[4],ctm[5],1}
+      }
+      ).getInverse().getData();
+
+    return new ModifyCTM(
+      inverseMatrixData[0][0],
+      inverseMatrixData[0][1],
+      inverseMatrixData[1][0],
+      inverseMatrixData[1][1],
+      inverseMatrixData[2][0],
+      inverseMatrixData[2][1]
+      );
+  }
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  public ModifyCTM(
+    double a,
+    double b,
+    double c,
+    double d,
+    double e,
+    double f
+    )
+  {
+    super(
+      Operator,
+      new PdfReal(a),
+      new PdfReal(b),
+      new PdfReal(c),
+      new PdfReal(d),
+      new PdfReal(e),
+      new PdfReal(f)
+      );
+  }
+
+  public ModifyCTM(
+    List<PdfDirectObject> operands
+    )
+  {super(Operator,operands);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public void applyTo(
+    ContentScanner.GraphicsState state
+    )
+  {
+    state.ctm = ContentScanner.GraphicsState.concat(
+      getValue(),
+      state.ctm
+      );
+  }
+
+  public double[] getValue(
+    )
+  {
+    return new double[]
+      {
+        ((IPdfNumber)operands.get(0)).getNumberValue(), // a.
+        ((IPdfNumber)operands.get(1)).getNumberValue(), // b.
+        ((IPdfNumber)operands.get(2)).getNumberValue(), // c.
+        ((IPdfNumber)operands.get(3)).getNumberValue(), // d.
+        ((IPdfNumber)operands.get(4)).getNumberValue(), // e.
+        ((IPdfNumber)operands.get(5)).getNumberValue() // f.
+      };
+  }
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/ModifyClipPath.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/ModifyClipPath.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/ModifyClipPath.java	(revision 23703)
@@ -0,0 +1,57 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+/**
+  'Modify the current clipping path by intersecting it with the current path,
+  using the nonzero winding number rule to determine which regions lie inside
+  the clipping path' operation [PDF:1.6:4.4.2].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.7
+  @version 0.0.7
+*/
+public final class ModifyClipPath
+  extends Operation
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final ModifyClipPath Value = new ModifyClipPath();
+
+  public static final String Operator = "W";
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  private ModifyClipPath(
+    )
+  {super(Operator);}
+  // </constructors>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/ModifyClipPathEvenOdd.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/ModifyClipPathEvenOdd.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/ModifyClipPathEvenOdd.java	(revision 23703)
@@ -0,0 +1,57 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+/**
+  'Modify the current clipping path by intersecting it with the current path,
+  using the even-odd rule to determine which regions lie inside the clipping path'
+  operation [PDF:1.6:4.4.2].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.7
+  @version 0.0.7
+*/
+public final class ModifyClipPathEvenOdd
+  extends Operation
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final ModifyClipPathEvenOdd Value = new ModifyClipPathEvenOdd();
+
+  public static final String Operator = "W*";
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  private ModifyClipPathEvenOdd(
+    )
+  {super(Operator);}
+  // </constructors>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/Operation.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/Operation.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/Operation.java	(revision 23703)
@@ -0,0 +1,264 @@
+/*
+  Copyright 2006-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+import it.stefanochizzolini.clown.bytes.IOutputStream;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+  Content stream instruction [PDF:1.6:3.7.1].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.2
+  @version 0.0.8
+*/
+public abstract class Operation
+  extends ContentObject
+{
+  // <class>
+  // <static>
+  // <interface>
+  // <public>
+  /**
+    Gets a specific operation.
+
+    @param operator Operator.
+    @param operands List of operands.
+    @return Operation associated to the operator.
+    @since 0.0.4
+  */
+  public static Operation get(
+    String operator,
+    List<PdfDirectObject> operands
+    )
+  {
+    /*
+      NOTE: This is a factory method for any operation-derived object.
+    */
+    if(operator == null)
+      return null;
+
+    if(operator.equals(SaveGraphicsState.Operator))
+      return SaveGraphicsState.Value;
+    else if(operator.equals(SetFont.Operator))
+      return new SetFont(operands);
+    else if(operator.equals(SetStrokeColor.Operator))
+      return new SetStrokeColor(operands);
+    else if(operator.equals(SetStrokeColorSpace.Operator))
+      return new SetStrokeColorSpace(operands);
+    else if(operator.equals(SetFillColor.Operator))
+      return new SetFillColor(operands);
+    else if(operator.equals(SetFillColorSpace.Operator))
+      return new SetFillColorSpace(operands);
+    else if(operator.equals(RestoreGraphicsState.Operator))
+      return RestoreGraphicsState.Value;
+    else if(operator.equals(BeginSubpath.Operator))
+      return new BeginSubpath(operands);
+    else if(operator.equals(CloseSubpath.Operator))
+      return CloseSubpath.Value;
+    else if(operator.equals(CloseStroke.Operator))
+      return CloseStroke.Value;
+    else if(operator.equals(Fill.Operator)
+      || operator.equals(Fill.ObsoleteOperator))
+      return Fill.Value;
+    else if(operator.equals(FillEvenOdd.Operator))
+      return FillEvenOdd.Value;
+    else if(operator.equals(Stroke.Operator))
+      return Stroke.Value;
+    else if(operator.equals(FillStroke.Operator))
+      return FillStroke.Value;
+    else if(operator.equals(FillStrokeEvenOdd.Operator))
+      return FillStrokeEvenOdd.Value;
+    else if(operator.equals(CloseFillStroke.Operator))
+      return CloseFillStroke.Value;
+    else if(operator.equals(CloseFillStrokeEvenOdd.Operator))
+      return CloseFillStrokeEvenOdd.Value;
+    else if(operator.equals(EndPathNoOp.Operator))
+      return EndPathNoOp.Value;
+    else if(operator.equals(ModifyClipPath.Operator))
+      return ModifyClipPath.Value;
+    else if(operator.equals(ModifyClipPathEvenOdd.Operator))
+      return ModifyClipPathEvenOdd.Value;
+    else if(operator.equals(TranslateTextToNextLine.Operator))
+      return TranslateTextToNextLine.Value;
+    else if(operator.equals(ShowSimpleText.Operator))
+      return new ShowSimpleText(operands);
+    else if(operator.equals(ShowTextToNextLine.SimpleOperator)
+      || operator.equals(ShowTextToNextLine.SpaceOperator))
+      return new ShowTextToNextLine(operator,operands);
+    else if(operator.equals(ShowAdjustedText.Operator))
+      return new ShowAdjustedText(operands);
+    else if(operator.equals(TranslateTextRelative.SimpleOperator)
+      || operator.equals(TranslateTextRelative.LeadOperator))
+      return new TranslateTextRelative(operator,operands);
+    else if(operator.equals(SetTextMatrix.Operator))
+      return new SetTextMatrix(operands);
+    else if(operator.equals(ModifyCTM.Operator))
+      return new ModifyCTM(operands);
+    else if(operator.equals(PaintXObject.Operator))
+      return new PaintXObject(operands);
+    else if(operator.equals(PaintShading.Operator))
+      return new PaintShading(operands);
+    else if(operator.equals(SetCharSpace.Operator))
+      return new SetCharSpace(operands);
+    else if(operator.equals(SetLineCap.Operator))
+      return new SetLineCap(operands);
+    else if(operator.equals(SetLineDash.Operator))
+      return new SetLineDash(operands);
+    else if(operator.equals(SetLineJoin.Operator))
+      return new SetLineJoin(operands);
+    else if(operator.equals(SetLineWidth.Operator))
+      return new SetLineWidth(operands);
+    else if(operator.equals(SetMiterLimit.Operator))
+      return new SetMiterLimit(operands);
+    else if(operator.equals(SetTextLead.Operator))
+      return new SetTextLead(operands);
+    else if(operator.equals(SetTextRise.Operator))
+      return new SetTextRise(operands);
+    else if(operator.equals(SetTextScale.Operator))
+      return new SetTextScale(operands);
+    else if(operator.equals(SetTextRenderMode.Operator))
+      return new SetTextRenderMode(operands);
+    else if(operator.equals(SetWordSpace.Operator))
+      return new SetWordSpace(operands);
+    else if(operator.equals(DrawLine.Operator))
+      return new DrawLine(operands);
+    else if(operator.equals(DrawRectangle.Operator))
+      return new DrawRectangle(operands);
+    else if(operator.equals(DrawCurve.FinalOperator)
+      || operator.equals(DrawCurve.FullOperator)
+      || operator.equals(DrawCurve.InitialOperator))
+      return new DrawCurve(operator,operands);
+    else if(operator.equals(EndInlineImage.Operator))
+      return EndInlineImage.Value;
+    else if(operator.equals(BeginText.Operator))
+      return BeginText.Value;
+    else if(operator.equals(EndText.Operator))
+      return EndText.Value;
+    else if(operator.equals(BeginMarkedContent.SimpleOperator))
+      return new BeginMarkedContent((PdfName)operands.get(0));
+    else if(operator.equals(BeginMarkedContent.PropertyListOperator))
+      return new BeginMarkedContent((PdfName)operands.get(0),operands.get(1));
+    else if(operator.equals(EndMarkedContent.Operator))
+      return EndMarkedContent.Value;
+    else if(operator.equals(BeginInlineImage.Operator))
+      return BeginInlineImage.Value;
+    else if(operator.equals(EndInlineImage.Operator))
+      return EndInlineImage.Value;
+    else if(operator.equals(SetExtGState.Operator))
+      return new SetExtGState(operands);
+    else // No explicit operation implementation available.
+      return new GenericOperation(operator,operands);
+  }
+  // </public>
+  // </interface>
+  // </static>
+
+  // <dynamic>
+  // <fields>
+  protected String operator;
+  protected List<PdfDirectObject> operands;
+  // </fields>
+
+  // <constructors>
+  protected Operation(
+    String operator
+    )
+  {this.operator = operator;}
+
+  protected Operation(
+    String operator,
+    PdfDirectObject operand
+    )
+  {
+    this.operator = operator;
+    this.operands = new ArrayList<PdfDirectObject>(2);
+    this.operands.add(operand);
+  }
+
+  protected Operation(
+    String operator,
+    PdfDirectObject... operands
+    )
+  {
+    this.operator = operator;
+    this.operands = new ArrayList<PdfDirectObject>(2);
+    for(PdfDirectObject operand : operands)
+    {this.operands.add(operand);}
+  }
+
+  protected Operation(
+    String operator,
+    List<PdfDirectObject> operands
+    )
+  {
+    this.operator = operator;
+    this.operands = operands;
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  public String getOperator(
+    )
+  {return operator;}
+
+  public List<PdfDirectObject> getOperands(
+    )
+  {return operands;}
+
+  @Override
+  public String toString(
+    )
+  {
+    return "{"
+      + operator + " "
+      + (operands == null ? "" : operands.toString())
+      + "}";
+  }
+
+  @Override
+  public void writeTo(
+    IOutputStream stream
+    )
+  {
+    if(operands != null)
+    {
+      for(PdfDirectObject operand : operands)
+      {operand.writeTo(stream); stream.write(" ");}
+    }
+    stream.write(operator); stream.write("\n");
+  }
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/PaintPath.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/PaintPath.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/PaintPath.java	(revision 23703)
@@ -0,0 +1,48 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+/**
+  Path-painting operation [PDF:1.6:4.4.2].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.7
+  @version 0.0.7
+*/
+public class PaintPath
+  extends Operation
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  protected PaintPath(
+    String operator
+    )
+  {super(operator);}
+  // </constructors>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/PaintShading.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/PaintShading.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/PaintShading.java	(revision 23703)
@@ -0,0 +1,64 @@
+/*
+  Copyright 2007-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+
+import java.util.List;
+
+/**
+  'Paint the shape and color shading' operation [PDF:1.6:4.6.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.4
+  @version 0.0.8
+*/
+public final class PaintShading
+  extends Operation
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final String Operator = "sh";
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  public PaintShading(
+    PdfName name
+    )
+  {super(Operator,name);}
+
+  public PaintShading(
+    List<PdfDirectObject> operands
+    )
+  {super(Operator,operands);}
+  // </constructors>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/PaintXObject.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/PaintXObject.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/PaintXObject.java	(revision 23703)
@@ -0,0 +1,83 @@
+/*
+  Copyright 2007-2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+
+import java.util.List;
+
+/**
+  'Paint the specified XObject' operation [PDF:1.6:4.7].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.4
+  @version 0.0.7
+*/
+public final class PaintXObject
+  extends Operation
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final String Operator = "Do";
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  public PaintXObject(
+    PdfName name
+    )
+  {super(Operator,name);}
+
+  public PaintXObject(
+    List<PdfDirectObject> operands
+    )
+  {super(Operator,operands);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  /**
+    Gets the name of the XObject resource to be painted.
+  */
+  public PdfName getName(
+    )
+  {return (PdfName)operands.get(0);}
+
+  /**
+    @see #getName()
+  */
+  public void setName(
+    PdfName value
+    )
+  {operands.set(0,value);}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/Path.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/Path.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/Path.java	(revision 23703)
@@ -0,0 +1,77 @@
+/*
+  Copyright 2008-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+import java.util.List;
+
+/**
+  Path object [PDF:1.6:4.4].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.7
+  @version 0.0.8
+*/
+public final class Path
+  extends GraphicsObject
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final String[] BeginOperators = new String[]
+    {
+      BeginSubpath.Operator,
+      DrawRectangle.Operator
+    };
+  public static final String[] EndOperators = new String[]
+    {
+      Stroke.Operator,
+      CloseStroke.Operator,
+      Fill.Operator,
+      Fill.ObsoleteOperator,
+      FillEvenOdd.Operator,
+      FillStroke.Operator,
+      FillStrokeEvenOdd.Operator,
+      CloseFillStroke.Operator,
+      CloseFillStrokeEvenOdd.Operator,
+      EndPathNoOp.Operator
+    };
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  public Path(
+    )
+  {}
+
+  public Path(
+    List<ContentObject> operations
+    )
+  {super(operations);}
+  // </constructors>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/RestoreGraphicsState.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/RestoreGraphicsState.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/RestoreGraphicsState.java	(revision 23703)
@@ -0,0 +1,56 @@
+/*
+  Copyright 2007 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+/**
+  'Restore the graphics state by removing the most recently saved state from the stack and making it
+  the current state' operation [PDF:1.6:4.3.3]. Practically, it ends the current local graphics state.
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.4
+  @version 0.0.4
+*/
+public final class RestoreGraphicsState
+  extends Operation
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final RestoreGraphicsState Value = new RestoreGraphicsState();
+
+  public static final String Operator = "Q";
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  private RestoreGraphicsState(
+    )
+  {super(Operator);}
+  // </constructors>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SaveGraphicsState.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SaveGraphicsState.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SaveGraphicsState.java	(revision 23703)
@@ -0,0 +1,55 @@
+/*
+  Copyright 2007 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+/**
+  'Save the current graphics state on the graphics state stack' operation [PDF:1.6:4.3.3]. Practically, it begins a local graphics state.
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.4
+  @version 0.0.4
+*/
+public final class SaveGraphicsState
+  extends Operation
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final SaveGraphicsState Value = new SaveGraphicsState();
+
+  public static final String Operator = "q";
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  private SaveGraphicsState(
+    )
+  {super(Operator);}
+  // </constructors>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SetCharSpace.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SetCharSpace.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SetCharSpace.java	(revision 23703)
@@ -0,0 +1,93 @@
+/*
+  Copyright 2007-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+import it.stefanochizzolini.clown.documents.contents.ContentScanner;
+import it.stefanochizzolini.clown.objects.IPdfNumber;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfReal;
+
+import java.util.List;
+
+/**
+  'Set the character spacing' operation [PDF:1.6:5.2].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.4
+  @version 0.0.8
+*/
+public final class SetCharSpace
+  extends Operation
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final String Operator = "Tc";
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  public SetCharSpace(
+    double value
+    )
+  {
+    super(
+      Operator,
+      new PdfReal(value)
+      );
+  }
+
+  public SetCharSpace(
+    List<PdfDirectObject> operands
+    )
+  {super(Operator,operands);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public void applyTo(
+    ContentScanner.GraphicsState state
+    )
+  {state.charSpace = getValue();}
+
+  public double getValue(
+    )
+  {return ((IPdfNumber)operands.get(0)).getNumberValue();}
+
+  /**
+    @since 0.0.6
+  */
+  public void setValue(
+    double value
+    )
+  {((IPdfNumber)operands.get(0)).setNumberValue(value);}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SetExtGState.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SetExtGState.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SetExtGState.java	(revision 23703)
@@ -0,0 +1,106 @@
+/*
+  Copyright 2009-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+import it.stefanochizzolini.clown.documents.contents.ContentScanner;
+import it.stefanochizzolini.clown.documents.contents.ExtGState;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+
+import java.util.List;
+
+/**
+  'Set the specified graphics state parameters' operation [PDF:1.6:4.3.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.8
+  @version 0.0.8
+*/
+public final class SetExtGState
+  extends Operation
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final String Operator = "gs";
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  public SetExtGState(
+    PdfName name
+    )
+  {super(Operator,name);}
+
+  public SetExtGState(
+    List<PdfDirectObject> operands
+    )
+  {super(Operator,operands);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public void applyTo(
+    ContentScanner.GraphicsState state
+    )
+  {
+    ExtGState extGState = state.getScanner().getContentContext().getResources().getExtGStates().get(getName());
+    for(PdfName parameterName : extGState.getBaseDataObject().keySet())
+    {
+      if(parameterName.equals(PdfName.Font))
+      {
+        state.font = extGState.getFont();
+        state.fontSize = extGState.getFontSize();
+      }
+      else if(parameterName.equals(PdfName.LC))
+      {state.lineCap = extGState.getLineCap();}
+      else if(parameterName.equals(PdfName.D))
+      {state.lineDash = extGState.getLineDash();}
+      else if(parameterName.equals(PdfName.LJ))
+      {state.lineJoin = extGState.getLineJoin();}
+      else if(parameterName.equals(PdfName.LW))
+      {state.lineWidth = extGState.getLineWidth();}
+      else if(parameterName.equals(PdfName.ML))
+      {state.miterLimit = extGState.getMiterLimit();}
+      //TODO:extend supported parameters!!!
+    }
+  }
+
+  public PdfName getName(
+    )
+  {return (PdfName)operands.get(0);}
+
+  public void setName(
+    PdfName value
+    )
+  {operands.set(0,value);}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SetFillColor.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SetFillColor.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SetFillColor.java	(revision 23703)
@@ -0,0 +1,105 @@
+/*
+  Copyright 2007-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+import it.stefanochizzolini.clown.documents.contents.ContentScanner;
+import it.stefanochizzolini.clown.documents.contents.colorSpaces.Color;
+import it.stefanochizzolini.clown.objects.IPdfNumber;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfReal;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+  'Set the color to use for nonstroking operations in a device, CIE-based (other than ICCBased),
+  or Indexed color space' operation [PDF:1.6:4.5.7].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.4
+  @version 0.0.8
+*/
+public final class SetFillColor
+  extends Operation
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final String Operator = "sc";
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  public SetFillColor(
+    Color value
+    )
+  {
+    super(
+      Operator,
+      new ArrayList<PdfDirectObject>()
+      );
+    for(double component : value.getComponents())
+    {operands.add(new PdfReal(component));}
+  }
+
+  public SetFillColor(
+    List<PdfDirectObject> operands
+    )
+  {super(Operator,operands);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public void applyTo(
+    ContentScanner.GraphicsState state
+    )
+  {
+    state.fillColor = state.fillColorSpace.getColor(
+      operands.toArray(new PdfDirectObject[0])
+      );
+  }
+
+  public double[] getComponents(
+    )
+  {
+    double[] components = new double[operands.size()];
+    for(
+      int index = 0,
+        length = components.length;
+      index < length;
+      index++
+      )
+    {components[index] = ((IPdfNumber)operands.get(index)).getNumberValue();}
+
+    return components;
+  }
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SetFillColorSpace.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SetFillColorSpace.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SetFillColorSpace.java	(revision 23703)
@@ -0,0 +1,117 @@
+/*
+  Copyright 2007-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+import it.stefanochizzolini.clown.documents.contents.ContentScanner;
+import it.stefanochizzolini.clown.documents.contents.colorSpaces.DeviceCMYKColorSpace;
+import it.stefanochizzolini.clown.documents.contents.colorSpaces.DeviceGrayColorSpace;
+import it.stefanochizzolini.clown.documents.contents.colorSpaces.DeviceRGBColorSpace;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+
+import java.util.List;
+
+/**
+  'Set the current color space to use for nonstroking operations' operation [PDF:1.6:4.5.7].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.4
+  @version 0.0.8
+*/
+public final class SetFillColorSpace
+  extends Operation
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final String Operator = "cs";
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  public SetFillColorSpace(
+    PdfName name
+    )
+  {super(Operator,name);}
+
+  public SetFillColorSpace(
+    List<PdfDirectObject> operands
+    )
+  {super(Operator,operands);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public void applyTo(
+    ContentScanner.GraphicsState state
+    )
+  {
+    /*
+      NOTE: The names DeviceGray, DeviceRGB, DeviceCMYK, and Pattern always identify
+      the corresponding color spaces directly; they never refer to resources in the
+      ColorSpace subdictionary [PDF:1.6:4.5.7].
+    */
+    PdfName name = getName();
+    if(name.equals(PdfName.DeviceGray))
+    {state.fillColorSpace = DeviceGrayColorSpace.Default;}
+    else if(name.equals(PdfName.DeviceRGB))
+    {state.fillColorSpace = DeviceRGBColorSpace.Default;}
+    else if(name.equals(PdfName.DeviceCMYK))
+    {state.fillColorSpace = DeviceCMYKColorSpace.Default;}
+//TODO:special color spaces[PDF:1.6:4.5.5]!!!
+//       else if(name.equals(PdfName.Pattern))
+//       {state.fillColorSpace = Pattern.Default;}
+    else
+    {state.fillColorSpace = state.getScanner().getContentContext().getResources().getColorSpaces().get(name);}
+//TODO:eliminate when full support to color spaces!!!
+if(state.fillColorSpace != null)
+{
+    /*
+      NOTE: The operation also sets the current nonstroking color
+      to its initial value, which depends on the color space [PDF:1.6:4.5.7].
+    */
+    state.fillColor = state.fillColorSpace.getDefaultColor();
+}
+  }
+
+  public PdfName getName(
+    )
+  {return (PdfName)operands.get(0);}
+
+  /**
+    @since 0.0.6
+  */
+  public void setName(
+    PdfName value
+    )
+  {operands.set(0,value);}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SetFont.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SetFont.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SetFont.java	(revision 23703)
@@ -0,0 +1,112 @@
+/*
+  Copyright 2007-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+import it.stefanochizzolini.clown.documents.contents.ContentScanner;
+import it.stefanochizzolini.clown.objects.IPdfNumber;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfReal;
+
+import java.util.List;
+
+/**
+  'Set the text font' operation [PDF:1.6:5.2].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.4
+  @version 0.0.8
+*/
+public final class SetFont
+  extends Operation
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final String Operator = "Tf";
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  public SetFont(
+    PdfName name,
+    double size
+    )
+  {
+    super(
+      Operator,
+      name,
+      new PdfReal(size)
+      );
+  }
+
+  public SetFont(
+    List<PdfDirectObject> operands
+    )
+  {super(Operator,operands);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public void applyTo(
+    ContentScanner.GraphicsState state
+    )
+  {
+	  //TODO: fix the fonts...
+    //state.font = state.getScanner().getContentContext().getResources().getFonts().get(getName());
+    state.fontSize = getSize();
+  }
+
+  public PdfName getName(
+    )
+  {return (PdfName)operands.get(0);}
+
+  public double getSize(
+    )
+  {return ((IPdfNumber)operands.get(1)).getNumberValue();}
+
+  /**
+    @since 0.0.6
+  */
+  public void setName(
+    PdfName value
+    )
+  {operands.set(0,value);}
+
+  /**
+    @since 0.0.6
+  */
+  public void setSize(
+    double value
+    )
+  {((IPdfNumber)operands.get(1)).setNumberValue(value);}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SetLineCap.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SetLineCap.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SetLineCap.java	(revision 23703)
@@ -0,0 +1,98 @@
+/*
+  Copyright 2007-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+import it.stefanochizzolini.clown.documents.contents.ContentScanner;
+import it.stefanochizzolini.clown.documents.contents.LineCapEnum;
+import it.stefanochizzolini.clown.objects.IPdfNumber;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfInteger;
+
+import java.util.List;
+
+/**
+  'Set the line cap style' operation [PDF:1.6:4.3.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.4
+  @version 0.0.8
+*/
+public final class SetLineCap
+  extends Operation
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final String Operator = "J";
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  public SetLineCap(
+    LineCapEnum value
+    )
+  {
+    super(
+      Operator,
+      new PdfInteger(value.getCode())
+      );
+  }
+
+  public SetLineCap(
+    List<PdfDirectObject> operands
+    )
+  {super(Operator,operands);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public void applyTo(
+    ContentScanner.GraphicsState state
+    )
+  {state.lineCap = getValue();}
+
+  public LineCapEnum getValue(
+    )
+  {
+    return LineCapEnum.valueOf(
+      (int)((IPdfNumber)operands.get(0)).getNumberValue()
+      );
+  }
+
+  /**
+    @since 0.0.6
+  */
+  public void setValue(
+    LineCapEnum value
+    )
+  {((IPdfNumber)operands.get(0)).setNumberValue(value.getCode());}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SetLineDash.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SetLineDash.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SetLineDash.java	(revision 23703)
@@ -0,0 +1,131 @@
+/*
+  Copyright 2007-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+import it.stefanochizzolini.clown.documents.contents.ContentScanner;
+import it.stefanochizzolini.clown.documents.contents.LineDash;
+import it.stefanochizzolini.clown.objects.IPdfNumber;
+import it.stefanochizzolini.clown.objects.PdfArray;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfReal;
+
+import java.util.List;
+
+/**
+  'Set the line dash pattern' operation [PDF:1.6:4.3.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.4
+  @version 0.0.8
+*/
+public final class SetLineDash
+  extends Operation
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final String Operator = "d";
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  public SetLineDash(
+    double phase,
+    double unitsOn,
+    double unitsOff
+    )
+  {
+    super(
+      Operator,
+      new PdfArray(
+        new PdfReal(unitsOn),
+        new PdfReal(unitsOff)
+        ),
+      new PdfReal(phase)
+      );
+  }
+
+  public SetLineDash(
+    List<PdfDirectObject> operands
+    )
+  {super(Operator,operands);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public void applyTo(
+    ContentScanner.GraphicsState state
+    )
+  {state.lineDash = getValue();}
+
+  public LineDash getValue(
+    )
+  {
+    // 1. Dash array.
+    PdfArray baseDashArray = (PdfArray)operands.get(0);
+    double[] dashArray = new double[baseDashArray.size()];
+    for(
+      int index = 0,
+        length = dashArray.length;
+      index < length;
+      index++
+      )
+    {dashArray[index] = ((IPdfNumber)baseDashArray.get(index)).getNumberValue();}
+    // 2. Dash phase.
+    double dashPhase = ((IPdfNumber)operands.get(1)).getNumberValue();
+
+    return new LineDash(dashArray,dashPhase);
+  }
+
+  /**
+    @since 0.0.6
+  */
+  public void setValue(
+    LineDash value
+    )
+  {
+    // 1. Dash array.
+    double[] dashArray = value.getDashArray();
+    PdfArray baseDashArray = new PdfArray(dashArray.length);
+    for(
+      int index = 0,
+        length = dashArray.length;
+      index < length;
+      index++
+      )
+    {baseDashArray.set(index,new PdfReal(dashArray[index]));}
+    operands.set(0,baseDashArray);
+
+    // 2. Dash phase.
+    ((IPdfNumber)operands.get(1)).setNumberValue(value.getDashPhase());
+  }
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SetLineJoin.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SetLineJoin.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SetLineJoin.java	(revision 23703)
@@ -0,0 +1,98 @@
+/*
+  Copyright 2007-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+import it.stefanochizzolini.clown.documents.contents.ContentScanner;
+import it.stefanochizzolini.clown.documents.contents.LineJoinEnum;
+import it.stefanochizzolini.clown.objects.IPdfNumber;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfInteger;
+
+import java.util.List;
+
+/**
+  'Set the line join style' operation [PDF:1.6:4.3.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.4
+  @version 0.0.8
+*/
+public final class SetLineJoin
+  extends Operation
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final String Operator = "j";
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  public SetLineJoin(
+    LineJoinEnum value
+    )
+  {
+    super(
+      Operator,
+      new PdfInteger(value.getCode())
+      );
+  }
+
+  public SetLineJoin(
+    List<PdfDirectObject> operands
+    )
+  {super(Operator,operands);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public void applyTo(
+    ContentScanner.GraphicsState state
+    )
+  {state.lineJoin = getValue();}
+
+  public LineJoinEnum getValue(
+    )
+  {
+    return LineJoinEnum.valueOf(
+      (int)((IPdfNumber)operands.get(0)).getNumberValue()
+      );
+  }
+
+  /**
+    @since 0.0.6
+  */
+  public void setValue(
+    LineJoinEnum value
+    )
+  {((IPdfNumber)operands.get(0)).setNumberValue(value.getCode());}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SetLineWidth.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SetLineWidth.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SetLineWidth.java	(revision 23703)
@@ -0,0 +1,93 @@
+/*
+  Copyright 2007-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+import it.stefanochizzolini.clown.documents.contents.ContentScanner;
+import it.stefanochizzolini.clown.objects.IPdfNumber;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfReal;
+
+import java.util.List;
+
+/**
+  'Set the line width' operation [PDF:1.6:4.3.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.4
+  @version 0.0.8
+*/
+public final class SetLineWidth
+  extends Operation
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final String Operator = "w";
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  public SetLineWidth(
+    double value
+    )
+  {
+    super(
+      Operator,
+      new PdfReal(value)
+      );
+  }
+
+  public SetLineWidth(
+    List<PdfDirectObject> operands
+    )
+  {super(Operator,operands);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public void applyTo(
+    ContentScanner.GraphicsState state
+    )
+  {state.lineWidth = getValue();}
+
+  public double getValue(
+    )
+  {return ((IPdfNumber)operands.get(0)).getNumberValue();}
+
+  /**
+    @since 0.0.6
+  */
+  public void setValue(
+    double value
+    )
+  {((IPdfNumber)operands.get(0)).setNumberValue(value);}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SetMiterLimit.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SetMiterLimit.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SetMiterLimit.java	(revision 23703)
@@ -0,0 +1,93 @@
+/*
+  Copyright 2007-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+import it.stefanochizzolini.clown.documents.contents.ContentScanner;
+import it.stefanochizzolini.clown.objects.IPdfNumber;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfReal;
+
+import java.util.List;
+
+/**
+  'Set the miter limit' operation [PDF:1.6:4.3.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.4
+  @version 0.0.8
+*/
+public final class SetMiterLimit
+  extends Operation
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final String Operator = "M";
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  public SetMiterLimit(
+    double value
+    )
+  {
+    super(
+      Operator,
+      new PdfReal(value)
+      );
+  }
+
+  public SetMiterLimit(
+    List<PdfDirectObject> operands
+    )
+  {super(Operator,operands);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public void applyTo(
+    ContentScanner.GraphicsState state
+    )
+  {state.miterLimit = getValue();}
+
+  public double getValue(
+    )
+  {return ((IPdfNumber)operands.get(0)).getNumberValue();}
+
+  /**
+    @since 0.0.6
+  */
+  public void setValue(
+    double value
+    )
+  {((IPdfNumber)operands.get(0)).setNumberValue(value);}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SetStrokeColor.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SetStrokeColor.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SetStrokeColor.java	(revision 23703)
@@ -0,0 +1,105 @@
+/*
+  Copyright 2007-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+import it.stefanochizzolini.clown.documents.contents.ContentScanner;
+import it.stefanochizzolini.clown.documents.contents.colorSpaces.Color;
+import it.stefanochizzolini.clown.objects.IPdfNumber;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfReal;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+  'Set the color to use for stroking operations in a device, CIE-based (other than ICCBased),
+  or Indexed color space' operation [PDF:1.6:4.5.7].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.4
+  @version 0.0.8
+*/
+public final class SetStrokeColor
+  extends Operation
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final String Operator = "SC";
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  public SetStrokeColor(
+    Color value
+    )
+  {
+    super(
+      Operator,
+      new ArrayList<PdfDirectObject>()
+      );
+    for(double component : value.getComponents())
+    {operands.add(new PdfReal(component));}
+  }
+
+  public SetStrokeColor(
+    List<PdfDirectObject> operands
+    )
+  {super(Operator,operands);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public void applyTo(
+    ContentScanner.GraphicsState state
+    )
+  {
+    state.strokeColor = state.strokeColorSpace.getColor(
+      operands.toArray(new PdfDirectObject[0])
+      );
+  }
+
+  public double[] getComponents(
+    )
+  {
+    double[] components = new double[operands.size()];
+    for(
+      int index = 0,
+        length = components.length;
+      index < length;
+      index++
+      )
+    {components[index] = ((IPdfNumber)operands.get(index)).getNumberValue();}
+
+    return components;
+  }
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SetStrokeColorSpace.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SetStrokeColorSpace.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SetStrokeColorSpace.java	(revision 23703)
@@ -0,0 +1,117 @@
+/*
+  Copyright 2007-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+import it.stefanochizzolini.clown.documents.contents.ContentScanner;
+import it.stefanochizzolini.clown.documents.contents.colorSpaces.DeviceCMYKColorSpace;
+import it.stefanochizzolini.clown.documents.contents.colorSpaces.DeviceGrayColorSpace;
+import it.stefanochizzolini.clown.documents.contents.colorSpaces.DeviceRGBColorSpace;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+
+import java.util.List;
+
+/**
+  'Set the current color space to use for stroking operations' operation [PDF:1.6:4.5.7].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.4
+  @version 0.0.8
+*/
+public final class SetStrokeColorSpace
+  extends Operation
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final String Operator = "CS";
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  public SetStrokeColorSpace(
+    PdfName name
+    )
+  {super(Operator,name);}
+
+  public SetStrokeColorSpace(
+    List<PdfDirectObject> operands
+    )
+  {super(Operator,operands);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public void applyTo(
+    ContentScanner.GraphicsState state
+    )
+  {
+    /*
+      NOTE: The names DeviceGray, DeviceRGB, DeviceCMYK, and Pattern always identify
+      the corresponding color spaces directly; they never refer to resources in the
+      ColorSpace subdictionary [PDF:1.6:4.5.7].
+    */
+    PdfName name = getName();
+    if(name.equals(PdfName.DeviceGray))
+    {state.strokeColorSpace = DeviceGrayColorSpace.Default;}
+    else if(name.equals(PdfName.DeviceRGB))
+    {state.strokeColorSpace = DeviceRGBColorSpace.Default;}
+    else if(name.equals(PdfName.DeviceCMYK))
+    {state.strokeColorSpace = DeviceCMYKColorSpace.Default;}
+//TODO:special color spaces[PDF:1.6:4.5.5]!!!
+//       else if(name.equals(PdfName.Pattern))
+//       {state.strokeColorSpace = Pattern.Default;}
+    else
+    {state.strokeColorSpace = state.getScanner().getContentContext().getResources().getColorSpaces().get(name);}
+//TODO:eliminate when full support to color spaces!!!
+if(state.strokeColorSpace != null)
+{
+          /*
+            NOTE: The operation also sets the current stroking color
+            to its initial value, which depends on the color space [PDF:1.6:4.5.7].
+          */
+          state.strokeColor = state.strokeColorSpace.getDefaultColor();
+}
+  }
+
+  public PdfName getName(
+    )
+  {return (PdfName)operands.get(0);}
+
+  /**
+    @since 0.0.6
+  */
+  public void setName(
+    PdfName value
+    )
+  {operands.set(0,value);}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SetTextLead.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SetTextLead.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SetTextLead.java	(revision 23703)
@@ -0,0 +1,96 @@
+/*
+  Copyright 2007-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+import it.stefanochizzolini.clown.documents.contents.ContentScanner;
+import it.stefanochizzolini.clown.objects.IPdfNumber;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfReal;
+
+import java.util.List;
+
+/**
+  'Set the text leading' operation [PDF:1.6:5.2].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.4
+  @version 0.0.8
+*/
+public final class SetTextLead
+  extends Operation
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final String Operator = "TL";
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  public SetTextLead(
+    double value
+    )
+  {
+    super(
+      Operator,
+      new PdfReal(value)
+      );
+  }
+
+  public SetTextLead(
+    List<PdfDirectObject> operands
+    )
+  {super(Operator,operands);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public void applyTo(
+    ContentScanner.GraphicsState state
+    )
+  {state.lead = getValue();}
+
+  /**
+    Gets the text leading, which is a number expressed in unscaled text space units.
+  */
+  public double getValue(
+    )
+  {return ((IPdfNumber)operands.get(0)).getNumberValue();}
+
+  /**
+    @since 0.0.6
+  */
+  public void setValue(
+    double value
+    )
+  {((IPdfNumber)operands.get(0)).setNumberValue(value);}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SetTextMatrix.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SetTextMatrix.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SetTextMatrix.java	(revision 23703)
@@ -0,0 +1,111 @@
+/*
+  Copyright 2007-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+import it.stefanochizzolini.clown.documents.contents.ContentScanner;
+import it.stefanochizzolini.clown.objects.IPdfNumber;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfReal;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+  'Set the text matrix' operation [PDF:1.6:5.3.1].
+  <h3>Remarks</h3>
+  <p>The specified matrix is not concatenated onto the current text matrix, but replaces it.</p>
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.4
+  @version 0.0.8
+*/
+public final class SetTextMatrix
+  extends Operation
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final String Operator = "Tm";
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  public SetTextMatrix(
+    double a,
+    double b,
+    double c,
+    double d,
+    double e,
+    double f
+    )
+  {
+    super(
+      Operator,
+      new PdfReal(a),
+      new PdfReal(b),
+      new PdfReal(c),
+      new PdfReal(d),
+      new PdfReal(e),
+      new PdfReal(f)
+      );
+  }
+
+  public SetTextMatrix(
+    List<PdfDirectObject> operands
+    )
+  {super(Operator,operands);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public void applyTo(
+    ContentScanner.GraphicsState state
+    )
+  {
+    state.tm = getValue();
+    state.tlm = Arrays.copyOf(state.tm,state.tm.length);
+  }
+
+  public double[] getValue(
+    )
+  {
+    return new double[]
+      {
+        ((IPdfNumber)operands.get(0)).getNumberValue(), // a.
+        ((IPdfNumber)operands.get(1)).getNumberValue(), // b.
+        ((IPdfNumber)operands.get(2)).getNumberValue(), // c.
+        ((IPdfNumber)operands.get(3)).getNumberValue(), // d.
+        ((IPdfNumber)operands.get(4)).getNumberValue(), // e.
+        ((IPdfNumber)operands.get(5)).getNumberValue() // f.
+      };
+  }
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SetTextRenderMode.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SetTextRenderMode.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SetTextRenderMode.java	(revision 23703)
@@ -0,0 +1,98 @@
+/*
+  Copyright 2007-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+import it.stefanochizzolini.clown.documents.contents.ContentScanner;
+import it.stefanochizzolini.clown.documents.contents.TextRenderModeEnum;
+import it.stefanochizzolini.clown.objects.IPdfNumber;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfInteger;
+
+import java.util.List;
+
+/**
+  'Set the text rendering mode' operation [PDF:1.6:5.2].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.4
+  @version 0.0.8
+*/
+public final class SetTextRenderMode
+  extends Operation
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final String Operator = "Tr";
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  public SetTextRenderMode(
+    TextRenderModeEnum value
+    )
+  {
+    super(
+      Operator,
+      new PdfInteger(value.getCode())
+      );
+  }
+
+  public SetTextRenderMode(
+    List<PdfDirectObject> operands
+    )
+  {super(Operator,operands);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public void applyTo(
+    ContentScanner.GraphicsState state
+    )
+  {state.renderMode = getValue();}
+
+  public TextRenderModeEnum getValue(
+    )
+  {
+    return TextRenderModeEnum.valueOf(
+      (int)((IPdfNumber)operands.get(0)).getNumberValue()
+      );
+  }
+
+  /**
+    @since 0.0.6
+  */
+  public void setValue(
+    TextRenderModeEnum value
+    )
+  {((IPdfNumber)operands.get(0)).setNumberValue(value.getCode());}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SetTextRise.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SetTextRise.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SetTextRise.java	(revision 23703)
@@ -0,0 +1,96 @@
+/*
+  Copyright 2007-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+import it.stefanochizzolini.clown.documents.contents.ContentScanner;
+import it.stefanochizzolini.clown.objects.IPdfNumber;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfReal;
+
+import java.util.List;
+
+/**
+  'Set the text rise' operation [PDF:1.6:5.2].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.4
+  @version 0.0.8
+*/
+public final class SetTextRise
+  extends Operation
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final String Operator = "Ts";
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  public SetTextRise(
+    double value
+    )
+  {
+    super(
+      Operator,
+      new PdfReal(value)
+      );
+  }
+
+  public SetTextRise(
+    List<PdfDirectObject> operands
+    )
+  {super(Operator,operands);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public void applyTo(
+    ContentScanner.GraphicsState state
+    )
+  {state.rise = getValue();}
+
+  /**
+    Gets the text rise, which is a number expressed in unscaled text space units.
+  */
+  public double getValue(
+    )
+  {return ((IPdfNumber)operands.get(0)).getNumberValue();}
+
+  /**
+    @since 0.0.6
+  */
+  public void setValue(
+    double value
+    )
+  {((IPdfNumber)operands.get(0)).setNumberValue(value);}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SetTextScale.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SetTextScale.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SetTextScale.java	(revision 23703)
@@ -0,0 +1,96 @@
+/*
+  Copyright 2007-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+import it.stefanochizzolini.clown.documents.contents.ContentScanner;
+import it.stefanochizzolini.clown.objects.IPdfNumber;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfReal;
+
+import java.util.List;
+
+/**
+  'Set the horizontal scaling' operation [PDF:1.6:5.2].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.4
+  @version 0.0.8
+*/
+public final class SetTextScale
+  extends Operation
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final String Operator = "Tz";
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  public SetTextScale(
+    double value
+    )
+  {
+    super(
+      Operator,
+      new PdfReal(value)
+      );
+  }
+
+  public SetTextScale(
+    List<PdfDirectObject> operands
+    )
+  {super(Operator,operands);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public void applyTo(
+    ContentScanner.GraphicsState state
+    )
+  {state.scale = getValue();}
+
+  /**
+    Gets the horizontal scale expressed as a percentage of the normal width (100).
+  */
+  public double getValue(
+    )
+  {return ((IPdfNumber)operands.get(0)).getNumberValue();}
+
+  /**
+    @since 0.0.6
+  */
+  public void setValue(
+    double value
+    )
+  {((IPdfNumber)operands.get(0)).setNumberValue(value);}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SetWordSpace.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SetWordSpace.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/SetWordSpace.java	(revision 23703)
@@ -0,0 +1,93 @@
+/*
+  Copyright 2007-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+import it.stefanochizzolini.clown.documents.contents.ContentScanner;
+import it.stefanochizzolini.clown.objects.IPdfNumber;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfReal;
+
+import java.util.List;
+
+/**
+  'Set the word spacing' operation [PDF:1.6:5.2].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.4
+  @version 0.0.8
+*/
+public final class SetWordSpace
+  extends Operation
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final String Operator = "Tw";
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  public SetWordSpace(
+    double value
+    )
+  {
+    super(
+      Operator,
+      new PdfReal(value)
+      );
+  }
+
+  public SetWordSpace(
+    List<PdfDirectObject> operands
+    )
+  {super(Operator,operands);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public void applyTo(
+    ContentScanner.GraphicsState state
+    )
+  {state.wordSpace = getValue();}
+
+  public double getValue(
+    )
+  {return ((IPdfNumber)operands.get(0)).getNumberValue();}
+
+  /**
+    @since 0.0.6
+  */
+  public void setValue(
+    double value
+    )
+  {((IPdfNumber)operands.get(0)).setNumberValue(value);}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/Shading.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/Shading.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/Shading.java	(revision 23703)
@@ -0,0 +1,56 @@
+/*
+  Copyright 2007-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+
+/**
+  Shading object [PDF:1.6:4.6.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.4
+  @version 0.0.8
+*/
+public final class Shading
+  extends GraphicsObject
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final String BeginOperator = PaintShading.Operator;
+  public static final String EndOperator = BeginOperator;
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  public Shading(
+    PaintShading operation
+    )
+  {super(operation);}
+  // </constructors>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/ShowAdjustedText.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/ShowAdjustedText.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/ShowAdjustedText.java	(revision 23703)
@@ -0,0 +1,143 @@
+/*
+  Copyright 2009 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+import it.stefanochizzolini.clown.objects.PdfArray;
+import it.stefanochizzolini.clown.objects.PdfAtomicObject;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfReal;
+import it.stefanochizzolini.clown.objects.PdfString;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+  'Show one or more text strings, allowing individual glyph positioning' operation [PDF:1.6:5.3.2].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.8
+  @version 0.0.8
+*/
+public final class ShowAdjustedText
+  extends ShowText
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final String Operator = "TJ";
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  /**
+    @param value Each element can be either a byte array (encoded text) or a number.
+      If the element is a byte array (encoded text), this operator shows the text glyphs.
+      If it is a number (glyph adjustment), the operator adjusts the next glyph position by that amount.
+  */
+  public ShowAdjustedText(
+    List<Object> value,
+    int reserved
+    )
+  {
+    super(Operator);
+    setValue(value);
+  }
+
+  public ShowAdjustedText(
+    List<PdfDirectObject> operands
+    )
+  {super(Operator,operands);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public byte[] getText(
+    )
+  {
+    ByteArrayOutputStream textStream = new ByteArrayOutputStream();
+    for(PdfDirectObject element : ((PdfArray)operands.get(0)))
+    {
+      if(element instanceof PdfString)
+      {
+        try
+        {textStream.write(((PdfString)element).getRawValue());}
+        catch(IOException exception)
+        {throw new RuntimeException(exception);}
+      }
+    }
+    return textStream.toByteArray();
+  }
+
+  @Override
+  public List<Object> getValue(
+    )
+  {
+    List<Object> value = new ArrayList<Object>();
+    for(PdfDirectObject element : ((PdfArray)operands.get(0)))
+    {
+      value.add(
+        ((PdfAtomicObject<?>)element).getRawValue()
+        );
+    }
+    return value;
+  }
+
+  @Override
+  public void setText(
+    byte[] value
+    )
+  {setValue(Arrays.asList((Object)value));}
+
+  @Override
+  public void setValue(
+    List<Object> value
+    )
+  {
+    PdfArray elements = new PdfArray();
+    operands.set(0,elements);
+    boolean textItemExpected = true;
+    for(Object valueItem : value)
+    {
+      PdfDirectObject element;
+      if(textItemExpected)
+      {element = new PdfString((byte[])valueItem);}
+      else
+      {element = new PdfReal((Double)valueItem);}
+      elements.add(element);
+
+      textItemExpected = !textItemExpected;
+    }
+  }
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/ShowSimpleText.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/ShowSimpleText.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/ShowSimpleText.java	(revision 23703)
@@ -0,0 +1,87 @@
+/*
+  Copyright 2009-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfString;
+
+import java.util.List;
+
+/**
+  'Show a text string' operation [PDF:1.6:5.3.2].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.8
+  @version 0.0.8
+*/
+public final class ShowSimpleText
+  extends ShowText
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final String Operator = "Tj";
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  /**
+    @param text Text encoded using current font's encoding.
+  */
+  public ShowSimpleText(
+    byte[] text
+    )
+  {
+    super(
+      Operator,
+      new PdfString(text)
+      );
+  }
+
+  public ShowSimpleText(
+    List<PdfDirectObject> operands
+    )
+  {super(Operator,operands);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public byte[] getText(
+    )
+  {return ((PdfString)operands.get(0)).getRawValue();}
+
+  @Override
+  public void setText(
+    byte[] value
+    )
+  {((PdfString)operands.get(0)).setRawValue(value);}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/ShowText.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/ShowText.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/ShowText.java	(revision 23703)
@@ -0,0 +1,275 @@
+/*
+  Copyright 2007-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+import it.stefanochizzolini.clown.documents.contents.ContentScanner;
+import it.stefanochizzolini.clown.documents.contents.IContentContext;
+import it.stefanochizzolini.clown.documents.contents.fonts.Font;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+
+import java.awt.geom.Rectangle2D;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+  Abstract 'show a text string' operation [PDF:1.6:5.3.2].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.8
+  @version 0.0.8
+*/
+public abstract class ShowText
+  extends Operation
+{
+  // <class>
+  // <interfaces>
+  public interface IScanner
+  {
+    /**
+      Notifies the scanner about the font.
+
+      @param fontSize Scaled font size.
+    */
+    void scanFont(
+      double fontSize
+      );
+
+    /**
+      Notifies the scanner about a text character.
+
+      @param textChar Scanned character.
+      @param textCharBox Bounding box of the scanned character.
+    */
+    void scanChar(
+      char textChar,
+      Rectangle2D textCharBox
+      );
+  }
+  // </interfaces>
+
+  // <dynamic>
+  // <constructors>
+  protected ShowText(
+    String operator
+    )
+  {super(operator);}
+
+  protected ShowText(
+    String operator,
+    PdfDirectObject... operands
+    )
+  {super(operator,operands);}
+
+  protected ShowText(
+    String operator,
+    List<PdfDirectObject> operands
+    )
+  {super(operator,operands);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public void applyTo(
+    ContentScanner.GraphicsState state
+    )
+  {
+	  //TODO: fix this
+	  //scan(state,null);
+	  }
+
+  /**
+    Gets the encoded text.
+    <h3>Remarks</h3>
+    <p>Text is expressed in native encoding: to resolve it to Unicode, pass it
+    to the decode method of the corresponding font.</p>
+  */
+  public abstract byte[] getText(
+    );
+
+  /**
+    Gets the encoded text elements along with their adjustments.
+    <h3>Remarks</h3>
+    <p>Text is expressed in native encoding: to resolve it to Unicode, pass it
+    to the decode method of the corresponding font.</p>
+
+    @return Each element can be either a byte array or a number:
+      if it's a byte array (encoded text), the operator shows text glyphs;
+      if it's a number (glyph adjustment), the operator inversely adjusts the next glyph position by that amount
+      (that is: a positive value reduces the distance between consecutive glyphs).
+  */
+  public List<Object> getValue(
+    )
+  {return Arrays.asList((Object)getText());}
+
+  /**
+    Executes scanning on this operation.
+
+    @param state Graphics state context.
+    @param textScanner Scanner to be notified about text contents.
+      In case it's null, the operation is applied to the graphics state context.
+  */
+  public void scan(
+    ContentScanner.GraphicsState state,
+    IScanner textScanner
+    )
+  {
+    /*
+      TODO: I really dislike this solution -- it's a temporary hack until the event-driven
+      parsing mechanism is implemented...
+     */
+    /*
+      TODO: support to vertical writing mode.
+    */
+
+    IContentContext context = state.getScanner().getContentContext();
+    double contextHeight = context.getBox().getHeight();
+    Font font = state.font;
+    double fontSize = state.fontSize;
+    double scale = state.scale / 100;
+    double scaledFactor = Font.getScalingFactor(fontSize) * scale;
+    double wordSpace = state.wordSpace * scale;
+    double charSpace = state.charSpace * scale;
+    double[] tm = state.tm;
+    double[] ctm = state.ctm;
+    boolean fontScanned = false;
+    if(this instanceof ShowTextToNextLine)
+    {
+      ShowTextToNextLine showTextToNextLine = (ShowTextToNextLine)this;
+      Double newWordSpace = showTextToNextLine.getWordSpace();
+      if(newWordSpace != null)
+      {
+        if(textScanner == null)
+        {state.wordSpace = newWordSpace;}
+        wordSpace = newWordSpace * scale;
+      }
+      Double newCharSpace = showTextToNextLine.getCharSpace();
+      if(newCharSpace != null)
+      {
+        if(textScanner == null)
+        {state.charSpace = newCharSpace;}
+        charSpace = newCharSpace * scale;
+      }
+      tm = ContentScanner.GraphicsState.concat(
+        new double[]{1,0,0,1,0,state.lead},
+        state.tlm
+        );
+    }
+    List<Object> textElements = getValue();
+    for(Object textElement : textElements)
+    {
+      if(textElement instanceof byte[]) // Text string.
+      {
+        String textString = font.decode((byte[])textElement);
+        for(char textChar : textString.toCharArray())
+        {
+          /*
+            NOTE: The text rendering matrix is recomputed before each glyph is painted
+            during a text-showing operation.
+          */
+          double[] trm = ContentScanner.GraphicsState.concat(tm,ctm);
+
+          double charWidth = font.getWidth(textChar) * scaledFactor;
+          double charHeight = font.getHeight(textChar,fontSize);
+
+          if(textScanner != null)
+          {
+            if(!fontScanned)
+            {
+              fontScanned = true;
+              textScanner.scanFont(fontSize * tm[3]);
+            }
+
+	          double scaledCharWidth = charWidth * tm[0];
+	          double scaledCharHeight = charHeight * tm[3];
+            Rectangle2D charBox = new Rectangle2D.Double(
+              trm[4],
+              contextHeight - trm[5] - font.getAscent(fontSize) * tm[3],
+              scaledCharWidth,
+              scaledCharHeight
+              );
+            textScanner.scanChar(textChar,charBox);
+          }
+
+          /*
+            NOTE: After the glyph is painted, the text matrix is updated
+            according to the glyph displacement and any applicable spacing parameter.
+          */
+          tm = ContentScanner.GraphicsState.concat(
+            new double[]
+            {
+              1,0,0,1,
+              charWidth
+	              + charSpace
+	              + (textChar == ' ' ? wordSpace : 0),
+              0
+            },
+            tm
+            );
+        }
+      }
+      else // Text position adjustment.
+      {
+        tm = ContentScanner.GraphicsState.concat(
+          new double[]
+          {
+            1,0,0,1,
+            -((Number)textElement).doubleValue() * scaledFactor,
+            0
+          },
+          tm
+          );
+      }
+    }
+
+    if(textScanner == null)
+    {
+      state.tm = tm;
+
+      if(this instanceof ShowTextToNextLine)
+      {state.tlm = Arrays.copyOf(state.tm,state.tm.length);}
+    }
+  }
+
+  /**
+    @see #getText()
+  */
+  public abstract void setText(
+    byte[] value
+    );
+
+  /**
+    @see #getValue()
+  */
+  public void setValue(
+    List<Object> value
+    )
+  {setText((byte[])value.get(0));}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/ShowTextToNextLine.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/ShowTextToNextLine.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/ShowTextToNextLine.java	(revision 23703)
@@ -0,0 +1,187 @@
+/*
+  Copyright 2009-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+import it.stefanochizzolini.clown.objects.IPdfNumber;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfReal;
+import it.stefanochizzolini.clown.objects.PdfString;
+
+import java.util.List;
+
+/**
+  'Move to the next line and show a text string' operation [PDF:1.6:5.3.2].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.8
+  @version 0.0.8
+*/
+public final class ShowTextToNextLine
+  extends ShowText
+{
+  // <class>
+  // <static>
+  // <fields>
+  /**
+    Specifies no text state parameter
+    (just uses the current settings).
+  */
+  public static final String SimpleOperator = "'";
+  /**
+    Specifies the word spacing and the character spacing
+    (setting the corresponding parameters in the text state).
+  */
+  public static final String SpaceOperator = "''";
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  /**
+    @param text Text encoded using current font's encoding.
+  */
+  public ShowTextToNextLine(
+    byte[] text
+    )
+  {
+    super(
+      SimpleOperator,
+      new PdfString(text)
+      );
+  }
+
+  /**
+    @param text Text encoded using current font's encoding.
+    @param wordSpace Word spacing.
+    @param charSpace Character spacing.
+  */
+  public ShowTextToNextLine(
+    byte[] text,
+    double wordSpace,
+    double charSpace
+    )
+  {
+    super(
+      SpaceOperator,
+      new PdfReal(wordSpace),
+      new PdfReal(charSpace),
+      new PdfString(text)
+      );
+  }
+
+  public ShowTextToNextLine(
+    String operator,
+    List<PdfDirectObject> operands
+    )
+  {super(operator,operands);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  /**
+    Gets the character spacing.
+  */
+  public Double getCharSpace(
+    )
+  {
+    if(operator.equals(SimpleOperator))
+      return null;
+
+    return ((IPdfNumber)operands.get(1)).getNumberValue();
+  }
+
+  @Override
+  public byte[] getText(
+    )
+  {
+    return ((PdfString)operands.get(
+      operator.equals(SimpleOperator) ? 0 : 2
+      )).getRawValue();
+  }
+
+  /**
+    Gets the word spacing.
+  */
+  public Double getWordSpace(
+    )
+  {
+    if(operator.equals(SimpleOperator))
+      return null;
+
+    return ((IPdfNumber)operands.get(0)).getNumberValue();
+  }
+
+  /**
+    @see #getCharSpace()
+  */
+  public void setCharSpace(
+    Double value
+    )
+  {
+    ensureSpaceOperation();
+
+    ((IPdfNumber)operands.get(1)).setNumberValue(value);
+  }
+
+  @Override
+  public void setText(
+    byte[] value
+    )
+  {
+    ((PdfString)operands.get(
+      operator.equals(SimpleOperator) ? 0 : 2
+      )).setRawValue(value);
+  }
+
+  /**
+    @see #getWordSpace()
+  */
+  public void setWordSpace(
+    Double value
+    )
+  {
+    ensureSpaceOperation();
+
+    ((IPdfNumber)operands.get(0)).setNumberValue(value);
+  }
+  // </public>
+
+  // <private>
+  private void ensureSpaceOperation(
+    )
+  {
+    if(operator.equals(SimpleOperator))
+    {
+      operator = SpaceOperator;
+      operands.add(0,new PdfReal(0));
+      operands.add(1,new PdfReal(0));
+    }
+  }
+  // </private>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/Stroke.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/Stroke.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/Stroke.java	(revision 23703)
@@ -0,0 +1,55 @@
+/*
+  Copyright 2007-2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+/**
+  'Stroke the path' operation [PDF:1.6:4.4.2].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.4
+  @version 0.0.7
+*/
+public final class Stroke
+  extends PaintPath
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final Stroke Value = new Stroke();
+
+  public static final String Operator = "S";
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  private Stroke(
+    )
+  {super(Operator);}
+  // </constructors>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/Text.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/Text.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/Text.java	(revision 23703)
@@ -0,0 +1,77 @@
+/*
+  Copyright 2007-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+import it.stefanochizzolini.clown.bytes.IOutputStream;
+
+import java.util.List;
+
+/**
+  Text object [PDF:1.6:5.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.4
+  @version 0.0.8
+*/
+public final class Text
+  extends GraphicsObject
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final String BeginOperator = BeginText.Operator;
+  public static final String EndOperator = EndText.Operator;
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  public Text(
+    )
+  {}
+
+  public Text(
+    List<ContentObject> objects
+    )
+  {super(objects);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public void writeTo(
+    IOutputStream stream
+    )
+  {
+    stream.write(BeginOperator); stream.write("\n");
+    super.writeTo(stream);
+    stream.write(EndOperator); stream.write("\n");
+  }
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/TranslateTextRelative.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/TranslateTextRelative.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/TranslateTextRelative.java	(revision 23703)
@@ -0,0 +1,150 @@
+/*
+  Copyright 2007-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+import it.stefanochizzolini.clown.documents.contents.ContentScanner;
+import it.stefanochizzolini.clown.objects.IPdfNumber;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfReal;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+  'Move to the start of the next line, offset from the start of the current line' operation
+  [PDF:1.6:5.2].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.4
+  @version 0.0.8
+*/
+public final class TranslateTextRelative
+  extends Operation
+{
+  // <class>
+  // <static>
+  // <fields>
+  /**
+    No side effect.
+  */
+  public static final String SimpleOperator = "Td";
+  /**
+    Lead parameter setting.
+  */
+  public static final String LeadOperator = "TD";
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  public TranslateTextRelative(
+    double offsetX,
+    double offsetY
+    )
+  {this(offsetX,offsetY,false);}
+
+  public TranslateTextRelative(
+    double offsetX,
+    double offsetY,
+    boolean leadSet
+    )
+  {
+    super(
+      leadSet ? LeadOperator : SimpleOperator,
+      new PdfReal(offsetX),
+      new PdfReal(offsetY)
+      );
+  }
+
+  public TranslateTextRelative(
+    String operator,
+    List<PdfDirectObject> operands
+    )
+  {super(operator,operands);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public void applyTo(
+    ContentScanner.GraphicsState state
+    )
+  {
+    state.tm = ContentScanner.GraphicsState.concat(
+      new double[]{1,0,0,1,getOffsetX(),getOffsetY()},
+      state.tlm
+      );
+    state.tlm = Arrays.copyOf(state.tm,state.tm.length);
+    if(isLeadSet())
+    {state.lead = getOffsetY();}
+  }
+
+  public double getOffsetX(
+    )
+  {return ((IPdfNumber)operands.get(0)).getNumberValue();}
+
+  public double getOffsetY(
+    )
+  {return ((IPdfNumber)operands.get(1)).getNumberValue();}
+
+  /**
+    Gets whether this operation, as a side effect, sets the leading parameter in the text state.
+
+    @since 0.0.8
+  */
+  public boolean isLeadSet(
+    )
+  {return operator.equals(LeadOperator);}
+
+  /**
+    @see #isLeadSet()
+    @since 0.0.8
+  */
+  public void setLeadSet(
+    boolean value
+    )
+  {operator = (value ? LeadOperator : SimpleOperator);}
+
+  /**
+    @since 0.0.6
+  */
+  public void setOffsetX(
+    double value
+    )
+  {((IPdfNumber)operands.get(0)).setNumberValue(value);}
+
+  /**
+    @since 0.0.6
+  */
+  public void setOffsetY(
+    double value
+    )
+  {((IPdfNumber)operands.get(1)).setNumberValue(value);}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/TranslateTextToNextLine.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/TranslateTextToNextLine.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/TranslateTextToNextLine.java	(revision 23703)
@@ -0,0 +1,75 @@
+/*
+  Copyright 2007-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+import it.stefanochizzolini.clown.documents.contents.ContentScanner;
+
+import java.util.Arrays;
+
+/**
+  'Move to the start of the next line' operation [PDF:1.6:5.3.1].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.4
+  @version 0.0.8
+*/
+public final class TranslateTextToNextLine
+  extends Operation
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final TranslateTextToNextLine Value = new TranslateTextToNextLine();
+
+  public static final String Operator = "T*";
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  private TranslateTextToNextLine(
+    )
+  {super(Operator);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public void applyTo(
+    ContentScanner.GraphicsState state
+    )
+  {
+    state.tm = ContentScanner.GraphicsState.concat(
+      new double[]{1,0,0,1,0,state.lead},
+      state.tlm
+      );
+    state.tlm = Arrays.copyOf(state.tm,state.tm.length);
+  }
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/XObject.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/XObject.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/XObject.java	(revision 23703)
@@ -0,0 +1,71 @@
+/*
+  Copyright 2007-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.objects;
+
+import it.stefanochizzolini.clown.objects.PdfName;
+
+/**
+  External object [PDF:1.6:4.7].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.4
+  @version 0.0.8
+*/
+public final class XObject
+  extends GraphicsObject
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final String BeginOperator = PaintXObject.Operator;
+  public static final String EndOperator = BeginOperator;
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <fields>
+  // </fields>
+
+  // <constructors>
+  public XObject(
+    PaintXObject operation
+    )
+  {super(operation);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  /**
+    Gets the name of the XObject resource.
+  */
+  public PdfName getName(
+    )
+  {return ((PaintXObject)getObjects().get(0)).getName();}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/package.html
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/package.html	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/objects/package.html	(revision 23703)
@@ -0,0 +1,37 @@
+<html>
+<head>
+<!--
+  Copyright 2006-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+-->
+</head>
+<body>
+<p>Content stream instructions [PDF:1.6:3.7.1].</p>
+
+<h2>Related Documentation</h2>
+<p>For overviews, tutorials, examples, guides, and tool documentation, please see:</p>
+<ul>
+  <li><a href="http://clown.stefanochizzolini.it">PDF Clown Home Page</a>
+</ul>
+</body>
+</html>
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/package.html
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/package.html	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/package.html	(revision 23703)
@@ -0,0 +1,37 @@
+<html>
+<head>
+<!--
+  Copyright 2006-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+-->
+</head>
+<body>
+<p>Types used to define the graphical appearance of PDF contents [PDF:1.6:3.7].</p>
+
+<h2>Related Documentation</h2>
+<p>For overviews, tutorials, examples, guides, and tool documentation, please see:</p>
+<ul>
+  <li><a href="http://clown.stefanochizzolini.it">PDF Clown Home Page</a>
+</ul>
+</body>
+</html>
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/tokens/Parser.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/tokens/Parser.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/tokens/Parser.java	(revision 23703)
@@ -0,0 +1,1025 @@
+/*
+  Copyright 2006-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+    * Haakan Aakerberg (bugfix contributor):
+      - [FIX:0.0.4:4]
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.tokens;
+
+import it.stefanochizzolini.clown.bytes.Buffer;
+import it.stefanochizzolini.clown.bytes.IInputStream;
+import it.stefanochizzolini.clown.documents.contents.objects.BeginInlineImage;
+import it.stefanochizzolini.clown.documents.contents.objects.BeginMarkedContent;
+import it.stefanochizzolini.clown.documents.contents.objects.BeginSubpath;
+import it.stefanochizzolini.clown.documents.contents.objects.BeginText;
+import it.stefanochizzolini.clown.documents.contents.objects.ContentObject;
+import it.stefanochizzolini.clown.documents.contents.objects.DrawRectangle;
+import it.stefanochizzolini.clown.documents.contents.objects.EndInlineImage;
+import it.stefanochizzolini.clown.documents.contents.objects.EndMarkedContent;
+import it.stefanochizzolini.clown.documents.contents.objects.EndText;
+import it.stefanochizzolini.clown.documents.contents.objects.InlineImage;
+import it.stefanochizzolini.clown.documents.contents.objects.InlineImageBody;
+import it.stefanochizzolini.clown.documents.contents.objects.InlineImageHeader;
+import it.stefanochizzolini.clown.documents.contents.objects.LocalGraphicsState;
+import it.stefanochizzolini.clown.documents.contents.objects.MarkedContent;
+import it.stefanochizzolini.clown.documents.contents.objects.Operation;
+import it.stefanochizzolini.clown.documents.contents.objects.PaintPath;
+import it.stefanochizzolini.clown.documents.contents.objects.PaintShading;
+import it.stefanochizzolini.clown.documents.contents.objects.PaintXObject;
+import it.stefanochizzolini.clown.documents.contents.objects.Path;
+import it.stefanochizzolini.clown.documents.contents.objects.RestoreGraphicsState;
+import it.stefanochizzolini.clown.documents.contents.objects.SaveGraphicsState;
+import it.stefanochizzolini.clown.documents.contents.objects.Shading;
+import it.stefanochizzolini.clown.documents.contents.objects.Text;
+import it.stefanochizzolini.clown.documents.contents.objects.XObject;
+import it.stefanochizzolini.clown.objects.PdfArray;
+import it.stefanochizzolini.clown.objects.PdfBoolean;
+import it.stefanochizzolini.clown.objects.PdfDataObject;
+import it.stefanochizzolini.clown.objects.PdfDate;
+import it.stefanochizzolini.clown.objects.PdfDictionary;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfInteger;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfReal;
+import it.stefanochizzolini.clown.objects.PdfReference;
+import it.stefanochizzolini.clown.objects.PdfStream;
+import it.stefanochizzolini.clown.objects.PdfString;
+import it.stefanochizzolini.clown.tokens.FileFormatException;
+import it.stefanochizzolini.clown.tokens.TokenTypeEnum;
+
+import java.io.EOFException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+  Content stream parser [PDF:1.6:3.7.1].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8.2
+*/
+public class Parser
+{
+/*
+TODO:IMPL this parser evaluates a subset of the lexical domain of the token parser (clown.tokens.Parser): it should be better to derive both parsers from a common parsing engine in order to avoid unwieldy duplications.
+*/
+  // <class>
+  // <static>
+  // <interface>
+  // <protected>
+  protected static int getHex(
+    int c
+    )
+  {
+    if(c >= '0' && c <= '9')
+      return (c - '0');
+    else if(c >= 'A' && c <= 'F')
+      return (c - 'A' + 10);
+    else if(c >= 'a' && c <= 'f')
+      return (c - 'a' + 10);
+    else
+      return -1;
+  }
+
+  /**
+    Evaluates whether a character is a delimiter [PDF:1.6:3.1.1].
+  */
+  protected static boolean isDelimiter(
+    int c
+    )
+  {return (c == '(' || c == ')' || c == '<' || c == '>' || c == '[' || c == ']' || c == '/' || c == '%');}
+
+  /**
+    Evaluates whether a character is an EOL marker [PDF:1.6:3.1.1].
+  */
+  protected static boolean isEOL(
+    int c
+    )
+  {return c == 10 || c == 13;}
+
+  /**
+    Evaluates whether a character is a white-space [PDF:1.6:3.1.1].
+  */
+  protected static boolean isWhitespace(
+    int c
+    )
+  {return c == 32 || isEOL(c) || c == 0 || c == 9 || c == 12;}
+  // </protected>
+  // </interface>
+  // </static>
+
+  // <dynamic>
+  // <fields>
+  private final PdfDataObject contentStream;
+
+  private long basePosition;
+  private IInputStream stream;
+  private int streamIndex = -1;
+  private Object token;
+  private TokenTypeEnum tokenType;
+  // </fields>
+
+  // <constructors>
+  /**
+    For internal use only.
+  */
+  public Parser(
+    PdfDataObject contentStream
+    )
+  {
+    this.contentStream = contentStream;
+
+    moveNextStream();
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  /**
+    Gets the content stream on which parsing is done.
+    <h3>Remarks</h3>
+    <p>A content stream may be made up of either a single stream or an array of streams.</p>
+  */
+  public PdfDataObject getContentStream(
+    )
+  {return contentStream;}
+
+  public long getLength(
+    )
+  {
+    if(contentStream instanceof PdfStream) // Single stream.
+      return ((PdfStream)contentStream).getBody().getLength();
+    else // Array of streams.
+    {
+      int length = 0;
+      for(PdfDirectObject stream : (PdfArray)contentStream)
+      {length += ((PdfStream)((PdfReference)stream).getDataObject()).getBody().getLength();}
+      return length;
+    }
+  }
+
+  public long getPosition(
+    )
+  {return basePosition + stream.getPosition();}
+
+  /**
+    Gets the current stream.
+  */
+  public IInputStream getStream(
+    )
+  {return stream;}
+
+  /**
+    Gets the current stream index.
+  */
+  public int getStreamIndex(
+    )
+  {return streamIndex;}
+
+  /**
+    Gets the currently-parsed token.
+    @return The current token.
+  */
+  public Object getToken(
+    )
+  {return token;}
+
+  /**
+    Gets the currently-parsed token type.
+    @return The current token type.
+  */
+  public TokenTypeEnum getTokenType(
+    )
+  {return tokenType;}
+
+  /**
+    @param offset Number of tokens to be skipped before reaching the intended one.
+  */
+  public boolean moveNext(
+    int offset
+    ) throws FileFormatException
+  {
+    for(
+      int index = 0;
+      index < offset;
+      index++
+      )
+    {
+      if(!moveNext())
+        return false;
+    }
+
+    return true;
+  }
+
+  /**
+    Parse the next token [PDF:1.6:3.1].
+    <h3>Contract</h3>
+    <ul>
+     <li>Preconditions:
+      <ol>
+       <li>To properly parse the current token, the pointer MUST be just before its starting (leading whitespaces are ignored).</li>
+      </ol>
+     </li>
+     <li>Postconditions:
+      <ol>
+       <li id="moveNext_contract_post[0]">When this method terminates, the pointer IS at the last byte of the current token.</li>
+      </ol>
+     </li>
+     <li>Invariants:
+      <ol>
+       <li>The byte-level position of the pointer IS anytime (during token parsing) at the end of the current token (whereas the 'current token' represents the token-level position of the pointer).</li>
+      </ol>
+     </li>
+     <li>Side-effects:
+      <ol>
+       <li>See <a href="#moveNext_contract_post[0]">Postconditions</a>.</li>
+      </ol>
+     </li>
+    </ul>
+    @return Whether a new token was found.
+  */
+  public boolean moveNext(
+    ) throws FileFormatException
+  {
+    /*
+      NOTE: It'd be interesting to evaluate an alternative regular-expression-based
+      implementation...
+    */
+    int c = 0;
+
+    // Skip leading white-space characters [PDF:1.6:3.1.1].
+    while(true)
+    {
+      try
+      {
+        do
+        {
+          c = stream.readUnsignedByte();
+        } while(isWhitespace(c)); // Keep goin' till there's a white-space character...
+        break;
+      }
+      catch(EOFException e)
+      {
+        /* NOTE: Current stream has finished. */
+        // Move to the next stream!
+        moveNextStream();
+      }
+      catch(Exception e)
+      {
+        // No more streams?
+        if(stream == null)
+          return false;
+      }
+    }
+
+    StringBuilder buffer = null;
+    token = null;
+    // Which character is it?
+    switch(c)
+    {
+      case '/': // Name.
+        tokenType = TokenTypeEnum.Name;
+
+        buffer = new StringBuilder();
+        try
+        {
+          while(true)
+          {
+            c = stream.readUnsignedByte();
+            if(isDelimiter(c) || isWhitespace(c))
+              break;
+            // Is it an hexadecimal code [PDF:1.6:3.2.4]?
+            if(c == '#')
+            {
+              try
+              {c = (getHex(stream.readUnsignedByte()) << 4) + getHex(stream.readUnsignedByte());}
+              catch(EOFException e)
+              {throw new FileFormatException("Unexpected EOF (malformed hexadecimal code in name object).",e,stream.getPosition());}
+            }
+
+            buffer.append((char)c);
+          }
+        }
+        catch(EOFException e)
+        {/* NOOP */}
+
+        stream.skip(-1); // Recover the first byte after the current token.
+        break;
+      case '0':
+      case '1':
+      case '2':
+      case '3':
+      case '4':
+      case '5':
+      case '6':
+      case '7':
+      case '8':
+      case '9':
+      case '.':
+      case '-':
+      case '+': // Number [PDF:1.6:3.2.2] | Indirect reference.
+        switch(c)
+        {
+          case '.': // Decimal point.
+            tokenType = TokenTypeEnum.Real;
+            break;
+          default: // Digit or signum.
+            tokenType = TokenTypeEnum.Integer; // By default (it may be real).
+            break;
+        }
+
+        // Building the number...
+        buffer = new StringBuilder();
+        try
+        {
+          do
+          {
+            buffer.append((char)c);
+            c = stream.readUnsignedByte();
+            if(c == '.')
+              tokenType = TokenTypeEnum.Real;
+            else if(c < '0' || c > '9')
+              break;
+          } while(true);
+        }
+        catch(EOFException e)
+        {/* NOOP */}
+
+        stream.skip(-1); // Recover the first byte after the current token.
+        break;
+      case '[': // Array (begin).
+        tokenType = TokenTypeEnum.ArrayBegin;
+        break;
+      case ']': // Array (end).
+        tokenType = TokenTypeEnum.ArrayEnd;
+        break;
+      case '<': // Dictionary (begin) | Hexadecimal string.
+        try
+        {c = stream.readUnsignedByte();}
+        catch(EOFException e)
+        {throw new FileFormatException("Unexpected EOF (isolated opening angle-bracket character).",e,stream.getPosition());}
+        // Is it a dictionary (2nd angle bracket [PDF:1.6:3.2.6])?
+        if(c == '<')
+        {
+          tokenType = TokenTypeEnum.DictionaryBegin;
+          break;
+        }
+
+        // Hexadecimal string (single angle bracket [PDF:1.6:3.2.3]).
+        tokenType = TokenTypeEnum.Hex;
+
+        // [FIX:0.0.4:4] It skipped after the first hexadecimal character, missing it.
+        buffer = new StringBuilder();
+        try
+        {
+          while(c != '>') // NOT string end.
+          {
+            buffer.append((char)c);
+
+            c = stream.readUnsignedByte();
+          }
+        }
+        catch(EOFException e)
+        {throw new FileFormatException("Unexpected EOF (malformed hex string).",e,stream.getPosition());}
+
+        break;
+      case '>': // Dictionary (end).
+        try
+        {c = stream.readUnsignedByte();}
+        catch(EOFException e)
+        {throw new FileFormatException("Unexpected EOF (malformed dictionary).",e,stream.getPosition());}
+        if(c != '>')
+          throw new FileFormatException("Malformed dictionary.",stream.getPosition());
+
+        tokenType = TokenTypeEnum.DictionaryEnd;
+
+        break;
+      case '(': // Literal string.
+        tokenType = TokenTypeEnum.Literal;
+
+        buffer = new StringBuilder();
+        int level = 0;
+        try
+        {
+          while(true)
+          {
+            c = stream.readUnsignedByte();
+            if(c == '(')
+              level++;
+            else if(c == ')')
+              level--;
+            else if(c == '\\')
+            {
+              boolean lineBreak = false;
+              c = stream.readUnsignedByte();
+              switch(c)
+              {
+                case 'n':
+                  c = '\n';
+                  break;
+                case 'r':
+                  c = '\r';
+                  break;
+                case 't':
+                  c = '\t';
+                  break;
+                case 'b':
+                  c = '\b';
+                  break;
+                case 'f':
+                  c = '\f';
+                  break;
+                case '(':
+                case ')':
+                case '\\':
+                  break;
+                case '\r':
+                  lineBreak = true;
+                  c = stream.readUnsignedByte();
+                  if(c != '\n')
+                    stream.skip(-1);
+                  break;
+                case '\n':
+                  lineBreak = true;
+                  break;
+                default:
+                {
+                  // Is it outside the octal encoding?
+                  if(c < '0' || c > '7')
+                    break;
+
+                  // Octal [PDF:1.6:3.2.3].
+                  int octal = c - '0';
+                  c = stream.readUnsignedByte();
+                  // Octal end?
+                  if(c < '0' || c > '7')
+                  {c = octal; stream.skip(-1); break;}
+                  octal = (octal << 3) + c - '0';
+                  c = stream.readUnsignedByte();
+                  // Octal end?
+                  if(c < '0' || c > '7')
+                  {c = octal; stream.skip(-1); break;}
+                  octal = (octal << 3) + c - '0';
+                  c = octal & 0xff;
+                  break;
+                }
+              }
+              if(lineBreak)
+                continue;
+            }
+            else if(c == '\r')
+            {
+              c = stream.readUnsignedByte();
+              if(c != '\n')
+              {c = '\n'; stream.skip(-1);}
+            }
+            if(level == -1)
+              break;
+
+            buffer.append((char)c);
+          }
+        }
+        catch(EOFException e)
+        {throw new FileFormatException("Unexpected EOF (malformed literal string).",e,stream.getPosition());}
+
+        break;
+      case '%': // Comment [PDF:1.6:3.1.2].
+        tokenType = TokenTypeEnum.Comment;
+        
+        buffer = new StringBuilder();
+        try
+        {
+          while(true)
+          {
+          	c = stream.readUnsignedByte();
+          	if(isEOL(c))
+          		break;
+          	
+          	buffer.append((char)c);
+          }
+        }
+        catch(EOFException e)
+        {/* NOOP */}
+
+        break;
+      default: // Keyword.
+        tokenType = TokenTypeEnum.Keyword;
+
+        buffer = new StringBuilder();
+        try
+        {
+          do
+          {
+            buffer.append((char)c);
+            c = stream.readUnsignedByte();
+          } while(!isDelimiter(c) && !isWhitespace(c));
+        }
+        catch(EOFException e)
+        {/* NOOP */}
+        stream.skip(-1); // Recover the first byte after the current token.
+
+        break;
+    }
+
+    if(buffer != null)
+    {
+      /*
+        Here we prepare the current token state.
+      */
+      // Which token type?
+      switch(tokenType)
+      {
+        case Keyword:
+          token = buffer.toString();
+          // Late recognition.
+          if(((String)token).equals("false")
+            || ((String)token).equals("true")) // Boolean.
+          {
+            tokenType = TokenTypeEnum.Boolean;
+            token = Boolean.parseBoolean((String)token);
+          }
+          else if(((String)token).equals("null")) // Null.
+          {
+            tokenType = TokenTypeEnum.Null;
+            token = null;
+          }
+          break;
+        case Comment:
+        case Hex:
+        case Name:
+          token = buffer.toString();
+          break;
+        case Literal:
+          token = buffer.toString();
+          // Late recognition.
+          if(((String)token).startsWith("D:")) // Date.
+          {
+            tokenType = TokenTypeEnum.Date;
+            token = PdfDate.toDate((String)token);
+          }
+          break;
+        case Integer:
+          token = Integer.parseInt(buffer.toString());
+          break;
+        case Real:
+          token = Float.parseFloat(buffer.toString());
+          break;
+      }
+    }
+
+    return true;
+  }
+
+  /**
+    Parses the next content object [PDF:1.6:4.1], may it be a single operation or a graphics object.
+
+    @since 0.0.4
+  */
+  public ContentObject parseContentObject(
+    ) throws FileFormatException
+  {
+    final Operation operation = parseOperation();
+    if(operation instanceof PaintXObject) // External object.
+      return new XObject((PaintXObject)operation);
+    else if(operation instanceof PaintShading) // Shading.
+      return new Shading((PaintShading)operation);
+    else if(operation instanceof BeginSubpath
+      || operation instanceof DrawRectangle) // Path.
+      return parsePath(operation);
+    else if(operation instanceof BeginText) // Text.
+      return new Text(
+        parseContentObjects()
+        );
+    else if(operation instanceof SaveGraphicsState) // Local graphics state.
+      return new LocalGraphicsState(
+        parseContentObjects()
+        );
+    else if(operation instanceof BeginMarkedContent) // Marked-content sequence.
+      return new MarkedContent(
+        (BeginMarkedContent)operation,
+        parseContentObjects()
+        );
+    else if(operation instanceof BeginInlineImage) // Inline image.
+      return parseInlineImage();
+    else // Single operation.
+      return operation;
+  }
+
+  public List<ContentObject> parseContentObjects(
+    ) throws FileFormatException
+  {
+    final List<ContentObject> contentObjects = new ArrayList<ContentObject>(2);
+    while(moveNext())
+    {
+      ContentObject contentObject = parseContentObject();
+      // Multiple-operation graphics object end?
+      if(contentObject instanceof EndText // Text.
+        || contentObject instanceof RestoreGraphicsState // Local graphics state.
+        || contentObject instanceof EndMarkedContent // End marked-content sequence.
+        || contentObject instanceof EndInlineImage) // Inline image.
+        return contentObjects;
+
+      contentObjects.add(contentObject);
+    }
+    return contentObjects;
+  }
+
+  public Operation parseOperation(
+    ) throws FileFormatException
+  {
+    String operator = null;
+    final List<PdfDirectObject> operands = new ArrayList<PdfDirectObject>(2);
+    // Parsing the operation parts...
+    while(true)
+    {
+      // Did we reach the operator keyword?
+      if(tokenType == TokenTypeEnum.Keyword)
+      {
+        operator = (String)token;
+        break;
+      }
+
+      operands.add(parsePdfObject()); moveNext();
+    }
+
+    return Operation.get(operator,operands);
+  }
+
+  /**
+    Parse the current PDF object [PDF:1.6:3.2].
+    <h3>Contract</h3>
+    <ul>
+     <li>Preconditions:
+      <ol>
+       <li>When this method is invoked, the pointer MUST be at the first
+       token of the requested object.</li>
+      </ol>
+     </li>
+     <li>Postconditions:
+      <ol>
+       <li id="parsePdfObject_contract_post[0]">When this method terminates,
+       the pointer IS at the last token of the requested object.</li>
+      </ol>
+     </li>
+     <li>Invariants:
+      <ol>
+       <li>(none).</li>
+      </ol>
+     </li>
+     <li>Side-effects:
+      <ol>
+       <li>See <a href="#parsePdfObject_contract_post[0]">Postconditions</a>.</li>
+      </ol>
+     </li>
+    </ul>
+  */
+  protected PdfDirectObject parsePdfObject(
+    ) throws FileFormatException
+  {
+  	do
+  	{
+	    switch(tokenType)
+	    {
+	      case Integer:
+	        return new PdfInteger((Integer)token);
+	      case Name:
+	        return new PdfName((String)token,true);
+	      case Literal:
+	        try
+	        {
+	          return new PdfString(
+	            ((String)token).getBytes("ISO-8859-1"),
+	            PdfString.SerializationModeEnum.Literal
+	            );
+	        }
+	        catch(Exception e)
+	        {throw new RuntimeException(e);}
+	      case DictionaryBegin:
+	        {
+	          PdfDictionary dictionary = new PdfDictionary();
+	          // Populate the dictionary.
+	          while(true)
+	          {
+	            // Key.
+	            moveNext();
+	            if(tokenType == TokenTypeEnum.DictionaryEnd)
+	              break;
+	            PdfName key = (PdfName)parsePdfObject();
+	
+	            // Value.
+	            moveNext();
+	            PdfDirectObject value = (PdfDirectObject)parsePdfObject();
+	
+	            // Add the current entry to the dictionary!
+	            dictionary.put(key,value);
+	          }
+	          return dictionary;
+	        }
+	      case ArrayBegin:
+	        {
+	          PdfArray array = new PdfArray();
+	          // Populate the array.
+	          while(true)
+	          {
+	            // Value.
+	            moveNext();
+	            if(tokenType == TokenTypeEnum.ArrayEnd)
+	              break;
+	
+	            // Add the current item to the array!
+	            array.add((PdfDirectObject)parsePdfObject());
+	          }
+	          return array;
+	        }
+	      case Real:
+	        return new PdfReal((Float)token);
+	      case Boolean:
+	        return new PdfBoolean((Boolean)token);
+	      case Date:
+	        return new PdfDate((Date)token);
+	      case Hex:
+	        try
+	        {
+	          return new PdfString(
+	            (String)token,
+	            PdfString.SerializationModeEnum.Hex
+	            );
+	        }
+	        catch(Exception e)
+	        {throw new RuntimeException(e);}
+	      case Null:
+	        return null;
+	      case Comment:
+	      	// NOOP: Comments are simply ignored and skipped.
+	      	break;
+	      default:
+	        throw new RuntimeException("Unknown type: " + tokenType);
+	    }
+  	} while(moveNext());
+
+  	return null;
+  }
+
+  public void seek(
+    long position
+    )
+  {
+    while(true)
+    {
+      if(position < basePosition) //Before current stream.
+      {
+        if(!movePreviousStream())
+          throw new IllegalArgumentException("The 'position' argument is lower than acceptable.");
+      }
+      else if(position > basePosition + stream.getLength()) // After current stream.
+      {
+        if(!moveNextStream())
+          throw new IllegalArgumentException("The 'position' argument is higher than acceptable.");
+      }
+      else // At current stream.
+      {
+        stream.seek(position - basePosition);
+        break;
+      }
+    }
+  }
+
+  public void skip(
+    long offset
+    )
+  {
+    while(true)
+    {
+      long position = stream.getPosition() + offset;
+      if(position < 0) //Before current stream.
+      {
+        offset += stream.getPosition();
+        if(!movePreviousStream())
+          throw new IllegalArgumentException("The 'offset' argument is lower than acceptable.");
+
+        stream.setPosition(stream.getLength());
+      }
+      else if(position > stream.getLength()) // After current stream.
+      {
+        offset -= (stream.getLength() - stream.getPosition());
+        if(!moveNextStream())
+          throw new IllegalArgumentException("The 'offset' argument is higher than acceptable.");
+      }
+      else // At current stream.
+      {
+        stream.skip(position);
+        break;
+      }
+    }
+  }
+
+  /**
+    Moves to the last whitespace after the current position in order to let read
+    the first non-whitespace.
+  */
+  public boolean skipWhitespace(
+    )
+  {
+    int b;
+    try
+    {
+      do
+      {b = stream.readUnsignedByte();} while(isWhitespace(b)); // Keep goin' till there's a white-space character...
+    }
+    catch(EOFException e)
+    {return false;}
+    stream.skip(-1); // Recover the last whitespace position.
+
+    return true;
+  }
+  // </public>
+
+  // <private>
+  private boolean moveNextStream(
+    )
+  {
+    /* NOTE: A content stream may be made up of multiple streams [PDF:1.6:3.6.2]. */
+    // Is the content stream just a single stream?
+    if(contentStream instanceof PdfStream) // Single stream.
+    {
+      if(streamIndex == 0)
+      {
+        streamIndex++;
+        basePosition += stream.getLength();
+        stream = null;
+      }
+      if(streamIndex == 1)
+        return false;
+
+      streamIndex++;
+      basePosition = 0;
+      stream = ((PdfStream)contentStream).getBody();
+    }
+    else // Array of streams.
+    {
+      PdfArray streams = (PdfArray)contentStream;
+      if(streamIndex == (streams.size() -1))
+      {
+        streamIndex++;
+        basePosition += stream.getLength();
+        stream = null;
+      }
+      if(streamIndex == streams.size())
+        return false;
+
+      streamIndex++;
+      if(streamIndex == 0)
+      {basePosition = 0;}
+      else
+      {basePosition += stream.getLength();}
+      stream = ((PdfStream)((PdfReference)streams.get(streamIndex)).getDataObject()).getBody();
+    }
+    return true;
+  }
+
+  private boolean movePreviousStream(
+    )
+  {
+    if(streamIndex == 0)
+    {
+      streamIndex--;
+      stream = null;
+    }
+    if(streamIndex == -1)
+      return false;
+
+    streamIndex--;
+    /* NOTE: A content stream may be made up of multiple streams [PDF:1.6:3.6.2]. */
+    // Is the content stream just a single stream?
+    if(contentStream instanceof PdfStream) // Single stream.
+    {
+      stream = ((PdfStream)contentStream).getBody();
+      basePosition = 0;
+    }
+    else // Array of streams.
+    {
+      PdfArray streams = (PdfArray)contentStream;
+
+      stream = ((PdfStream)((PdfReference)streams.get(streamIndex)).getDataObject()).getBody();
+      basePosition -= stream.getLength();
+    }
+
+    return true;
+  }
+
+  private InlineImage parseInlineImage(
+    ) throws FileFormatException
+  {
+    /*
+      NOTE: Inline images use a peculiar syntax that's an exception to the usual rule
+      that the data in a content stream is interpreted according to the standard PDF syntax
+      for objects.
+    */
+    InlineImageHeader header;
+    {
+      final List<PdfDirectObject> operands = new ArrayList<PdfDirectObject>(2);
+      // Parsing the image entries...
+      while(moveNext()
+        && tokenType != TokenTypeEnum.Keyword) // Not keyword (i.e. end at image data beginning (ID operator)).
+      {operands.add(parsePdfObject());}
+      header = new InlineImageHeader(operands);
+    }
+
+    InlineImageBody body;
+    {
+      moveNext();
+      Buffer data = new Buffer();
+      byte c1 = 0, c2 = 0;
+      do
+      {
+        try
+        {
+          while(true)
+          {
+            c1 = stream.readByte();
+            c2 = stream.readByte();
+            if(c1 == 'E' && c2 == 'I')
+              break;
+
+            data.append(c1);
+            data.append(c2);
+          } break;
+        }
+        catch(EOFException e)
+        {
+          /* NOTE: Current stream has finished. */
+          // Move to the next stream!
+          moveNextStream();
+        }
+      } while(stream != null);
+      body = new InlineImageBody(data);
+    }
+
+    return new InlineImage(
+      header,
+      body
+      );
+  }
+
+  /**
+    @since 0.0.7
+  */
+  private Path parsePath(
+    Operation beginOperation
+    ) throws FileFormatException
+  {
+    /*
+      NOTE: Paths do not have an explicit end operation, so we must infer it
+      looking for the first non-painting operation.
+    */
+    final List<ContentObject> operations = new ArrayList<ContentObject>(2);
+    {
+      operations.add(beginOperation);
+      long position = getPosition();
+      boolean closeable = false;
+      while(moveNext())
+      {
+        Operation operation = parseOperation();
+        // Multiple-operation graphics object closeable?
+        if(operation instanceof PaintPath) // Painting operation.
+        {closeable = true;}
+        else if(closeable) // Past end (first non-painting operation).
+        {
+          seek(position); // Rolls back to the last path-related operation.
+          break;
+        }
+
+        operations.add(operation);
+        position = getPosition();
+      }
+    }
+    return new Path(operations);
+  }
+  // </private>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/tokens/package.html
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/tokens/package.html	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/tokens/package.html	(revision 23703)
@@ -0,0 +1,37 @@
+<html>
+<head>
+<!--
+  Copyright 2006-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+-->
+</head>
+<body>
+<p>Content stream serialization [PDF:1.6:3.7.1].</p>
+
+<h2>Related Documentation</h2>
+<p>For overviews, tutorials, examples, guides, and tool documentation, please see:</p>
+<ul>
+  <li><a href="http://clown.stefanochizzolini.it">PDF Clown Home Page</a>
+</ul>
+</body>
+</html>
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/xObjects/FormXObject.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/xObjects/FormXObject.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/xObjects/FormXObject.java	(revision 23703)
@@ -0,0 +1,255 @@
+/*
+  Copyright 2006-2009 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.xObjects;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.contents.Contents;
+import it.stefanochizzolini.clown.documents.contents.IContentContext;
+import it.stefanochizzolini.clown.documents.contents.Resources;
+import it.stefanochizzolini.clown.documents.contents.composition.PrimitiveFilter;
+import it.stefanochizzolini.clown.documents.contents.objects.ContentObject;
+import it.stefanochizzolini.clown.files.File;
+import it.stefanochizzolini.clown.objects.IPdfNumber;
+import it.stefanochizzolini.clown.objects.PdfArray;
+import it.stefanochizzolini.clown.objects.PdfDictionary;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfReference;
+import it.stefanochizzolini.clown.objects.Rectangle;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.awt.Dimension;
+import java.awt.geom.Dimension2D;
+import java.awt.geom.Rectangle2D;
+
+/**
+  Form external object [PDF:1.6:4.9].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+*/
+public class FormXObject
+  extends XObject
+  implements IContentContext
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  /**
+    Creates a new form within the given document context, using default resources.
+  */
+  public FormXObject(
+    Document context
+    )
+  {this(context,null);}
+
+  /**
+    Creates a new form within the given document context, using custom resources.
+
+    @since 0.0.5
+  */
+  public FormXObject(
+    Document context,
+    Resources resources
+    )
+  {
+    super(context);
+
+    PdfDictionary header = getBaseDataObject().getHeader();
+    header.put(PdfName.Subtype,PdfName.Form);
+    header.put(PdfName.BBox,new Rectangle(0,0,0,0).getBaseDataObject());
+
+    // No resources collection?
+    /* NOTE: Resources collection is mandatory. */
+    if(resources == null)
+    {resources = new Resources(context);}
+    header.put(PdfName.Resources,resources.getBaseObject());
+  }
+
+  /**
+    For internal use only.
+  */
+  public FormXObject(
+    PdfDirectObject baseObject
+    )
+  {super(baseObject);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public FormXObject clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    @since 0.0.5
+  */
+  @Override
+  public double[] getMatrix(
+    )
+  {
+    /*
+      NOTE: Form-space-to-user-space matrix is identity [1 0 0 1 0 0] by default,
+      but may be adjusted by setting the Matrix entry in the form dictionary [PDF:1.6:4.9].
+    */
+    PdfArray matrix = (PdfArray)File.resolve(
+      getBaseDataObject().getHeader().get(PdfName.Matrix)
+      );
+    if(matrix == null)
+      return new double[]
+        {
+          1, // a.
+          0, // b.
+          0, // c.
+          1, // d.
+          0, // e.
+          0 // f.
+        };
+
+    return new double[]
+      {
+        ((IPdfNumber)matrix.get(0)).getNumberValue(), // a.
+        ((IPdfNumber)matrix.get(1)).getNumberValue(), // b.
+        ((IPdfNumber)matrix.get(2)).getNumberValue(), // c.
+        ((IPdfNumber)matrix.get(3)).getNumberValue(), // d.
+        ((IPdfNumber)matrix.get(4)).getNumberValue(), // e.
+        ((IPdfNumber)matrix.get(5)).getNumberValue() // f.
+      };
+  }
+
+  /**
+    Gets the form size.
+  */
+  @Override
+  public Dimension2D getSize(
+    )
+  {
+    PdfArray box = (PdfArray)File.resolve(
+      getBaseDataObject().getHeader().get(PdfName.BBox)
+      );
+
+    return new Dimension(
+      (int)((IPdfNumber)box.get(2)).getNumberValue(),
+      (int)((IPdfNumber)box.get(3)).getNumberValue()
+      );
+  }
+
+  /**
+    Sets the resources associated to the form.
+  */
+  public void setResources(
+    Resources value
+    )
+  {
+    getBaseDataObject().getHeader().put(
+      PdfName.Resources,
+      value.getBaseObject()
+      );
+  }
+
+  /**
+    Sets the form size.
+  */
+  @Override
+  public void setSize(
+    Dimension2D value
+    )
+  {
+    PdfDirectObject box = getBaseDataObject().getHeader().get(PdfName.BBox);
+
+    PdfArray boxObject = (PdfArray)File.resolve(box);
+    ((IPdfNumber)boxObject.get(2)).setNumberValue(value.getWidth());
+    ((IPdfNumber)boxObject.get(3)).setNumberValue(value.getHeight());
+
+    File.update(box);
+  }
+
+  // <IContentContext>
+  public Rectangle2D getBox(
+    )
+  {
+    PdfArray box = (PdfArray)File.resolve(
+      getBaseDataObject().getHeader().get(PdfName.BBox) // NOTE: Required [PDF:1.6:4.9.1].
+      );
+
+    return new Rectangle2D.Double(
+      ((IPdfNumber)box.get(0)).getNumberValue(),
+      ((IPdfNumber)box.get(1)).getNumberValue(),
+      ((IPdfNumber)box.get(2)).getNumberValue(),
+      ((IPdfNumber)box.get(3)).getNumberValue()
+      );
+  }
+
+  /**
+    Gets the content stream associated to the form.
+  */
+  public Contents getContents(
+    )
+  {
+    return new Contents(
+      getBaseObject(),
+      ((PdfReference)getBaseObject()).getIndirectObject(),
+      this
+      );
+  }
+
+  /**
+    Gets the resources associated to the form.
+  */
+  public Resources getResources(
+    )
+  {
+    return new Resources(
+      getBaseDataObject().getHeader().get(PdfName.Resources),
+      ((PdfReference)getBaseObject()).getIndirectObject()
+      );
+  }
+
+  // <IContentEntity>
+  /**
+    @since 0.0.6
+  */
+  public ContentObject toInlineObject(
+    PrimitiveFilter context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    @since 0.0.5
+  */
+  public XObject toXObject(
+    Document context
+    )
+  {throw new NotImplementedException();}
+  // </IContentEntity>
+  // </IContentContext>
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/xObjects/ImageXObject.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/xObjects/ImageXObject.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/xObjects/ImageXObject.java	(revision 23703)
@@ -0,0 +1,155 @@
+/*
+  Copyright 2006-2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.xObjects;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.objects.PdfDictionary;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfInteger;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfStream;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.awt.Dimension;
+import java.awt.geom.Dimension2D;
+
+/**
+  Image external object [PDF:1.6:4.8.4].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.6
+*/
+public class ImageXObject
+  extends XObject
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  public ImageXObject(
+    Document context,
+    PdfStream baseDataObject
+    )
+  {
+    /*
+      NOTE: It's caller responsability to adequately populate the stream
+      header and body in order to instantiate a valid object; header entries like
+      'Width', 'Height', 'ColorSpace', 'BitsPerComponent' MUST be defined
+      appropriately.
+    */
+
+    super(
+      context,
+      baseDataObject
+      );
+
+    baseDataObject.getHeader().put(PdfName.Subtype,PdfName.Image);
+  }
+
+  /**
+    For internal use only.
+  */
+  public ImageXObject(
+    PdfDirectObject baseObject
+    )
+  {super(baseObject);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  /**
+    Gets the number of bits per color component.
+  */
+  public int getBitsPerComponent(
+    )
+  {return ((PdfInteger)getBaseDataObject().getHeader().get(PdfName.BitsPerComponent)).getRawValue();}
+
+  @Override
+  public ImageXObject clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    Gets the color space in which samples are specified.
+  */
+  public String getColorSpace(
+    )
+  {return ((PdfName)getBaseDataObject().getHeader().get(PdfName.ColorSpace)).getRawValue();}
+
+  /**
+    @since 0.0.5
+  */
+  @Override
+  public double[] getMatrix(
+    )
+  {
+    Dimension2D size = getSize();
+
+    /*
+      NOTE: Image-space-to-user-space matrix is [1/w 0 0 1/h 0 0],
+      where w and h are the width and height of the image in samples [PDF:1.6:4.8.3].
+    */
+    return new double[]
+      {
+        1 / size.getWidth(), // a.
+        0, // b.
+        0, // c.
+        1 / size.getHeight(), // d.
+        0, // e.
+        0 // f.
+      };
+  }
+
+  /**
+    Gets the size of the image (in samples).
+
+    @since 0.0.5
+  */
+  @Override
+  public Dimension2D getSize(
+    )
+  {
+    PdfDictionary header = getBaseDataObject().getHeader();
+
+    return new Dimension(
+      ((PdfInteger)header.get(PdfName.Width)).getRawValue(),
+      ((PdfInteger)header.get(PdfName.Height)).getRawValue()
+      );
+  }
+
+  /**
+    @since 0.0.5
+  */
+  @Override
+  public void setSize(
+    Dimension2D value
+    )
+  {throw new UnsupportedOperationException();}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/xObjects/XObject.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/xObjects/XObject.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/xObjects/XObject.java	(revision 23703)
@@ -0,0 +1,152 @@
+/*
+  Copyright 2006-2007 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.contents.xObjects;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfObjectWrapper;
+import it.stefanochizzolini.clown.objects.PdfReference;
+import it.stefanochizzolini.clown.objects.PdfStream;
+
+import java.awt.geom.Dimension2D;
+
+/**
+  Abstract external object [PDF:1.6:4.7].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.5
+*/
+public abstract class XObject
+  extends PdfObjectWrapper<PdfStream>
+{
+  // <class>
+  // <static>
+  // <interface>
+  // <public>
+  /**
+    Wraps an external object reference into an external object.
+    @param reference Reference to an external object.
+    @return External object associated to the reference.
+  */
+  public static XObject wrap(
+    PdfReference reference
+    )
+  {
+    /*
+      NOTE: This is a factory method for any xobject-derived object.
+    */
+    if(reference == null)
+      return null;
+
+    PdfName subtype = (PdfName)((PdfStream)reference.getDataObject()).getHeader().get(PdfName.Subtype);
+    if(subtype.equals(PdfName.Form))
+      return new FormXObject(reference);
+    else if(subtype.equals(PdfName.Image))
+      return new ImageXObject(reference);
+    else
+      return null;
+  }
+  // </public>
+  // </interface>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  /**
+    Creates a new external object inside the document.
+  */
+  protected XObject(
+    Document context
+    )
+  {
+    this(
+      context,
+      new PdfStream()
+      );
+  }
+
+  /**
+    Creates a new external object inside the document.
+  */
+  protected XObject(
+    Document context,
+    PdfStream baseDataObject
+    )
+  {
+    super(
+      context.getFile(),
+      baseDataObject
+      );
+
+    baseDataObject.getHeader().put(PdfName.Type,PdfName.XObject);
+  }
+
+  /**
+    Instantiates an existing external object.
+  */
+  protected XObject(
+    PdfDirectObject baseObject
+    )
+  {
+    super(
+      baseObject,
+      null // NO container (baseObject is (by definition) a PDF stream, so it MUST be an indirect object [PDF:1.6:3.2.7]).
+      );
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  /**
+    Gets the mapping from external-object space to user space.
+
+    @since 0.0.5
+  */
+  public abstract double[] getMatrix(
+    );
+
+  /**
+    Gets the external object size.
+
+    @since 0.0.5
+  */
+  public abstract Dimension2D getSize(
+    );
+
+  /**
+    Sets the external object size.
+
+    @since 0.0.5
+  */
+  public abstract void setSize(
+    Dimension2D value
+    );
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/xObjects/package.html
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/xObjects/package.html	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/contents/xObjects/package.html	(revision 23703)
@@ -0,0 +1,37 @@
+<html>
+<head>
+<!--
+  Copyright 2006-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+-->
+</head>
+<body>
+<p>External content objects that are able to be referenced from content stream objects [PDF:1.6:4.7].</p>
+
+<h2>Related Documentation</h2>
+<p>For overviews, tutorials, examples, guides, and tool documentation, please see:</p>
+<ul>
+  <li><a href="http://clown.stefanochizzolini.it">PDF Clown Home Page</a>
+</ul>
+</body>
+</html>
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/fileSpecs/EmbeddedFile.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/fileSpecs/EmbeddedFile.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/fileSpecs/EmbeddedFile.java	(revision 23703)
@@ -0,0 +1,127 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.fileSpecs;
+
+import it.stefanochizzolini.clown.bytes.Buffer;
+import it.stefanochizzolini.clown.bytes.FileInputStream;
+import it.stefanochizzolini.clown.bytes.IInputStream;
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.objects.PdfDictionary;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfObjectWrapper;
+import it.stefanochizzolini.clown.objects.PdfStream;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+/**
+  Embedded file [PDF:1.6:3.10.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.7
+  @version 0.0.7
+*/
+public class EmbeddedFile
+  extends PdfObjectWrapper<PdfStream>
+{
+  // <class>
+  // <static>
+  // <interface>
+  // <public>
+  public static EmbeddedFile get(
+    Document context,
+    String path
+    )
+  {
+    try
+    {
+      return new EmbeddedFile(
+        context,
+        new FileInputStream(
+          new java.io.RandomAccessFile(path,"r")
+          )
+        );
+    }
+    catch(Exception e)
+    {throw new RuntimeException(e);}
+  }
+
+  public static EmbeddedFile get(
+    Document context,
+    java.io.File file
+    )
+  {return get(context,file.getPath());}
+  // </public>
+  // </interface>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  /**
+    Creates a new embedded file inside the document.
+  */
+  public EmbeddedFile(
+    Document context,
+    IInputStream stream
+    )
+  {
+    super(
+      context.getFile(),
+      new PdfStream(
+        new PdfDictionary(
+          new PdfName[]{PdfName.Type},
+          new PdfDirectObject[]{PdfName.EmbeddedFile}
+          ),
+        new Buffer(stream.toByteArray())
+        )
+      );
+  }
+
+  /**
+    Instantiates an existing embedded file.
+  */
+  public EmbeddedFile(
+    PdfDirectObject baseObject
+    )
+  {
+    super(
+      baseObject,
+      null // NO container (baseObject is (by definition) a PDF stream, so it MUST be an indirect object [PDF:1.6:3.2.7]).
+      );
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public EmbeddedFile clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/fileSpecs/FileSpec.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/fileSpecs/FileSpec.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/fileSpecs/FileSpec.java	(revision 23703)
@@ -0,0 +1,419 @@
+/*
+  Copyright 2008-2009 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.fileSpecs;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.objects.PdfDictionary;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfNamedObjectWrapper;
+import it.stefanochizzolini.clown.objects.PdfReference;
+import it.stefanochizzolini.clown.objects.PdfString;
+import it.stefanochizzolini.clown.objects.PdfTextString;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+/**
+  Reference to the contents of another file (file specification) [PDF:1.6:3.10.2].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.7
+  @version 0.0.8
+*/
+public class FileSpec
+  extends PdfNamedObjectWrapper<PdfDictionary>
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  public FileSpec(
+    Document context
+    )
+  {
+    super(
+      context.getFile(),
+      new PdfDictionary(
+        new PdfName[]
+        {PdfName.Type},
+        new PdfDirectObject[]
+        {PdfName.Filespec}
+        )
+      );
+  }
+
+  public FileSpec(
+    EmbeddedFile embeddedFile,
+    String filename
+    )
+  {
+    this(embeddedFile.getDocument());
+
+    setFilename(filename);
+    setEmbeddedFile(embeddedFile);
+  }
+
+  public FileSpec(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container,
+    PdfString name
+    )
+  {super(baseObject,container,name);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public FileSpec clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    Gets the related files.
+  */
+  public RelatedFiles getDependencies(
+    )
+  {return getDependencies(PdfName.F);}
+
+  /**
+    Gets the description of the file.
+  */
+  public String getDescription(
+    )
+  {
+    /*
+      NOTE: 'Desc' entry may be undefined.
+    */
+    PdfTextString descriptionObject = (PdfTextString)getBaseDataObject().get(PdfName.Desc);
+    if(descriptionObject == null)
+      return null;
+
+    return (String)descriptionObject.getValue();
+  }
+
+  /**
+    Gets the embedded file.
+  */
+  public EmbeddedFile getEmbeddedFile(
+    )
+  {return getEmbeddedFile(PdfName.F);}
+
+  /**
+    Gets the Mac OS-specific related files.
+  */
+  public RelatedFiles getMacDependencies(
+    )
+  {return getDependencies(PdfName.Mac);}
+
+  /**
+    Gets the Mac OS-specific embedded file.
+  */
+  public EmbeddedFile getMacEmbeddedFile(
+    )
+  {return getEmbeddedFile(PdfName.Mac);}
+
+  /**
+    Gets the Mac OS-specific file name.
+  */
+  public String getMacFilename(
+    )
+  {return getFilename(PdfName.Mac);}
+
+  /**
+    Gets the file name.
+  */
+  public String getFilename(
+    )
+  {return getFilename(PdfName.F);}
+
+  /**
+    Gets the Unix-specific related files.
+  */
+  public RelatedFiles getUnixDependencies(
+    )
+  {return getDependencies(PdfName.Unix);}
+
+  /**
+    Gets the Unix-specific embedded file.
+  */
+  public EmbeddedFile getUnixEmbeddedFile(
+    )
+  {return getEmbeddedFile(PdfName.Unix);}
+
+  /**
+    Gets the Unix-specific file name.
+  */
+  public String getUnixFilename(
+    )
+  {return getFilename(PdfName.Unix);}
+
+  /**
+    Gets the Windows-specific related files.
+  */
+  public RelatedFiles getWinDependencies(
+    )
+  {return getDependencies(PdfName.DOS);}
+
+  /**
+    Gets the Windows-specific embedded file.
+  */
+  public EmbeddedFile getWinEmbeddedFile(
+    )
+  {return getEmbeddedFile(PdfName.DOS);}
+
+  /**
+    Gets the Windows-specific file name.
+  */
+  public String getWinFilename(
+    )
+  {return getFilename(PdfName.DOS);}
+
+  /**
+    @see #getDescription()
+  */
+  public void setDescription(
+    String value
+    )
+  {getBaseDataObject().put(PdfName.Desc, new PdfTextString(value));}
+
+  /**
+    @see #getDependencies()
+  */
+  public void setDependencies(
+    RelatedFiles value
+    )
+  {setDependencies(PdfName.F,value);}
+
+  /**
+    @see #getEmbeddedFile()
+  */
+  public void setEmbeddedFile(
+    EmbeddedFile value
+    )
+  {setEmbeddedFile(PdfName.F,value);}
+
+  /**
+    @see #getMacDependencies()
+  */
+  public void setMacDependencies(
+    RelatedFiles value
+    )
+  {setDependencies(PdfName.Mac,value);}
+
+  /**
+    @see #getMacEmbeddedFile()
+  */
+  public void setMacEmbeddedFile(
+    EmbeddedFile value
+    )
+  {setEmbeddedFile(PdfName.Mac,value);}
+
+  /**
+    @see #getMacFilename()
+  */
+  public void setMacFilename(
+    String value
+    )
+  {setFilename(PdfName.Mac,value);}
+
+  /**
+    @see #getFilename()
+  */
+  public void setFilename(
+    String value
+    )
+  {setFilename(PdfName.F,value);}
+
+  /**
+    @see #getUnixDependencies()
+  */
+  public void setUnixDependencies(
+    RelatedFiles value
+    )
+  {setDependencies(PdfName.Unix,value);}
+
+  /**
+    @see #getUnixEmbeddedFile()
+  */
+  public void setUnixEmbeddedFile(
+    EmbeddedFile value
+    )
+  {setEmbeddedFile(PdfName.Unix,value);}
+
+  /**
+    @see #getUnixFilename()
+  */
+  public void setUnixFilename(
+    String value
+    )
+  {setFilename(PdfName.Unix,value);}
+
+  /**
+    @see #getWinDependencies()
+  */
+  public void setWinDependencies(
+    RelatedFiles value
+    )
+  {setDependencies(PdfName.DOS,value);}
+
+  /**
+    @see #getWinEmbeddedFile()
+  */
+  public void setWinEmbeddedFile(
+    EmbeddedFile value
+    )
+  {setEmbeddedFile(PdfName.DOS,value);}
+
+  /**
+    @see #getWinFilename()
+  */
+  public void setWinFilename(
+    String value
+    )
+  {setFilename(PdfName.DOS,value);}
+  // </public>
+
+  // <private>
+  /**
+    Gets the related files associated to the given key.
+  */
+  private RelatedFiles getDependencies(
+    PdfName key
+    )
+  {
+    /*
+      NOTE: 'RF' entry may be undefined.
+    */
+    PdfDictionary dependenciesObject = (PdfDictionary)getBaseDataObject().get(PdfName.RF);
+    if(dependenciesObject == null)
+      return null;
+
+    /*
+      NOTE: key entry may be undefined.
+    */
+    PdfReference dependencyFilesObject = (PdfReference)dependenciesObject.get(key);
+    if(dependencyFilesObject == null)
+      return null;
+
+    return new RelatedFiles(dependencyFilesObject,getContainer());
+  }
+
+  /**
+    Gets the embedded file associated to the given key.
+  */
+  private EmbeddedFile getEmbeddedFile(
+    PdfName key
+    )
+  {
+    /*
+      NOTE: 'EF' entry may be undefined.
+    */
+    PdfDictionary embeddedFilesObject = (PdfDictionary)getBaseDataObject().get(PdfName.EF);
+    if(embeddedFilesObject == null)
+      return null;
+
+    /*
+      NOTE: key entry may be undefined.
+    */
+    PdfReference embeddedFileObject = (PdfReference)embeddedFilesObject.get(key);
+    if(embeddedFileObject == null)
+      return null;
+
+    return new EmbeddedFile(embeddedFileObject);
+  }
+
+  /**
+    Gets the file name associated to the given key.
+  */
+  private String getFilename(
+    PdfName key
+    )
+  {
+    /*
+      NOTE: key entry may be undefined.
+    */
+    PdfString nameObject = (PdfString)getBaseDataObject().get(key);
+    if(nameObject == null)
+      return null;
+
+    return (String)nameObject.getValue();
+  }
+
+  /**
+    @see #getDependencies(PdfName)
+  */
+  private void setDependencies(
+    PdfName key,
+    RelatedFiles value
+    )
+  {
+    /*
+      NOTE: 'RF' entry may be undefined.
+    */
+    PdfDictionary dependenciesObject = (PdfDictionary)getBaseDataObject().get(PdfName.RF);
+    if(dependenciesObject == null)
+    {
+      dependenciesObject = new PdfDictionary();
+      getBaseDataObject().put(PdfName.RF,dependenciesObject);
+    }
+
+    dependenciesObject.put(key,value.getBaseObject());
+  }
+
+  /**
+    @see #getEmbeddedFile(PdfName)
+  */
+  private void setEmbeddedFile(
+    PdfName key,
+    EmbeddedFile value
+    )
+  {
+    /*
+      NOTE: 'EF' entry may be undefined.
+    */
+    PdfDictionary embeddedFilesObject = (PdfDictionary)getBaseDataObject().get(PdfName.EF);
+    if(embeddedFilesObject == null)
+    {
+      embeddedFilesObject = new PdfDictionary();
+      getBaseDataObject().put(PdfName.EF,embeddedFilesObject);
+    }
+
+    embeddedFilesObject.put(key,value.getBaseObject());
+  }
+
+  /**
+    @see #getFilename(PdfName)
+  */
+  private void setFilename(
+    PdfName key,
+    String value
+    )
+  {getBaseDataObject().put(key, new PdfString(value));}
+  // <private>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/fileSpecs/RelatedFiles.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/fileSpecs/RelatedFiles.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/fileSpecs/RelatedFiles.java	(revision 23703)
@@ -0,0 +1,332 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.fileSpecs;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.objects.PdfArray;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfObjectWrapper;
+import it.stefanochizzolini.clown.objects.PdfTextString;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+  Embedded files referenced by another one (dependencies) [PDF:1.6:3.10.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.7
+  @version 0.0.7
+*/
+public class RelatedFiles
+  extends PdfObjectWrapper<PdfArray>
+  implements Map<String,EmbeddedFile>
+{
+  // <class>
+  // <classes>
+  private class Entry
+    implements Map.Entry<String,EmbeddedFile>
+  {
+    // <class>
+    // <dynamic>
+    // <fields>
+    private final String key;
+    private final EmbeddedFile value;
+    // </fields>
+
+    // <constructors>
+    private Entry(
+      String key,
+      EmbeddedFile value
+      )
+    {
+      this.key = key;
+      this.value = value;
+    }
+    // </constructors>
+
+    // <interface>
+    // <public>
+    // <Map.Entry>
+    public String getKey(
+      )
+    {return key;}
+
+    public EmbeddedFile getValue(
+      )
+    {return value;}
+
+    public EmbeddedFile setValue(
+      EmbeddedFile value
+      )
+    {throw new UnsupportedOperationException();}
+    // </Map.Entry>
+    // </public>
+    // </interface>
+    // </dynamic>
+    // </class>
+  }
+  // </classes>
+
+  // <dynamic>
+  // <constructors>
+  public RelatedFiles(
+    Document context
+    )
+  {
+    super(
+      context.getFile(),
+      new PdfArray()
+      );
+  }
+
+  RelatedFiles(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {super(baseObject,container);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public RelatedFiles clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  // <Map>
+  public void clear(
+    )
+  {getBaseDataObject().clear();}
+
+  public boolean containsKey(
+    Object key
+    )
+  {
+    PdfArray itemPairs = getBaseDataObject();
+    for(
+      int index = 0,
+        length = itemPairs.size();
+      index < length;
+      index += 2
+      )
+    {
+      if(((PdfTextString)itemPairs.get(index)).getValue().equals(key))
+        return true;
+    }
+
+    return false;
+  }
+
+  public boolean containsValue(
+    Object value
+    )
+  {
+    PdfArray itemPairs = getBaseDataObject();
+    for(
+      int index = 1,
+        length = itemPairs.size();
+      index < length;
+      index += 2
+      )
+    {
+      if(itemPairs.get(index).equals(value))
+        return true;
+    }
+
+    return false;
+  }
+
+  public Set<Map.Entry<String,EmbeddedFile>> entrySet(
+    )
+  {
+    HashSet<Map.Entry<String,EmbeddedFile>> entrySet = new HashSet<Map.Entry<String,EmbeddedFile>>();
+    PdfArray itemPairs = getBaseDataObject();
+    for(
+      int index = 0,
+        length = itemPairs.size();
+      index < length;
+      index += 2
+      )
+    {
+      entrySet.add(
+        new Entry(
+          (String)((PdfTextString)itemPairs.get(index)).getValue(),
+          new EmbeddedFile(itemPairs.get(index+1))
+          )
+        );
+    }
+
+    return entrySet;
+  }
+
+  public boolean equals(
+    PdfDirectObject object
+    )
+  {throw new NotImplementedException();}
+
+  public EmbeddedFile get(
+    Object key
+    )
+  {
+    PdfArray itemPairs = getBaseDataObject();
+    for(
+      int index = 0,
+        length = itemPairs.size();
+      index < length;
+      index += 2
+      )
+    {
+      if(((PdfTextString)itemPairs.get(index)).getValue().equals(key))
+        return new EmbeddedFile(itemPairs.get(index+1));
+    }
+
+    return null;
+  }
+
+  public int hashCode(
+    )
+  {throw new NotImplementedException();}
+
+  public boolean isEmpty(
+    )
+  {return (getBaseDataObject().size() == 0);}
+
+  public Set<String> keySet(
+    )
+  {
+    HashSet<String> keySet = new HashSet<String>();
+    PdfArray itemPairs = getBaseDataObject();
+    for(
+      int index = 0,
+        length = itemPairs.size();
+      index < length;
+      index += 2
+      )
+    {
+      keySet.add(
+        (String)((PdfTextString)itemPairs.get(index)).getValue()
+        );
+    }
+
+    return keySet;
+  }
+
+  public EmbeddedFile put(
+    String key,
+    EmbeddedFile value
+    )
+  {
+    PdfArray itemPairs = getBaseDataObject();
+    for(
+      int index = 0,
+        length = itemPairs.size();
+      index < length;
+      index += 2
+      )
+    {
+      // Already existing entry?
+      if(((PdfTextString)itemPairs.get(index)).getValue().equals(key))
+      {
+        EmbeddedFile oldEmbeddedFile = new EmbeddedFile(itemPairs.get(index+1));
+
+        itemPairs.set(index+1,value.getBaseObject());
+
+        return oldEmbeddedFile;
+      }
+    }
+
+    // New entry.
+    itemPairs.add(new PdfTextString(key));
+    itemPairs.add(value.getBaseObject());
+
+    return null;
+  }
+
+  public void putAll(
+    Map<? extends String,? extends EmbeddedFile> entries
+    )
+  {throw new NotImplementedException();}
+
+  public EmbeddedFile remove(
+    Object key
+    )
+  {
+    PdfArray itemPairs = getBaseDataObject();
+    for(
+      int index = 0,
+        length = itemPairs.size();
+      index < length;
+      index += 2
+      )
+    {
+      if(((PdfTextString)itemPairs.get(index)).getValue().equals(key))
+      {
+        itemPairs.remove(index); // Key removed.
+
+        return new EmbeddedFile(itemPairs.remove(index)); // Value removed.
+      }
+    }
+
+    return null;
+  }
+
+  public int size(
+    )
+  {return getBaseDataObject().size();}
+
+  public Collection<EmbeddedFile> values(
+    )
+  {
+    List<EmbeddedFile> values = new ArrayList<EmbeddedFile>();
+    PdfArray itemPairs = getBaseDataObject();
+    for(
+      int index = 1,
+        length = itemPairs.size();
+      index < length;
+      index += 2
+      )
+    {
+      values.add(
+        new EmbeddedFile(itemPairs.get(index))
+        );
+    }
+
+    return values;
+  }
+  // </Map>
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/fileSpecs/package.html
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/fileSpecs/package.html	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/fileSpecs/package.html	(revision 23703)
@@ -0,0 +1,38 @@
+<html>
+<head>
+<!--
+  Copyright 2008-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+-->
+</head>
+<body>
+<p>File specifications used to reference the contents of other
+(either external or embedded) files [PDF:1.6:3.10].</p>
+
+<h2>Related Documentation</h2>
+<p>For overviews, tutorials, examples, guides, and tool documentation, please see:</p>
+<ul>
+  <li><a href="http://clown.stefanochizzolini.it">PDF Clown Home Page</a>
+</ul>
+</body>
+</html>
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/ILink.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/ILink.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/ILink.java	(revision 23703)
@@ -0,0 +1,79 @@
+/*
+  Copyright 2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+  
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+  
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+  
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+  
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction;
+
+import it.stefanochizzolini.clown.documents.interaction.actions.Action;
+import it.stefanochizzolini.clown.documents.interaction.navigation.document.Destination;
+import it.stefanochizzolini.clown.objects.PdfObjectWrapper;
+
+/**
+  Link.
+  
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+  @since 0.0.8
+*/
+public interface ILink
+{
+  /**
+    Gets the action to be performed when the link is activated.
+  */
+  public Action getAction(
+    );
+
+  /**
+    Gets the destination to jump to when the link is activated.
+  */
+  public Destination getDestination(
+    );
+
+  /**
+    Gets the link target (either a Destination or an Action).
+  */
+  public PdfObjectWrapper<?> getTarget(
+    );
+
+  /**
+    @see #getAction()
+  */
+  public void setAction(
+    Action value
+    );
+
+  /**
+    @see #getDestination()
+  */
+  public void setDestination(
+    Destination value
+    );
+
+  /**
+    @see #getTarget()
+  */
+  public void setTarget(
+    PdfObjectWrapper<?> value
+    );
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/Action.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/Action.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/Action.java	(revision 23703)
@@ -0,0 +1,217 @@
+/*
+  Copyright 2008-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.actions;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.files.File;
+import it.stefanochizzolini.clown.objects.PdfDictionary;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfObjectWrapper;
+import it.stefanochizzolini.clown.objects.PdfReference;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+/**
+  Action to be performed by the viewer application [PDF:1.6:8.5].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+  @since 0.0.7
+*/
+public class Action
+  extends PdfObjectWrapper<PdfDictionary>
+{
+  // <class>
+  // <static>
+  // <fields>
+  // </fields>
+
+  // <interface>
+  // <public>
+  /**
+    Wraps an action reference into an action object.
+
+    @param reference Reference to an action object.
+    @return Action object associated to the reference.
+  */
+  public static final Action wrap(
+    PdfReference reference
+    )
+  {return wrap(reference,null);}
+
+  /**
+    Wraps an action base object into an action object.
+
+    @param baseObject Action base object.
+    @param container Action base object container.
+    @return Action object associated to the base object.
+  */
+  public static final Action wrap(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {
+    /*
+      NOTE: This is a factory method for any action-derived object.
+    */
+    if(baseObject == null)
+      return null;
+
+    PdfDictionary dataObject = (PdfDictionary)File.resolve(baseObject);
+    PdfName actionType = (PdfName)dataObject.get(PdfName.S);
+    if(actionType == null
+      || (dataObject.containsKey(PdfName.Type)
+          && !dataObject.get(PdfName.Type).equals(PdfName.Action)))
+      return null;
+
+    if(actionType.equals(PdfName.GoTo))
+      return new GoToLocal(baseObject,container);
+    else if(actionType.equals(PdfName.GoToR))
+      return new GoToRemote(baseObject,container);
+    else if(actionType.equals(PdfName.GoToE))
+      return new GoToEmbedded(baseObject,container);
+    else if(actionType.equals(PdfName.Launch))
+      return new Launch(baseObject,container);
+    else if(actionType.equals(PdfName.Thread))
+      return new GoToThread(baseObject,container);
+    else if(actionType.equals(PdfName.URI))
+      return new GoToURI(baseObject,container);
+    else if(actionType.equals(PdfName.Sound))
+      return new PlaySound(baseObject,container);
+    else if(actionType.equals(PdfName.Movie))
+      return new PlayMovie(baseObject,container);
+    else if(actionType.equals(PdfName.Hide))
+      return new ToggleVisibility(baseObject,container);
+    else if(actionType.equals(PdfName.Named))
+    {
+      PdfName actionName = (PdfName)dataObject.get(PdfName.N);
+      if(actionName.equals(PdfName.NextPage))
+        return new GoToNextPage(baseObject,container);
+      else if(actionName.equals(PdfName.PrevPage))
+        return new GoToPreviousPage(baseObject,container);
+      else if(actionName.equals(PdfName.FirstPage))
+        return new GoToFirstPage(baseObject,container);
+      else if(actionName.equals(PdfName.LastPage))
+        return new GoToLastPage(baseObject,container);
+      else // Custom named action.
+        return new NamedAction(baseObject,container);
+    }
+    else if(actionType.equals(PdfName.SubmitForm))
+      return new SubmitForm(baseObject,container);
+    else if(actionType.equals(PdfName.ResetForm))
+      return new ResetForm(baseObject,container);
+    else if(actionType.equals(PdfName.ImportData))
+      return new ImportData(baseObject,container);
+    else if(actionType.equals(PdfName.JavaScript))
+      return new JavaScript(baseObject,container);
+    else if(actionType.equals(PdfName.SetOCGState))
+      return new SetOcgState(baseObject,container);
+    else if(actionType.equals(PdfName.Rendition))
+      return new Rendition(baseObject,container);
+    else if(actionType.equals(PdfName.Trans))
+      return new DoTransition(baseObject,container);
+    else if(actionType.equals(PdfName.GoTo3DView))
+      return new GoTo3dView(baseObject,container);
+    else // Custom action.
+      return new Action(baseObject,container);
+  }
+  // </public>
+  // </interface>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  /**
+    Creates a new action within the given document context.
+  */
+  protected Action(
+    Document context,
+    PdfName actionType
+    )
+  {
+    super(
+      context.getFile(),
+      new PdfDictionary(
+        new PdfName[]
+        {
+          PdfName.Type,
+          PdfName.S
+        },
+        new PdfDirectObject[]
+        {
+          PdfName.Action,
+          actionType
+        }
+        )
+      );
+  }
+
+  protected Action(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {
+    super(
+      baseObject,
+      container
+      );
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public Action clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    Gets the actions to be performed after the current one.
+  */
+  public ChainedActions getActions(
+    )
+  {
+    PdfDirectObject nextObject = getBaseDataObject().get(PdfName.Next);
+    if(nextObject == null)
+      return null;
+
+    return new ChainedActions(nextObject,getContainer(),this);
+  }
+
+  /**
+    @see #getActions()
+  */
+  public void setActions(
+    ChainedActions value
+    )
+  {getBaseDataObject().put(PdfName.Next,value.getBaseObject());}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/ChainedActions.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/ChainedActions.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/ChainedActions.java	(revision 23703)
@@ -0,0 +1,393 @@
+/*
+  Copyright 2008-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.actions;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.objects.PdfArray;
+import it.stefanochizzolini.clown.objects.PdfDataObject;
+import it.stefanochizzolini.clown.objects.PdfDictionary;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfObjectWrapper;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.NoSuchElementException;
+
+/**
+  Chained actions [PDF:1.6:8.5.1].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+  @since 0.0.7
+*/
+public class ChainedActions
+  extends PdfObjectWrapper<PdfDataObject>
+  implements List<Action>
+{
+  /*
+    NOTE: Chained actions may be either singular or multiple (within an array).
+    This implementation hides such a complexity to the user, smoothly exposing
+    just the most general case (array) yet preserving its internal state.
+  */
+  // <class>
+  // <dynamic>
+  // <fields>
+  /**
+    Parent action.
+  */
+  private Action parent;
+  // </fields>
+
+  // <constructors>
+  ChainedActions(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container,
+    Action parent
+    )
+  {
+    super(
+      baseObject,
+      container
+      );
+
+    this.parent = parent;
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public ChainedActions clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    Gets the parent action.
+  */
+  public Action getParent(
+    )
+  {return parent;}
+
+  // <List>
+  public void add(
+    int index,
+    Action value
+    )
+  {ensureArray().add(index,value.getBaseObject());}
+
+  public boolean addAll(
+    int index,
+    Collection<? extends Action> values
+    )
+  {
+    PdfArray items = ensureArray();
+    for(Action value : values)
+    {items.add(index++,value.getBaseObject());}
+
+    return true;
+  }
+
+  public Action get(
+    int index
+    )
+  {
+    PdfDataObject baseDataObject = getBaseDataObject();
+    if(baseDataObject instanceof PdfDictionary) // Single action.
+    {
+      if(index != 0)
+        throw new IndexOutOfBoundsException("Index: " + index + ", Size: 1");
+
+      return Action.wrap(getBaseObject(),getContainer());
+    }
+
+    return Action.wrap(((PdfArray)baseDataObject).get(index),getContainer());
+  }
+
+  public int indexOf(
+    Object value
+    )
+  {
+    if(!(value instanceof Action))
+      return -1;
+
+    PdfDataObject baseDataObject = getBaseDataObject();
+    if(baseDataObject instanceof PdfDictionary) // Single action.
+    {
+      if(!((Action)value).getBaseObject().equals(getBaseObject()))
+        return -1;
+
+      return 0;
+    }
+
+    return ((PdfArray)baseDataObject).indexOf(((Action)value).getBaseObject());
+  }
+
+  public int lastIndexOf(
+    Object value
+    )
+  {
+    /*
+      NOTE: Actions are expected not to be duplicated.
+    */
+    return indexOf(value);
+  }
+
+  public ListIterator<Action> listIterator(
+    )
+  {throw new NotImplementedException();}
+
+  public ListIterator<Action> listIterator(
+    int index
+    )
+  {throw new NotImplementedException();}
+
+  public Action remove(
+    int index
+    )
+  {
+    PdfDirectObject actionObject = ensureArray().remove(index);
+
+    return Action.wrap(actionObject,getContainer());
+  }
+
+  public Action set(
+    int index,
+    Action value
+    )
+  {
+    return Action.wrap(
+      ensureArray().set(index,value.getBaseObject()),
+      getContainer()
+      );
+  }
+
+  public List<Action> subList(
+    int fromIndex,
+    int toIndex
+    )
+  {throw new NotImplementedException();}
+
+  // <Collection>
+  public boolean add(
+    Action value
+    )
+  {return ensureArray().add(value.getBaseObject());}
+
+  public boolean addAll(
+    Collection<? extends Action> values
+    )
+  {
+    for(Action value : values)
+    {add(value);}
+
+    return true;
+  }
+
+  public void clear(
+    )
+  {ensureArray().clear();}
+
+  public boolean contains(
+    Object value
+    )
+  {
+    if(!(value instanceof Action))
+      return false;
+
+    PdfDataObject baseDataObject = getBaseDataObject();
+    if(baseDataObject instanceof PdfDictionary) // Single action.
+      return ((Action)value).getBaseObject().equals(getBaseObject());
+
+    return ((PdfArray)baseDataObject).contains(((Action)value).getBaseObject());
+  }
+
+  public boolean containsAll(
+    Collection<?> values
+    )
+  {throw new NotImplementedException();}
+
+  public boolean equals(
+    Object object
+    )
+  {throw new NotImplementedException();}
+
+  public int hashCode(
+    )
+  {throw new NotImplementedException();}
+
+  public boolean isEmpty(
+    )
+  {
+    PdfDataObject baseDataObject = getBaseDataObject();
+    if(baseDataObject instanceof PdfDictionary) // Single action.
+      return false;
+
+    return ((PdfArray)baseDataObject).isEmpty();
+  }
+
+  public boolean remove(
+    Object value
+    )
+  {
+    if(!(value instanceof Action))
+      return false;
+
+    return ensureArray().remove(((Action)value).getBaseObject());
+  }
+
+  public boolean removeAll(
+    Collection<?> values
+    )
+  {throw new NotImplementedException();}
+
+  public boolean retainAll(
+    Collection<?> values
+    )
+  {throw new NotImplementedException();}
+
+  public int size(
+    )
+  {
+    PdfDataObject baseDataObject = getBaseDataObject();
+    if(baseDataObject instanceof PdfDictionary) // Single action.
+      return 1;
+
+    return ((PdfArray)baseDataObject).size();
+  }
+
+  public Object[] toArray(
+    )
+  {return toArray(new Action[0]);}
+
+  @SuppressWarnings("unchecked")
+  public <T> T[] toArray(
+    T[] values
+    )
+  {
+    PdfDataObject baseDataObject = getBaseDataObject();
+    if(baseDataObject instanceof PdfDictionary) // Single action.
+    {
+      if(values.length == 0)
+      {values = (T[])new Object[1];}
+
+      values[0] = (T)Action.wrap(getBaseObject(),getContainer());
+    }
+    else // Array.
+    {
+      PdfArray actionObjects = (PdfArray)baseDataObject;
+      if(values.length < actionObjects.size())
+      {values = (T[])new Object[actionObjects.size()];}
+
+      PdfIndirectObject container = getContainer();
+      for(
+        int index = 0,
+          length = actionObjects.size();
+        index < length;
+        index++
+        )
+      {values[index] = (T)Action.wrap(actionObjects.get(index),container);}
+    }
+    return values;
+  }
+
+  // <Iterable>
+  public Iterator<Action> iterator(
+    )
+  {
+    return new Iterator<Action>()
+    {
+      // <class>
+      // <dynamic>
+      // <fields>
+      /**
+        Index of the next item.
+      */
+      private int index = 0;
+      /**
+        Collection size.
+      */
+      private int size = size();
+      // </fields>
+
+      // <interface>
+      // <public>
+      // <Iterator>
+      public boolean hasNext(
+        )
+      {return (index < size);}
+
+      public Action next(
+        )
+      {
+        if(!hasNext())
+          throw new NoSuchElementException();
+
+        return get(index++);
+      }
+
+      public void remove(
+        )
+      {throw new UnsupportedOperationException();}
+      // </Iterator>
+      // </public>
+      // </interface>
+      // </dynamic>
+      // </class>
+    };
+  }
+  // </Iterable>
+  // </Collection>
+  // </List>
+  // </public>
+
+  // <private>
+  private PdfArray ensureArray(
+    )
+  {
+    PdfDataObject baseDataObject = getBaseDataObject();
+    if(baseDataObject instanceof PdfDictionary) // Single action.
+    {
+      PdfArray actionsArray = new PdfArray();
+      actionsArray.add(getBaseObject());
+      setBaseObject(actionsArray);
+      parent.getBaseDataObject().put(PdfName.Next,actionsArray);
+
+      baseDataObject = actionsArray;
+    }
+
+    return (PdfArray)baseDataObject;
+  }
+  // </private>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/DoTransition.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/DoTransition.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/DoTransition.java	(revision 23703)
@@ -0,0 +1,107 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.actions;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.interaction.navigation.page.Transition;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+/**
+  'Control drawing during a sequence of actions' action [PDF:1.6:8.5.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.7
+  @since 0.0.7
+*/
+public class DoTransition
+  extends Action
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  /**
+    Creates a new transition action within the given document context.
+  */
+  public DoTransition(
+    Document context,
+    Transition transition
+    )
+  {
+    super(
+      context,
+      PdfName.Trans
+      );
+
+    setTransition(transition);
+  }
+
+  DoTransition(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {
+    super(
+      baseObject,
+      container
+      );
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public DoTransition clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    Gets the transition effect to be used for the update of the display.
+  */
+  public Transition getTransition(
+    )
+  {
+    /*
+      NOTE: 'Trans' entry MUST exist.
+    */
+    return new Transition(getBaseDataObject().get(PdfName.Trans),getContainer());
+  }
+
+  /**
+    @see #getTransition()
+  */
+  public void setTransition(
+    Transition value
+    )
+  {getBaseDataObject().put(PdfName.Trans, value.getBaseObject());}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/GoTo3dView.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/GoTo3dView.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/GoTo3dView.java	(revision 23703)
@@ -0,0 +1,84 @@
+/*
+  Copyright 2008-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.actions;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+/**
+  'Change the view to a specified 3D annotation' action [PDF:1.6:8.5.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.7
+  @version 0.0.8
+*/
+public class GoTo3dView
+  extends Action
+  implements IGoToAction
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  /**
+    Creates a new action within the given document context.
+  */
+  public GoTo3dView(
+    Document context
+    )
+  {
+    super(
+      context,
+      PdfName.GoTo3DView
+      );
+  }
+
+  GoTo3dView(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {
+    super(
+      baseObject,
+      container
+      );
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public GoTo3dView clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/GoToDestination.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/GoToDestination.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/GoToDestination.java	(revision 23703)
@@ -0,0 +1,106 @@
+/*
+  Copyright 2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.actions;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.interaction.navigation.document.Destination;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+
+/**
+  Abstract go-to-destination action.
+  
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+  @since 0.0.8
+*/
+public abstract class GoToDestination<T extends Destination>
+  extends Action
+  implements IGoToAction
+{
+  // <class>
+  // <constructors>
+  protected GoToDestination(
+    Document context,
+    PdfName actionType,
+    T destination
+    )
+  {
+    super(context,actionType);
+    
+    setDestination(destination);
+  }
+
+  protected GoToDestination(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {super(baseObject,container);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  /**
+    Gets the destination to jump to.
+  */
+  public T getDestination(
+    )
+  {
+    /*
+      NOTE: 'D' entry MUST exist.
+    */
+    return Document.resolveName(
+      getDestinationClass(),
+      getBaseDataObject().get(PdfName.D),
+      getContainer()
+      );
+  }
+  
+  /**
+    @see #getDestination()
+  */
+  public void setDestination(
+    T value
+    )
+  {
+    if(value == null)
+      throw new IllegalArgumentException("Destination MUST be defined.");
+  
+    getBaseDataObject().put(PdfName.D,value.getNamedBaseObject());
+  }
+  // </public>
+  
+  // <protected>
+  /*
+    NOTE: This getter is necessary because of type erasure.
+  */
+  protected abstract Class<T> getDestinationClass(
+    );
+  // </protected>
+  // </interface>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/GoToEmbedded.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/GoToEmbedded.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/GoToEmbedded.java	(revision 23703)
@@ -0,0 +1,542 @@
+/*
+  Copyright 2008-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.actions;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.fileSpecs.FileSpec;
+import it.stefanochizzolini.clown.documents.interaction.navigation.document.Destination;
+import it.stefanochizzolini.clown.objects.PdfAtomicObject;
+import it.stefanochizzolini.clown.objects.PdfBoolean;
+import it.stefanochizzolini.clown.objects.PdfDictionary;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfInteger;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfObjectWrapper;
+import it.stefanochizzolini.clown.objects.PdfString;
+import it.stefanochizzolini.clown.objects.PdfTextString;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.util.EnumSet;
+
+/**
+  'Change the view to a specified destination in a PDF file
+  embedded in another PDF file' action [PDF:1.6:8.5.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+  @since 0.0.7
+*/
+public class GoToEmbedded
+  extends GoToNonLocal<Destination>
+{
+  // <class>
+  // <classes>
+  /**
+    Path information to the target document [PDF:1.6:8.5.3].
+  */
+  public static class TargetObject
+    extends PdfObjectWrapper<PdfDictionary>
+  {
+    // <class>
+    // <classes>
+    /**
+      Relationship between the target and the current document [PDF:1.6:8.5.3].
+    */
+    public enum RelationEnum
+    {
+      // <class>
+      // <static>
+      // <fields>
+      /**
+        Parent.
+      */
+      Parent(PdfName.P),
+      /**
+        Child.
+      */
+      Child(PdfName.C);
+      // </fields>
+
+      // <interface>
+      // <public>
+      /**
+        Gets the relation corresponding to the given value.
+      */
+      public static RelationEnum get(
+        PdfName value
+        )
+      {
+        for(RelationEnum relation : RelationEnum.values())
+        {
+          if(relation.getCode().equals(value))
+            return relation;
+        }
+        return null;
+      }
+      // </public>
+      // </interface>
+      // </static>
+
+      // <dynamic>
+      // <fields>
+      private final PdfName code;
+      // </fields>
+
+      // <constructors>
+      private RelationEnum(
+        PdfName code
+        )
+      {this.code = code;}
+      // </constructors>
+
+      // <interface>
+      // <public>
+      public PdfName getCode(
+        )
+      {return code;}
+      // </public>
+      // </interface>
+      // </dynamic>
+      // </class>
+    }
+    // </classes>
+
+    // <dynamic>
+    // <constructors>
+    /**
+      Creates a new target representing the parent of the document.
+    */
+    public TargetObject(
+      Document context,
+      TargetObject target
+      )
+    {
+      this(
+        context,
+        RelationEnum.Parent,
+        null,
+        null,
+        null,
+        target
+        );
+    }
+
+    /**
+      Creates a new target located in the embedded files collection of the document.
+    */
+    public TargetObject(
+      Document context,
+      String embeddedFileName,
+      TargetObject target
+      )
+    {
+      this(
+        context,
+        RelationEnum.Child,
+        embeddedFileName,
+        null,
+        null,
+        target
+        );
+    }
+
+    /**
+      Creates a new target associated with a file attachment annotation.
+    */
+    public TargetObject(
+      Document context,
+      Object annotationPageRef,
+      Object annotationRef,
+      TargetObject target
+      )
+    {
+      this(
+        context,
+        RelationEnum.Child,
+        null,
+        annotationPageRef,
+        annotationRef,
+        target
+        );
+    }
+
+    /**
+      Creates a new target.
+    */
+    private TargetObject(
+      Document context,
+      RelationEnum relation,
+      String embeddedFileName,
+      Object annotationPageRef,
+      Object annotationRef,
+      TargetObject target
+      )
+    {
+      super(
+        context.getFile(),
+        new PdfDictionary()
+        );
+
+      setRelation(relation);
+      setEmbeddedFileName(embeddedFileName);
+      setAnnotationPageRef(annotationPageRef);
+      setAnnotationRef(annotationRef);
+      setTarget(target);
+    }
+
+    private TargetObject(
+      PdfDirectObject baseObject,
+      PdfIndirectObject container
+      )
+    {super(baseObject,container);}
+    // </constructors>
+
+    // <interface>
+    // <public>
+    @Override
+    public TargetObject clone(
+      Document context
+      )
+    {throw new NotImplementedException();}
+
+    /**
+      Gets the page reference to the file attachment annotation.
+
+      @return Either the (zero-based) number of the page in the current document containing the file attachment annotation,
+        or the name of a destination in the current document that provides the page number of the file attachment annotation.
+    */
+    public Object getAnnotationPageRef(
+      )
+    {
+      /*
+        NOTE: 'P' entry may be undefined.
+      */
+      PdfAtomicObject<?> pageRefObject = (PdfAtomicObject<?>)getBaseDataObject().get(PdfName.P);
+      if(pageRefObject == null)
+        return null;
+
+      return pageRefObject.getValue();
+    }
+
+    /**
+      Gets the reference to the file attachment annotation.
+
+      @return Either the (zero-based) index of the annotation in the list of annotations
+        associated to the page specified by the annotationPageRef property,
+        or the name of the annotation.
+    */
+    public Object getAnnotationRef(
+      )
+    {
+      /*
+        NOTE: 'A' entry may be undefined.
+      */
+      PdfAtomicObject<?> annotationRefObject = (PdfAtomicObject<?>)getBaseDataObject().get(PdfName.A);
+      if(annotationRefObject == null)
+        return null;
+
+      return annotationRefObject.getValue();
+    }
+
+    /**
+      Gets the embedded file name.
+    */
+    public String getEmbeddedFileName(
+      )
+    {
+      /*
+        NOTE: 'N' entry may be undefined.
+      */
+      PdfString fileNameObject = (PdfString)getBaseDataObject().get(PdfName.N);
+      if(fileNameObject == null)
+        return null;
+
+      return (String)fileNameObject.getValue();
+    }
+
+    /**
+      Gets the relationship between the target and the current document.
+    */
+    public RelationEnum getRelation(
+      )
+    {
+      /*
+        NOTE: 'R' entry MUST exist.
+      */
+      return RelationEnum.get((PdfName)getBaseDataObject().get(PdfName.R));
+    }
+
+    /**
+      Gets a further path information to the target document.
+    */
+    public TargetObject getTarget(
+      )
+    {
+      /*
+        NOTE: 'T' entry may be undefined.
+      */
+      PdfDirectObject targetObject = getBaseDataObject().get(PdfName.T);
+      if(targetObject == null)
+        return null;
+
+      return new TargetObject(targetObject,getContainer());
+    }
+
+    /**
+      @see #getAnnotationPageRef()
+    */
+    public void setAnnotationPageRef(
+      Object value
+      )
+    {
+      if(value == null)
+      {getBaseDataObject().remove(PdfName.P);}
+      else
+      {
+        PdfDirectObject pageRefObject;
+        if(value instanceof Integer)
+        {pageRefObject = new PdfInteger((Integer)value);}
+        else if(value instanceof String)
+        {pageRefObject = new PdfString((String)value);}
+        else
+          throw new IllegalArgumentException("Wrong argument type: it MUST be either a page number Integer or a named destination String.");
+
+        getBaseDataObject().put(PdfName.P, pageRefObject);
+      }
+    }
+
+    /**
+      @see #getAnnotationRef()
+    */
+    public void setAnnotationRef(
+      Object value
+      )
+    {
+      if(value == null)
+      {getBaseDataObject().remove(PdfName.A);}
+      else
+      {
+        PdfDirectObject annotationRefObject;
+        if(value instanceof Integer)
+        {annotationRefObject = new PdfInteger((Integer)value);}
+        else if(value instanceof String)
+        {annotationRefObject = new PdfTextString((String)value);}
+        else
+          throw new IllegalArgumentException("Wrong argument type: it MUST be either an annotation index Integer or an annotation name String.");
+
+        getBaseDataObject().put(PdfName.A, annotationRefObject);
+      }
+    }
+
+    /**
+      @see #getEmbeddedFileName()
+    */
+    public void setEmbeddedFileName(
+      String value
+      )
+    {
+      if(value == null)
+      {getBaseDataObject().remove(PdfName.N);}
+      else
+      {getBaseDataObject().put(PdfName.N, new PdfString(value));}
+    }
+
+    /**
+      @see #getRelation()
+    */
+    public void setRelation(
+      RelationEnum value
+      )
+    {getBaseDataObject().put(PdfName.R, value.getCode());}
+
+    /**
+      @see #getTarget()
+    */
+    public void setTarget(
+      TargetObject value
+      )
+    {
+      if(value == null)
+      {getBaseDataObject().remove(PdfName.T);}
+      else
+      {getBaseDataObject().put(PdfName.T, value.getBaseObject());}
+    }
+    // </public>
+    // </interface>
+    // </dynamic>
+    // </class>
+  }
+  // </classes>
+
+  // <dynamic>
+  // <constructors>
+  /**
+    Creates a new embedded-goto action within the given document context,
+    pointing to a destination within a target document embedded within the same document.
+  */
+  public GoToEmbedded(
+    Document context,
+    TargetObject target,
+    Destination destination
+    )
+  {
+    this(
+      context,
+      null,
+      target,
+      destination
+      );
+  }
+
+  /**
+    Creates a new embedded-goto action within the given document context,
+    pointing to a destination within another document.
+  */
+  public GoToEmbedded(
+    Document context,
+    FileSpec fileSpec,
+    Destination destination
+    )
+  {
+    this(
+      context,
+      fileSpec,
+      null,
+      destination
+      );
+  }
+
+  /**
+    Creates a new embedded-goto action within the given document context.
+  */
+  public GoToEmbedded(
+    Document context,
+    FileSpec fileSpec,
+    TargetObject target,
+    Destination destination
+    )
+  {
+    super(
+      context,
+      PdfName.GoToE,
+      fileSpec,
+      destination
+      );
+    setTarget(target);
+  }
+
+  GoToEmbedded(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {
+    super(
+      baseObject,
+      container
+      );
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public GoToEmbedded clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    Gets the action options.
+  */
+  public EnumSet<OptionsEnum> getOptions(
+    )
+  {
+    EnumSet<OptionsEnum> options = EnumSet.noneOf(OptionsEnum.class);
+
+    PdfDirectObject optionsObject = getBaseDataObject().get(PdfName.NewWindow);
+    if(optionsObject != null
+      && ((Boolean)((PdfBoolean)optionsObject).getValue()).booleanValue())
+    {options.add(OptionsEnum.NewWindow);}
+
+    return options;
+  }
+
+  /**
+    Gets the path information to the target document.
+  */
+  public TargetObject getTarget(
+    )
+  {
+    /*
+      NOTE: 'T' entry may be undefined.
+    */
+    PdfDirectObject targetObject = getBaseDataObject().get(PdfName.T);
+    if(targetObject == null)
+      return null;
+
+    return new TargetObject(targetObject,getContainer());
+  }
+
+  /**
+    @see #getOptions()
+  */
+  public void setOptions(
+    EnumSet<OptionsEnum> value
+    )
+  {
+    if(value.contains(OptionsEnum.NewWindow))
+    {getBaseDataObject().put(PdfName.NewWindow,PdfBoolean.True);}
+    else if(value.contains(OptionsEnum.SameWindow))
+    {getBaseDataObject().put(PdfName.NewWindow,PdfBoolean.False);}
+    else
+    {getBaseDataObject().remove(PdfName.NewWindow);} // NOTE: Forcing the absence of this entry ensures that the viewer application should behave in accordance with the current user preference.
+  }
+
+  /**
+    @see #getTarget()
+  */
+  public void setTarget(
+    TargetObject value
+    )
+  {
+    if(value == null)
+    {getBaseDataObject().remove(PdfName.T);}
+    else
+    {getBaseDataObject().put(PdfName.T, value.getBaseObject());}
+  }
+  // </public>
+  
+  // <protected>
+  @Override
+  protected Class<Destination> getDestinationClass() {
+    return Destination.class;
+  }
+  // </protected>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/GoToFirstPage.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/GoToFirstPage.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/GoToFirstPage.java	(revision 23703)
@@ -0,0 +1,84 @@
+/*
+  Copyright 2008-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.actions;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+/**
+  'Go to the first page of the document' action [PDF:1.6:8.5.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+  @since 0.0.7
+*/
+public class GoToFirstPage
+  extends NamedAction
+  implements IGoToAction
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  /**
+    Creates a new action within the given document context.
+  */
+  public GoToFirstPage(
+    Document context
+    )
+  {
+    super(
+      context,
+      PdfName.FirstPage
+      );
+  }
+
+  GoToFirstPage(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {
+    super(
+      baseObject,
+      container
+      );
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public GoToFirstPage clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/GoToLastPage.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/GoToLastPage.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/GoToLastPage.java	(revision 23703)
@@ -0,0 +1,84 @@
+/*
+  Copyright 2008-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.actions;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+/**
+  'Go to the last page of the document' action [PDF:1.6:8.5.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+  @since 0.0.7
+*/
+public class GoToLastPage
+  extends NamedAction
+  implements IGoToAction
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  /**
+    Creates a new action within the given document context.
+  */
+  public GoToLastPage(
+    Document context
+    )
+  {
+    super(
+      context,
+      PdfName.LastPage
+      );
+  }
+
+  GoToLastPage(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {
+    super(
+      baseObject,
+      container
+      );
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public GoToLastPage clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/GoToLocal.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/GoToLocal.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/GoToLocal.java	(revision 23703)
@@ -0,0 +1,93 @@
+/*
+  Copyright 2008-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.actions;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.interaction.navigation.document.LocalDestination;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+/**
+  'Change the view to a specified destination within the same PDF file' action [PDF:1.6:8.5.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+  @since 0.0.7
+*/
+public class GoToLocal
+  extends GoToDestination<LocalDestination>
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  /**
+    Creates a new action within the given document context.
+  */
+  public GoToLocal(
+    Document context,
+    LocalDestination destination
+    )
+  {
+    super(
+      context,
+      PdfName.GoTo,
+      destination
+      );
+  }
+
+  GoToLocal(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {
+    super(
+      baseObject,
+      container
+      );
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public GoToLocal clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+  // </public>
+  
+  // <protected>
+  @Override
+  protected Class<LocalDestination> getDestinationClass() {
+    return LocalDestination.class;
+  }
+  // </protected>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/GoToNextPage.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/GoToNextPage.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/GoToNextPage.java	(revision 23703)
@@ -0,0 +1,84 @@
+/*
+  Copyright 2008-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.actions;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+/**
+  'Go to the next page of the document' action [PDF:1.6:8.5.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+  @since 0.0.7
+*/
+public class GoToNextPage
+  extends NamedAction
+  implements IGoToAction
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  /**
+    Creates a new action within the given document context.
+  */
+  public GoToNextPage(
+    Document context
+    )
+  {
+    super(
+      context,
+      PdfName.NextPage
+      );
+  }
+
+  GoToNextPage(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {
+    super(
+      baseObject,
+      container
+      );
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public GoToNextPage clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/GoToNonLocal.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/GoToNonLocal.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/GoToNonLocal.java	(revision 23703)
@@ -0,0 +1,95 @@
+/*
+  Copyright 2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.actions;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.fileSpecs.FileSpec;
+import it.stefanochizzolini.clown.documents.interaction.navigation.document.Destination;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+
+/**
+  Abstract go-to-nonlocal-destination action.
+  
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+  @since 0.0.8
+*/
+public abstract class GoToNonLocal<T extends Destination>
+  extends GoToDestination<T>
+{
+  // <class>
+  // <constructors>
+  protected GoToNonLocal(
+    Document context,
+    PdfName actionType,
+    FileSpec fileSpec,
+    T destination
+    )
+  {
+    super(context,actionType,destination);
+    setFileSpec(fileSpec);
+  }
+
+  protected GoToNonLocal(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {super(baseObject,container);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  /**
+    Gets the file in which the destination is located.
+  */
+  public FileSpec getFileSpec(
+    )
+  {
+    PdfDirectObject fileSpecObject = getBaseDataObject().get(PdfName.F);
+    if(fileSpecObject == null)
+      return null;
+
+    return new FileSpec(fileSpecObject,getContainer(),null);
+  }
+  
+  /**
+    @see #getFileSpec()
+  */
+  public void setFileSpec(
+    FileSpec value
+    )
+  {
+    if(value == null)
+    {getBaseDataObject().remove(PdfName.F);}
+    else
+    {getBaseDataObject().put(PdfName.F, value.getBaseObject());}
+  }
+  // </public>
+  // </interface>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/GoToPreviousPage.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/GoToPreviousPage.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/GoToPreviousPage.java	(revision 23703)
@@ -0,0 +1,84 @@
+/*
+  Copyright 2008-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.actions;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+/**
+  'Go to the previous page of the document' action [PDF:1.6:8.5.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+  @since 0.0.7
+*/
+public class GoToPreviousPage
+  extends NamedAction
+  implements IGoToAction
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  /**
+    Creates a new action within the given document context.
+  */
+  public GoToPreviousPage(
+    Document context
+    )
+  {
+    super(
+      context,
+      PdfName.PrevPage
+      );
+  }
+
+  GoToPreviousPage(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {
+    super(
+      baseObject,
+      container
+      );
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public GoToPreviousPage clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/GoToRemote.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/GoToRemote.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/GoToRemote.java	(revision 23703)
@@ -0,0 +1,138 @@
+/*
+  Copyright 2008-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.actions;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.fileSpecs.FileSpec;
+import it.stefanochizzolini.clown.documents.interaction.navigation.document.RemoteDestination;
+import it.stefanochizzolini.clown.objects.PdfBoolean;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.util.EnumSet;
+
+/**
+  'Change the view to a specified destination in another PDF file' action [PDF:1.6:8.5.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+  @since 0.0.7
+*/
+public class GoToRemote
+  extends GoToNonLocal<RemoteDestination>
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  /**
+    Creates a new action within the given document context.
+  */
+  public GoToRemote(
+    Document context,
+    FileSpec fileSpec,
+    RemoteDestination destination
+    )
+  {
+    super(
+      context,
+      PdfName.GoToR,
+      fileSpec,
+      destination
+      );
+  }
+
+  GoToRemote(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {
+    super(
+      baseObject,
+      container
+      );
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public GoToRemote clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    Gets the action options.
+  */
+  public EnumSet<OptionsEnum> getOptions(
+    )
+  {
+    EnumSet<OptionsEnum> options = EnumSet.noneOf(OptionsEnum.class);
+
+    PdfDirectObject optionObject = getBaseDataObject().get(PdfName.NewWindow);
+    if(optionObject != null
+      && ((Boolean)((PdfBoolean)optionObject).getValue()).booleanValue())
+    {options.add(OptionsEnum.NewWindow);}
+
+    return options;
+  }
+
+  @Override
+  public void setFileSpec(FileSpec value) {
+    if(value == null)
+      throw new IllegalArgumentException("FileSpec cannot be null.");
+
+    super.setFileSpec(value);
+  }
+
+  /**
+    @see #getOptions()
+  */
+  public void setOptions(
+    EnumSet<OptionsEnum> value
+    )
+  {
+    if(value.contains(OptionsEnum.NewWindow))
+    {getBaseDataObject().put(PdfName.NewWindow,PdfBoolean.True);}
+    else if(value.contains(OptionsEnum.SameWindow))
+    {getBaseDataObject().put(PdfName.NewWindow,PdfBoolean.False);}
+    else
+    {getBaseDataObject().remove(PdfName.NewWindow);} // NOTE: Forcing the absence of this entry ensures that the viewer application should behave in accordance with the current user preference.
+  }
+  // </public>
+  
+  // <protected>
+  @Override
+  protected Class<RemoteDestination> getDestinationClass() {
+    return RemoteDestination.class;
+  }
+  // </protected>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/GoToThread.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/GoToThread.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/GoToThread.java	(revision 23703)
@@ -0,0 +1,84 @@
+/*
+  Copyright 2008-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.actions;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+/**
+  'Jump to a specified bead on an article thread' action [PDF:1.6:8.5.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.7
+  @version 0.0.8
+*/
+public class GoToThread
+  extends Action
+  implements IGoToAction
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  /**
+    Creates a new action within the given document context.
+  */
+  public GoToThread(
+    Document context
+    )
+  {
+    super(
+      context,
+      PdfName.Thread
+      );
+  }
+
+  GoToThread(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {
+    super(
+      baseObject,
+      container
+      );
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public GoToThread clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/GoToURI.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/GoToURI.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/GoToURI.java	(revision 23703)
@@ -0,0 +1,116 @@
+/*
+  Copyright 2008-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.actions;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfString;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.net.URI;
+
+/**
+  'Cause a URI (Uniform Resource Identifier) to be resolved' action [PDF:1.6:8.5.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.7
+  @version 0.0.8
+*/
+public class GoToURI
+  extends Action
+  implements IGoToAction
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  /**
+    Creates a new action within the given document context.
+  */
+  public GoToURI(
+    Document context,
+    URI uri
+    )
+  {
+    super(
+      context,
+      PdfName.URI
+      );
+    setURI(uri);
+  }
+
+  GoToURI(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {
+    super(
+      baseObject,
+      container
+      );
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public GoToURI clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    Gets the uniform resource identifier to resolve [RFC 2396].
+  */
+  public URI getURI(
+    )
+  {
+    /*
+      NOTE: 'URI' entry MUST exist.
+    */
+    try
+    {
+      return new URI(
+        (String)((PdfString)getBaseDataObject().get(PdfName.URI)).getValue()
+        );
+    }
+    catch(Exception exception)
+    {throw new RuntimeException(exception);}
+  }
+
+  /**
+    @see #getURI()
+  */
+  public void setURI(
+    URI value
+    )
+  {getBaseDataObject().put(PdfName.URI,new PdfString(value.toString()));}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/IGoToAction.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/IGoToAction.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/IGoToAction.java	(revision 23703)
@@ -0,0 +1,38 @@
+/*
+  Copyright 2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.actions;
+
+/**
+  Go-to action.
+  
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.8
+  @version 0.0.8
+*/
+public interface IGoToAction
+{
+
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/ImportData.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/ImportData.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/ImportData.java	(revision 23703)
@@ -0,0 +1,84 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.actions;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+/**
+  'Import FDF (Forms Data Format) data into the document's interactive form
+  from a specified file' action [PDF:1.6:8.6.4].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.7
+  @version 0.0.7
+*/
+public class ImportData
+  extends Action
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  /**
+    Creates a new action within the given document context.
+  */
+  public ImportData(
+    Document context
+    )
+  {
+    super(
+      context,
+      PdfName.ImportData
+      );
+  }
+
+  ImportData(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {
+    super(
+      baseObject,
+      container
+      );
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public ImportData clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/JavaScript.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/JavaScript.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/JavaScript.java	(revision 23703)
@@ -0,0 +1,127 @@
+/*
+  Copyright 2008-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.actions;
+
+import it.stefanochizzolini.clown.bytes.IBuffer;
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.objects.PdfDataObject;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfStream;
+import it.stefanochizzolini.clown.objects.PdfTextString;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+/**
+  'Cause a script to be compiled and executed by the JavaScript interpreter' action [PDF:1.6:8.6.4].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+  @since 0.0.7
+*/
+public class JavaScript
+  extends Action
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  /**
+    Creates a new action within the given document context.
+  */
+  public JavaScript(
+    Document context,
+    String script
+    )
+  {
+    super(
+      context,
+      PdfName.JavaScript
+      );
+
+    getBaseDataObject().put(PdfName.JS,new PdfTextString(script));
+  }
+
+  JavaScript(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {
+    super(
+      baseObject,
+      container
+      );
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public JavaScript clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  public String getScript(
+    )
+  {
+    /*
+      NOTE: 'JS' entry MUST be defined.
+    */
+    PdfDataObject scriptObject = getBaseDataObject().get(PdfName.JS);
+    if(scriptObject instanceof PdfTextString)
+    {return (String)((PdfTextString)scriptObject).getValue();}
+    else
+    {
+      IBuffer scriptBuffer = ((PdfStream)scriptObject).getBody();
+      return scriptBuffer.getString(0,(int)scriptBuffer.getLength());
+    }
+  }
+
+  /**
+    @see #getScript()
+  */
+  public void setScript(
+    String value
+    )
+  {
+    /*
+      NOTE: 'JS' entry MUST be defined.
+    */
+    PdfDataObject scriptObject = getBaseDataObject().get(PdfName.JS);
+    if(scriptObject instanceof PdfTextString)
+    {((PdfTextString)scriptObject).setValue(value);}
+    else
+    {
+      IBuffer scriptBuffer = ((PdfStream)scriptObject).getBody();
+      scriptBuffer.setLength(0);
+      scriptBuffer.append(value);
+    }
+  }
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/Launch.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/Launch.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/Launch.java	(revision 23703)
@@ -0,0 +1,396 @@
+/*
+  Copyright 2008-2009 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.actions;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.fileSpecs.FileSpec;
+import it.stefanochizzolini.clown.objects.PdfBoolean;
+import it.stefanochizzolini.clown.objects.PdfDictionary;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfObjectWrapper;
+import it.stefanochizzolini.clown.objects.PdfString;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.util.EnumSet;
+
+/**
+  'Launch an application' action [PDF:1.6:8.5.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+  @since 0.0.7
+*/
+public class Launch
+  extends Action
+{
+  // <class>
+  // <classes>
+  /**
+    Windows-specific launch parameters [PDF:1.6:8.5.3].
+  */
+  public static class WinParametersObject
+    extends PdfObjectWrapper<PdfDictionary>
+  {
+    // <class>
+    // <classes>
+    /**
+      Operation [PDF:1.6:8.5.3].
+    */
+    public enum OperationEnum
+    {
+      // <class>
+      // <static>
+      // <fields>
+      /**
+        Open.
+      */
+      Open(new PdfString("open")),
+      /**
+        Print.
+      */
+      Print(new PdfString("print"));
+      // </fields>
+
+      // <interface>
+      // <public>
+      /**
+        Gets the operation corresponding to the given value.
+      */
+      public static OperationEnum get(
+        PdfString value
+        )
+      {
+        for(OperationEnum operation : OperationEnum.values())
+        {
+          if(operation.getCode().equals(value))
+            return operation;
+        }
+        return null;
+      }
+      // </public>
+      // </interface>
+      // </static>
+
+      // <dynamic>
+      // <fields>
+      private final PdfString code;
+      // </fields>
+
+      // <constructors>
+      private OperationEnum(
+        PdfString code
+        )
+      {this.code = code;}
+      // </constructors>
+
+      // <interface>
+      // <public>
+      public PdfString getCode(
+        )
+      {return code;}
+      // </public>
+      // </interface>
+      // </dynamic>
+      // </class>
+    }
+    // </classes>
+
+    // <dynamic>
+    // <constructors>
+    public WinParametersObject(
+      Document context,
+      String fileName
+      )
+    {
+      super(
+        context.getFile(),
+        new PdfDictionary()
+        );
+
+      setFileName(fileName);
+    }
+
+    public WinParametersObject(
+      Document context,
+      String fileName,
+      OperationEnum operation
+      )
+    {
+      this(
+        context,
+        fileName
+        );
+
+      setOperation(operation);
+    }
+
+    public WinParametersObject(
+      Document context,
+      String fileName,
+      String parameterString
+      )
+    {
+      this(
+        context,
+        fileName
+        );
+
+      setParameterString(parameterString);
+    }
+
+    private WinParametersObject(
+      PdfDirectObject baseObject,
+      PdfIndirectObject container
+      )
+    {super(baseObject,container);}
+    // </constructors>
+
+    // <interface>
+    // <public>
+    @Override
+    public WinParametersObject clone(
+      Document context
+      )
+    {throw new NotImplementedException();}
+
+    /**
+      Gets the default directory.
+    */
+    public String getDefaultDirectory(
+      )
+    {
+      /*
+        NOTE: 'D' entry may be undefined.
+      */
+      PdfString defaultDirectoryObject = (PdfString)getBaseDataObject().get(PdfName.D);
+      if(defaultDirectoryObject == null)
+        return null;
+
+      return (String)defaultDirectoryObject.getValue();
+    }
+
+    /**
+      Gets the file name of the application to be launched or the document to be opened or printed.
+    */
+    public String getFileName(
+      )
+    {
+      /*
+        NOTE: 'F' entry MUST exist.
+      */
+      return (String)((PdfString)getBaseDataObject().get(PdfName.F)).getValue();
+    }
+
+    /**
+      Gets the operation to perform.
+    */
+    public OperationEnum getOperation(
+      )
+    {
+      /*
+        NOTE: 'O' entry may be undefined.
+      */
+      PdfString operationObject = (PdfString)getBaseDataObject().get(PdfName.O);
+      if(operationObject == null)
+        return OperationEnum.Open;
+
+      return OperationEnum.get(operationObject);
+    }
+
+    /**
+      Gets the parameter string to be passed to the application.
+    */
+    public String getParameterString(
+      )
+    {
+      /*
+        NOTE: 'P' entry may be undefined.
+      */
+      PdfString parameterStringObject = (PdfString)getBaseDataObject().get(PdfName.P);
+      if(parameterStringObject == null)
+        return null;
+
+      return (String)parameterStringObject.getValue();
+    }
+
+    /**
+      @see #getDefaultDirectory()
+    */
+    public void setDefaultDirectory(
+      String value
+      )
+    {getBaseDataObject().put(PdfName.D, new PdfString(value));}
+
+    /**
+      @see #getFileName()
+    */
+    public void setFileName(
+      String value
+      )
+    {getBaseDataObject().put(PdfName.F, new PdfString(value));}
+
+    /**
+      @see #getOperation()
+    */
+    public void setOperation(
+      OperationEnum value
+      )
+    {getBaseDataObject().put(PdfName.O, value.getCode());}
+
+    /**
+      @see #getParameterString()
+    */
+    public void setParameterString(
+      String value
+      )
+    {getBaseDataObject().put(PdfName.P, new PdfString(value));}
+    // </public>
+    // </interface>
+    // </dynamic>
+    // </class>
+  }
+  // </classes>
+
+  // <dynamic>
+  // <constructors>
+  /**
+    Creates a new action within the given document context.
+  */
+  public Launch(
+    Document context
+    )
+  {
+    super(
+      context,
+      PdfName.Launch
+      );
+  }
+
+  Launch(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {
+    super(
+      baseObject,
+      container
+      );
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public Launch clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    Gets the application to be launched or the document to be opened or printed.
+  */
+  public FileSpec getFileSpec(
+    )
+  {
+    /*
+      NOTE: 'F' entry may be undefined.
+    */
+    PdfDirectObject fileSpecObject = getBaseDataObject().get(PdfName.F);
+    if(fileSpecObject == null)
+      return null;
+
+    return new FileSpec(fileSpecObject,getContainer(),null);
+  }
+
+  /**
+    Gets the action options.
+  */
+  public EnumSet<OptionsEnum> getOptions(
+    )
+  {
+    EnumSet<OptionsEnum> options = EnumSet.noneOf(OptionsEnum.class);
+
+    PdfDirectObject optionObject = getBaseDataObject().get(PdfName.NewWindow);
+    if(optionObject != null
+      && ((Boolean)((PdfBoolean)optionObject).getValue()).booleanValue())
+    {options.add(OptionsEnum.NewWindow);}
+
+    return options;
+  }
+
+  /**
+    Gets the Windows-specific launch parameters.
+  */
+  public WinParametersObject getWinParameters(
+    )
+  {
+    /*
+      NOTE: 'Win' entry may be undefined.
+    */
+    PdfDictionary parametersObject = (PdfDictionary)getBaseDataObject().get(PdfName.Win);
+    if(parametersObject == null)
+      return null;
+
+    return new WinParametersObject(parametersObject,getContainer());
+  }
+
+  /**
+    @see #getFileSpec()
+  */
+  public void setFileSpec(
+    FileSpec value
+    )
+  {getBaseDataObject().put(PdfName.F, value.getBaseObject());}
+
+  /**
+    @see #getOptions()
+  */
+  public void setOptions(
+    EnumSet<OptionsEnum> value
+    )
+  {
+    if(value.contains(OptionsEnum.NewWindow))
+    {getBaseDataObject().put(PdfName.NewWindow,PdfBoolean.True);}
+    else if(value.contains(OptionsEnum.SameWindow))
+    {getBaseDataObject().put(PdfName.NewWindow,PdfBoolean.False);}
+    else
+    {getBaseDataObject().remove(PdfName.NewWindow);} // NOTE: Forcing the absence of this entry ensures that the viewer application should behave in accordance with the current user preference.
+  }
+
+  /**
+    @see #getWinParameters()
+  */
+  public void setWinParameters(
+    WinParametersObject value
+    )
+  {getBaseDataObject().put(PdfName.Win, value.getBaseObject());}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/NamedAction.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/NamedAction.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/NamedAction.java	(revision 23703)
@@ -0,0 +1,85 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.actions;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+/**
+  Named action [PDF:1.6:8.5.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.7
+  @since 0.0.7
+*/
+public class NamedAction
+  extends Action
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  /**
+    Creates a new action within the given document context.
+  */
+  public NamedAction(
+    Document context,
+    PdfName actionName
+    )
+  {
+    super(
+      context,
+      PdfName.Named
+      );
+    getBaseDataObject().put(PdfName.N,actionName);
+  }
+
+  NamedAction(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {
+    super(
+      baseObject,
+      container
+      );
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public NamedAction clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/OptionsEnum.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/OptionsEnum.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/OptionsEnum.java	(revision 23703)
@@ -0,0 +1,77 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.actions;
+
+/**
+  Action options.
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.7
+  @since 0.0.7
+*/
+public enum OptionsEnum
+{
+  // <class>
+  // <static>
+  // <fields>
+  /**
+    Whether to open the destination document in a new window.
+  */
+  NewWindow(0x1),
+  /**
+    Whether to open the destination document in the current window.
+  */
+  SameWindow(0x2);
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <fields>
+  /**
+    <h3>Remarks</h3>
+    <p>Bitwise code MUST be explicitly distinct from the ordinal position of the enum constant
+    as they don't coincide.</p>
+  */
+  private final int code;
+  // </fields>
+
+  // <constructors>
+  private OptionsEnum(
+    int code
+    )
+  {this.code = code;}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  public int getCode(
+    )
+  {return code;}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/PlayMovie.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/PlayMovie.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/PlayMovie.java	(revision 23703)
@@ -0,0 +1,115 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.actions;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.interaction.annotations.MovieAnnotation;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+/**
+  'Play a movie' action [PDF:1.6:8.5.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.7
+  @since 0.0.7
+*/
+public class PlayMovie
+  extends Action
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  /**
+    Creates a new action within the given document context.
+  */
+  public PlayMovie(
+    Document context,
+    MovieAnnotation movie
+    )
+  {
+    super(
+      context,
+      PdfName.Movie
+      );
+
+    setMovie(movie);
+  }
+
+  PlayMovie(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {super(baseObject,container);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public PlayMovie clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    Gets the movie to be played.
+  */
+  public MovieAnnotation getMovie(
+    )
+  {
+    /*
+      NOTE: Either 'Annotation' or 'T' entry MUST exist.
+    */
+    PdfDirectObject annotationObject = getBaseDataObject().get(PdfName.Annotation);
+    if(annotationObject == null)
+    {
+      annotationObject = getBaseDataObject().get(PdfName.T);
+
+      throw new NotImplementedException("No by-title movie annotation support currently: we have to implement a hook to the page of the referenced movie to get it from its annotations collection.");
+    }
+
+    return new MovieAnnotation(annotationObject,getContainer());
+  }
+
+  /**
+    @see #getMovie()
+  */
+  public void setMovie(
+    MovieAnnotation value
+    )
+  {
+    if(value == null)
+      throw new IllegalArgumentException("Movie MUST be defined.");
+
+    getBaseDataObject().put(PdfName.Annotation,value.getBaseObject());
+  }
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/PlaySound.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/PlaySound.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/PlaySound.java	(revision 23703)
@@ -0,0 +1,109 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.actions;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.multimedia.Sound;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+/**
+  'Play a sound' action [PDF:1.6:8.5.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.7
+  @since 0.0.7
+*/
+public class PlaySound
+  extends Action
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  /**
+    Creates a new action within the given document context.
+  */
+  public PlaySound(
+    Document context,
+    Sound sound
+    )
+  {
+    super(
+      context,
+      PdfName.Sound
+      );
+
+    setSound(sound);
+  }
+
+  PlaySound(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {super(baseObject,container);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public PlaySound clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    Gets the sound to be played.
+  */
+  public Sound getSound(
+    )
+  {
+    /*
+      NOTE: 'Sound' entry MUST exist.
+    */
+    return new Sound(
+      getBaseDataObject().get(PdfName.Sound)
+      );
+  }
+
+  /**
+    @see #getSound()
+  */
+  public void setSound(
+    Sound value
+    )
+  {
+    if(value == null)
+      throw new IllegalArgumentException("Sound MUST be defined.");
+
+    getBaseDataObject().put(PdfName.Sound,value.getBaseObject());
+  }
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/Rendition.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/Rendition.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/Rendition.java	(revision 23703)
@@ -0,0 +1,83 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.actions;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+/**
+  'Control the playing of multimedia content' action [PDF:1.6:8.5.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.7
+  @since 0.0.7
+*/
+public class Rendition
+  extends Action
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  /**
+    Creates a new action within the given document context.
+  */
+  public Rendition(
+    Document context
+    )
+  {
+    super(
+      context,
+      PdfName.Rendition
+      );
+  }
+
+  Rendition(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {
+    super(
+      baseObject,
+      container
+      );
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public Rendition clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/ResetForm.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/ResetForm.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/ResetForm.java	(revision 23703)
@@ -0,0 +1,83 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.actions;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+/**
+  'Reset selected interactive form fields to their default values' action [PDF:1.6:8.6.4].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.7
+  @since 0.0.7
+*/
+public class ResetForm
+  extends Action
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  /**
+    Creates a new action within the given document context.
+  */
+  public ResetForm(
+    Document context
+    )
+  {
+    super(
+      context,
+      PdfName.ResetForm
+      );
+  }
+
+  ResetForm(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {
+    super(
+      baseObject,
+      container
+      );
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public ResetForm clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/SetOcgState.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/SetOcgState.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/SetOcgState.java	(revision 23703)
@@ -0,0 +1,83 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.actions;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+/**
+  'Set the state of one or more optional content groups' action [PDF:1.6:8.5.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.7
+  @since 0.0.7
+*/
+public class SetOcgState
+  extends Action
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  /**
+    Creates a new action within the given document context.
+  */
+  public SetOcgState(
+    Document context
+    )
+  {
+    super(
+      context,
+      PdfName.SetOCGState
+      );
+  }
+
+  SetOcgState(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {
+    super(
+      baseObject,
+      container
+      );
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public SetOcgState clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/SubmitForm.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/SubmitForm.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/SubmitForm.java	(revision 23703)
@@ -0,0 +1,84 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.actions;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+/**
+  'Transmit the names and values of selected interactive form fields
+  to a specified URL (Uniform Resource Locator)' action [PDF:1.6:8.6.4].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.7
+  @since 0.0.7
+*/
+public class SubmitForm
+  extends Action
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  /**
+    Creates a new action within the given document context.
+  */
+  public SubmitForm(
+    Document context
+    )
+  {
+    super(
+      context,
+      PdfName.SubmitForm
+      );
+  }
+
+  SubmitForm(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {
+    super(
+      baseObject,
+      container
+      );
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public SubmitForm clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/ToggleVisibility.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/ToggleVisibility.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/ToggleVisibility.java	(revision 23703)
@@ -0,0 +1,202 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.actions;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.interaction.annotations.Annotation;
+import it.stefanochizzolini.clown.documents.interaction.forms.Field;
+import it.stefanochizzolini.clown.files.File;
+import it.stefanochizzolini.clown.objects.PdfArray;
+import it.stefanochizzolini.clown.objects.PdfBoolean;
+import it.stefanochizzolini.clown.objects.PdfDataObject;
+import it.stefanochizzolini.clown.objects.PdfDictionary;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfObjectWrapper;
+import it.stefanochizzolini.clown.objects.PdfReference;
+import it.stefanochizzolini.clown.objects.PdfTextString;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+/**
+  'Toggle the visibility of one or more annotations on the screen' action [PDF:1.6:8.5.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.7
+  @since 0.0.7
+*/
+public class ToggleVisibility
+  extends Action
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  /**
+    Creates a new action within the given document context.
+  */
+  public ToggleVisibility(
+    Document context,
+    Collection<PdfObjectWrapper<?>> objects,
+    boolean visible
+    )
+  {
+    super(
+      context,
+      PdfName.Hide
+      );
+
+    setObjects(objects);
+    setVisible(visible);
+  }
+
+  ToggleVisibility(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {
+    super(
+      baseObject,
+      container
+      );
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public ToggleVisibility clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    Gets the annotations (or associated form fields) to be affected.
+  */
+  public Collection<PdfObjectWrapper<?>> getObjects(
+    )
+  {
+    ArrayList<PdfObjectWrapper<?>> objects = new ArrayList<PdfObjectWrapper<?>>();
+
+    /*
+      NOTE: 'T' entry MUST exist.
+    */
+    PdfDirectObject objectsObject = getBaseDataObject().get(PdfName.T);
+    fillObjects(objectsObject,objects);
+
+    return objects;
+  }
+
+  /**
+    Gets whether to show the annotations.
+  */
+  public boolean isVisible(
+    )
+  {
+    /*
+      NOTE: 'H' entry may be undefined.
+    */
+    PdfBoolean hideObject = (PdfBoolean)getBaseDataObject().get(PdfName.H);
+    if(hideObject == null)
+      return false;
+
+    return !((Boolean)hideObject.getValue()).booleanValue();
+  }
+
+  /**
+    @see #getObjects()
+  */
+  public void setObjects(
+    Collection<PdfObjectWrapper<?>> value
+    )
+  {
+    PdfArray objectsDataObject = new PdfArray();
+    for(PdfObjectWrapper<?> item : value)
+    {
+      if(item instanceof Annotation)
+        objectsDataObject.add(
+          item.getBaseObject()
+          );
+      else if(item instanceof Field)
+        objectsDataObject.add(
+          new PdfTextString(((Field)item).getFullName())
+          );
+      else
+        throw new IllegalArgumentException(
+          "Invalid 'Hide' action target type (" + item.getClass().getName() + ").\n"
+            + "It MUST be either an annotation or a form field."
+          );
+    }
+    getBaseDataObject().put(PdfName.T, objectsDataObject);
+  }
+
+  /**
+    @see #isVisible()
+  */
+  public void setVisible(
+    boolean value
+    )
+  {getBaseDataObject().put(PdfName.H, new PdfBoolean(!value));}
+  // </public>
+
+  // <private>
+  private void fillObjects(
+    PdfDataObject objectObject,
+    Collection<PdfObjectWrapper<?>> objects
+    )
+  {
+    PdfDataObject objectDataObject = File.resolve(objectObject);
+    if(objectDataObject instanceof PdfArray) // Multiple objects.
+    {
+      for(PdfDirectObject itemObject : (PdfArray)objectDataObject)
+      {fillObjects(itemObject,objects);}
+    }
+    else // Single object.
+    {
+      if(objectDataObject instanceof PdfDictionary) // Annotation.
+        objects.add(
+          Annotation.wrap((PdfReference)objectObject)
+          );
+      else if(objectDataObject instanceof PdfTextString) // Form field (associated to widget annotations).
+        objects.add(
+          getDocument().getForm().getFields().get(
+            (String)((PdfTextString)objectDataObject).getValue()
+            )
+          );
+      else // Invalid object type.
+        throw new RuntimeException(
+          "Invalid 'Hide' action target type (" + objectDataObject.getClass().getName() + ").\n"
+            + "It should be either an annotation or a form field."
+          );
+    }
+  }
+  // </private>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/package.html
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/package.html	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/actions/package.html	(revision 23703)
@@ -0,0 +1,37 @@
+<html>
+<head>
+<!--
+  Copyright 2008-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+-->
+</head>
+<body>
+<p>Actions used to perform specific operations when triggered [PDF:1.6:8.5].</p>
+
+<h2>Related Documentation</h2>
+<p>For overviews, tutorials, examples, guides, and tool documentation, please see:</p>
+<ul>
+  <li><a href="http://clown.stefanochizzolini.it">PDF Clown Home Page</a>
+</ul>
+</body>
+</html>
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/Annotation.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/Annotation.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/Annotation.java	(revision 23703)
@@ -0,0 +1,658 @@
+/*
+  Copyright 2008-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.annotations;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.Page;
+import it.stefanochizzolini.clown.documents.interaction.actions.Action;
+import it.stefanochizzolini.clown.files.File;
+import it.stefanochizzolini.clown.objects.PdfArray;
+import it.stefanochizzolini.clown.objects.PdfDate;
+import it.stefanochizzolini.clown.objects.PdfDictionary;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfInteger;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfObjectWrapper;
+import it.stefanochizzolini.clown.objects.PdfReference;
+import it.stefanochizzolini.clown.objects.PdfTextString;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.awt.geom.Rectangle2D;
+import java.util.Date;
+import java.util.EnumSet;
+
+/**
+  Annotation [PDF:1.6:8.4].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+  @since 0.0.7
+*/
+public class Annotation
+  extends PdfObjectWrapper<PdfDictionary>
+{
+  // <class>
+  // <classes>
+  /**
+    Field flags [PDF:1.6:8.4.2].
+  */
+  public enum FlagsEnum
+  {
+    // <class>
+    // <static>
+    // <fields>
+    /**
+      Hide the annotation, both on screen and on print,
+      if it does not belong to one of the standard annotation types
+      and no annotation handler is available.
+    */
+    Invisible(0x1),
+    /**
+      Hide the annotation, both on screen and on print
+      (regardless of its annotation type or whether an annotation handler is available).
+    */
+    Hidden(0x2),
+    /**
+      Print the annotation when the page is printed.
+    */
+    Print(0x4),
+    /**
+      Do not scale the annotation's appearance to match the magnification of the page.
+    */
+    NoZoom(0x8),
+    /**
+      Do not rotate the annotation's appearance to match the rotation of the page.
+    */
+    NoRotate(0x10),
+    /**
+      Hide the annotation on the screen.
+    */
+    NoView(0x20),
+    /**
+      Do not allow the annotation to interact with the user.
+    */
+    ReadOnly(0x40),
+    /**
+      Do not allow the annotation to be deleted or its properties to be modified by the user.
+    */
+    Locked(0x80),
+    /**
+      Invert the interpretation of the NoView flag.
+    */
+    ToggleNoView(0x100);
+    // </fields>
+
+    // <interface>
+    // <public>
+    /**
+      Converts an enumeration set into its corresponding bit mask representation.
+    */
+    public static int toInt(
+      EnumSet<FlagsEnum> flags
+      )
+    {
+      int flagsMask = 0;
+      for(FlagsEnum flag : flags)
+      {flagsMask |= flag.getCode();}
+
+      return flagsMask;
+    }
+
+    /**
+      Converts a bit mask into its corresponding enumeration representation.
+    */
+    public static EnumSet<FlagsEnum> toEnumSet(
+      int flagsMask
+      )
+    {
+      EnumSet<FlagsEnum> flags = EnumSet.noneOf(FlagsEnum.class);
+      for(FlagsEnum flag : FlagsEnum.values())
+      {
+        if((flagsMask & flag.getCode()) > 0)
+        {flags.add(flag);}
+      }
+
+      return flags;
+    }
+    // </public>
+    // </interface>
+    // </static>
+
+    // <dynamic>
+    // <fields>
+    /**
+      <h3>Remarks</h3>
+      <p>Bitwise code MUST be explicitly distinct from the ordinal position of the enum constant
+      as they don't coincide.</p>
+    */
+    private final int code;
+    // </fields>
+
+    // <constructors>
+    private FlagsEnum(
+      int code
+      )
+    {this.code = code;}
+    // </constructors>
+
+    // <interface>
+    // <public>
+    public int getCode(
+      )
+    {return code;}
+    // </public>
+    // </interface>
+    // </dynamic>
+    // </class>
+  }
+  // </classes>
+
+  // <static>
+  // <fields>
+  // </fields>
+
+  // <interface>
+  // <public>
+  /**
+    Wraps an annotation reference into an annotation object.
+
+    @param reference Reference to an annotation object.
+    @return Annotation object associated to the reference.
+  */
+  public static final Annotation wrap(
+    PdfReference reference
+    )
+  {return wrap(reference,null);}
+
+  /**
+    Wraps an annotation base object into an annotation object.
+
+    @param baseObject Annotation base object.
+    @param container Annotation base object container.
+    @return Annotation object associated to the base object.
+  */
+  public static final Annotation wrap(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {
+    /*
+      NOTE: This is a factory method for any annotation-derived object.
+    */
+    if(baseObject == null)
+      return null;
+
+    PdfDictionary dataObject = (PdfDictionary)File.resolve(baseObject);
+    if(!dataObject.get(PdfName.Type).equals(PdfName.Annot))
+      return null;
+
+    PdfName annotationType = (PdfName)dataObject.get(PdfName.Subtype);
+    if(annotationType.equals(PdfName.Text))
+      return new Note(baseObject,container);
+    else if(annotationType.equals(PdfName.Link))
+      return new Link(baseObject,container);
+    else if(annotationType.equals(PdfName.FreeText))
+      return new CalloutNote(baseObject,container);
+    else if(annotationType.equals(PdfName.Line))
+      return new Line(baseObject,container);
+    else if(annotationType.equals(PdfName.Square))
+      return new Rectangle(baseObject,container);
+    else if(annotationType.equals(PdfName.Circle))
+      return new Ellipse(baseObject,container);
+    else if(annotationType.equals(PdfName.Polygon))
+      return new Polygon(baseObject,container);
+    else if(annotationType.equals(PdfName.PolyLine))
+      return new Polyline(baseObject,container);
+    else if(annotationType.equals(PdfName.Highlight)
+      || annotationType.equals(PdfName.Underline)
+      || annotationType.equals(PdfName.Squiggly)
+      || annotationType.equals(PdfName.StrikeOut))
+      return new TextMarkup(baseObject,container);
+    else if(annotationType.equals(PdfName.Stamp))
+      return new RubberStamp(baseObject,container);
+    else if(annotationType.equals(PdfName.Caret))
+      return new Caret(baseObject,container);
+    else if(annotationType.equals(PdfName.Ink))
+      return new Scribble(baseObject,container);
+    else if(annotationType.equals(PdfName.Popup))
+      return new Popup(baseObject,container);
+    else if(annotationType.equals(PdfName.FileAttachment))
+      return new FileAttachment(baseObject,container);
+    else if(annotationType.equals(PdfName.Sound))
+      return new SoundAnnotation(baseObject,container);
+    else if(annotationType.equals(PdfName.Movie))
+      return new MovieAnnotation(baseObject,container);
+    else if(annotationType.equals(PdfName.Widget))
+      return new Widget(baseObject,container);
+//TODO
+//     else if(annotationType.equals(PdfName.Screen)) return new Screen(baseObject,container);
+//     else if(annotationType.equals(PdfName.PrinterMark)) return new PrinterMark(baseObject,container);
+//     else if(annotationType.equals(PdfName.TrapNet)) return new TrapNet(baseObject,container);
+//     else if(annotationType.equals(PdfName.Watermark)) return new Watermark(baseObject,container);
+//     else if(annotationType.equals(PdfName.3DAnnotation)) return new 3DAnnotation(baseObject,container);
+    else // Other annotation type.
+      return new Annotation(baseObject,container);
+  }
+  // </public>
+  // </interface>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  protected Annotation(
+    Document context,
+    PdfName subtype,
+    Rectangle2D box,
+    Page page
+    )
+  {
+    super(
+      context.getFile(),
+      new PdfDictionary(
+        new PdfName[]
+        {
+          PdfName.Type,
+          PdfName.Subtype,
+          PdfName.P,
+          PdfName.Border
+        },
+        new PdfDirectObject[]
+        {
+          PdfName.Annot,
+          subtype,
+          page.getBaseObject(),
+          new PdfArray(new PdfDirectObject[]{new PdfInteger(0),new PdfInteger(0),new PdfInteger(0)}) // NOTE: Hide border by default.
+        }
+        )
+      );
+
+    {
+      setBox(box);
+
+      PdfArray pageAnnotsObject = (PdfArray)File.resolve(page.getBaseDataObject().get(PdfName.Annots));
+      if(pageAnnotsObject == null)
+      {page.getBaseDataObject().put(PdfName.Annots,pageAnnotsObject = new PdfArray());}
+      pageAnnotsObject.add(getBaseObject());
+    }
+  }
+
+  protected Annotation(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {super(baseObject,container);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public Annotation clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    Gets the action to be performed when the annotation is activated.
+
+    @since 0.0.8
+  */
+  public Action getAction(
+    )
+  {
+    /*
+      NOTE: 'A' entry may be undefined.
+    */
+    PdfDirectObject actionObject = getBaseDataObject().get(PdfName.A);
+    if(actionObject == null)
+      return null;
+
+    return Action.wrap(actionObject,getContainer());
+  }
+
+  /**
+    Gets the annotation's behavior in response to various trigger events.
+  */
+  public AnnotationActions getActions(
+    )
+  {
+    PdfDirectObject actionsObject = getBaseDataObject().get(PdfName.AA);
+    if(actionsObject == null)
+      return null;
+
+    return new AnnotationActions(this,actionsObject,getContainer());
+  }
+
+  /**
+    Gets the appearance specifying how the annotation is presented visually on the page.
+  */
+  public Appearance getAppearance(
+    )
+  {
+    /*
+      NOTE: 'AP' entry may be undefined.
+    */
+    PdfDirectObject appearanceObject = getBaseDataObject().get(PdfName.AP);
+    if(appearanceObject == null)
+      return null;
+
+    return new Appearance(appearanceObject,getContainer());
+  }
+
+  /**
+    Gets the border style.
+  */
+  public Border getBorder(
+    )
+  {
+    /*
+      NOTE: 'BS' entry may be undefined.
+    */
+    PdfDirectObject borderObject = getBaseDataObject().get(PdfName.BS);
+    if(borderObject == null)
+      return null;
+
+    return new Border(borderObject,getContainer());
+  }
+
+  /**
+    Gets the annotation rectangle.
+  */
+  public Rectangle2D getBox(
+    )
+  {
+    /*
+      NOTE: 'Rect' entry MUST be defined.
+    */
+    it.stefanochizzolini.clown.objects.Rectangle box = new it.stefanochizzolini.clown.objects.Rectangle(getBaseDataObject().get(PdfName.Rect));
+    return new Rectangle2D.Double(
+      box.getX(),
+      getPageHeight() - box.getY(),
+      box.getWidth(),
+      box.getHeight()
+      );
+  }
+
+  /**
+    Gets the annotation flags.
+  */
+  public EnumSet<FlagsEnum> getFlags(
+    )
+  {
+    PdfInteger flagsObject = (PdfInteger)getBaseDataObject().get(PdfName.F);
+    if(flagsObject == null)
+      return EnumSet.noneOf(FlagsEnum.class);
+
+    return FlagsEnum.toEnumSet(flagsObject.getRawValue());
+  }
+
+  /**
+    Gets the date and time when the annotation was most recently modified.
+  */
+  public Date getModificationDate(
+    )
+  {
+    /*
+      NOTE: 'M' entry may be undefined.
+    */
+    PdfDirectObject modificationDateObject = getBaseDataObject().get(PdfName.M);
+    if(modificationDateObject == null
+      || !(modificationDateObject instanceof PdfDate)) // NOTE: Non-well-formed dates are ignored.
+      return null;
+
+    return (Date)((PdfDate)modificationDateObject).getValue();
+  }
+
+  /**
+    Gets the annotation name.
+    <h3>Remarks</h3>
+    <p>The annotation name uniquely identifies the annotation among all the annotations on its page.</p>
+  */
+  public String getName(
+    )
+  {
+    /*
+      NOTE: 'NM' entry may be undefined.
+    */
+    PdfTextString nameObject = (PdfTextString)getBaseDataObject().get(PdfName.NM);
+    if(nameObject == null)
+      return null;
+
+    return (String)nameObject.getValue();
+  }
+
+  /**
+    Gets the associated page.
+  */
+  public Page getPage(
+    )
+  {
+    /*
+      NOTE: 'P' entry may be undefined.
+    */
+    PdfDirectObject pageObject = getBaseDataObject().get(PdfName.P);
+    if(pageObject == null)
+      return null;
+
+    return new Page(pageObject);
+  }
+
+  /**
+    Gets the annotation text.
+    <h3>Remarks</h3>
+    <p>Depending on the annotation type, the text may be either directly displayed
+    or (in case of non-textual annotations) used as alternate description.</p>
+  */
+  public String getText(
+    )
+  {
+    /*
+      NOTE: 'Contents' entry may be undefined.
+    */
+    PdfTextString textObject = (PdfTextString)getBaseDataObject().get(PdfName.Contents);
+    if(textObject == null)
+      return null;
+
+    return (String)textObject.getValue();
+  }
+
+  /**
+    Gets whether to print the annotation when the page is printed.
+  */
+  public boolean isPrintable(
+    )
+  {return getFlags().contains(FlagsEnum.Print);}
+
+  /**
+    Gets whether the annotation is visible.
+  */
+  public boolean isVisible(
+    )
+  {return !getFlags().contains(FlagsEnum.Hidden);}
+
+  /**
+    @see #getAction()
+  */
+  public void setAction(
+    Action value
+    )
+  {
+    if(value == null)
+    {getBaseDataObject().remove(PdfName.A);}
+    else
+    {getBaseDataObject().put(PdfName.A,value.getBaseObject());}
+  }
+
+  /**
+    @see #getActions()
+  */
+  public void setActions(
+    AnnotationActions value
+    )
+  {
+    if(value == null)
+    {getBaseDataObject().remove(PdfName.AA);}
+    else
+    {getBaseDataObject().put(PdfName.AA,value.getBaseObject());}
+  }
+
+  /**
+    @see #getAppearance()
+  */
+  public void setAppearance(
+    Appearance value
+    )
+  {
+    if(value == null)
+    {getBaseDataObject().remove(PdfName.AP);}
+    else
+    {getBaseDataObject().put(PdfName.AP, value.getBaseObject());}
+  }
+
+  /**
+    @see #getBorder()
+  */
+  public void setBorder(
+    Border value
+    )
+  {
+    if(value == null)
+    {getBaseDataObject().remove(PdfName.BS);}
+    else
+    {
+      getBaseDataObject().put(PdfName.BS, value.getBaseObject());
+      getBaseDataObject().remove(PdfName.Border);
+    }
+  }
+
+  /**
+    @see #getBox()
+  */
+  public void setBox(
+    Rectangle2D value
+    )
+  {
+    getBaseDataObject().put(
+      PdfName.Rect,
+      new it.stefanochizzolini.clown.objects.Rectangle(
+        value.getX(),
+        getPageHeight() - value.getY(),
+        value.getWidth(),
+        value.getHeight()
+        ).getBaseDataObject()
+      );
+  }
+
+  /**
+    @see #getFlags()
+  */
+  public void setFlags(
+    EnumSet<FlagsEnum> value
+    )
+  {getBaseDataObject().put(PdfName.F, new PdfInteger(FlagsEnum.toInt(value)));}
+
+  /**
+    @see #getModificationDate()
+  */
+  public void setModificationDate(
+    Date value
+    )
+  {getBaseDataObject().put(PdfName.M, new PdfDate(value));}
+
+  /**
+    @see #getName()
+  */
+  public void setName(
+    String value
+    )
+  {getBaseDataObject().put(PdfName.NM, new PdfTextString(value));}
+
+  /**
+    @see #getPage()
+  */
+  public void setPage(
+    Page value
+    )
+  {getBaseDataObject().put(PdfName.P, value.getBaseObject());}
+
+  /**
+    @see #isPrintable()
+  */
+  public void setPrintable(
+    boolean value
+    )
+  {
+    EnumSet<FlagsEnum> flags = getFlags();
+    if(value)
+    {flags.add(FlagsEnum.Print);}
+    else
+    {flags.remove(FlagsEnum.Print);}
+    setFlags(flags);
+  }
+
+  /**
+    @see #getText()
+  */
+  public void setText(
+    String value
+    )
+  {
+    if(value == null)
+    {getBaseDataObject().remove(PdfName.Contents);}
+    else
+    {getBaseDataObject().put(PdfName.Contents, new PdfTextString(value));}
+  }
+
+  /**
+    @see #isVisible()
+  */
+  public void setVisible(
+    boolean value
+    )
+  {
+    EnumSet<FlagsEnum> flags = getFlags();
+    if(value)
+    {flags.remove(FlagsEnum.Hidden);}
+    else
+    {flags.add(FlagsEnum.Hidden);}
+    setFlags(flags);
+  }
+  // </public>
+
+  // <private>
+  private double getPageHeight(
+    )
+  {
+    Page page = getPage();
+    return (page != null
+        ? page.getBox().getHeight()
+        : getDocument().getSize().getHeight());
+  }
+  // </private>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/AnnotationActions.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/AnnotationActions.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/AnnotationActions.java	(revision 23703)
@@ -0,0 +1,420 @@
+/*
+  Copyright 2008-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.annotations;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.interaction.actions.Action;
+import it.stefanochizzolini.clown.objects.PdfDictionary;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfObjectWrapper;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+  Annotation actions [PDF:1.6:8.5.2].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+  @since 0.0.7
+*/
+public class AnnotationActions
+  extends PdfObjectWrapper<PdfDictionary>
+  implements Map<PdfName,Action>
+{
+  // <class>
+  // <dynamic>
+  // <fields>
+  private Annotation parent;
+  // </fields>
+
+  // <constructors>
+  public AnnotationActions(
+    Annotation parent
+    )
+  {
+    super(
+      parent.getFile(),
+      new PdfDictionary()
+      );
+
+    this.parent = parent;
+  }
+
+  public AnnotationActions(
+    Annotation parent,
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {
+    super(baseObject,container);
+
+    this.parent = parent;
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public AnnotationActions clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    Gets the action to be performed when the annotation is activated.
+  */
+  public Action getOnActivate(
+    )
+  {return parent.getAction();}
+
+  /**
+    Gets the action to be performed when the cursor enters the annotation's active area.
+  */
+  public Action getOnEnter(
+    )
+  {
+    /*
+      NOTE: 'E' entry may be undefined.
+    */
+    PdfDirectObject onEnterObject = getBaseDataObject().get(PdfName.E);
+    if(onEnterObject == null)
+      return null;
+
+    return Action.wrap(onEnterObject,getContainer());
+  }
+
+  /**
+    Gets the action to be performed when the cursor exits the annotation's active area.
+  */
+  public Action getOnExit(
+    )
+  {
+    /*
+      NOTE: 'X' entry may be undefined.
+    */
+    PdfDirectObject onExitObject = getBaseDataObject().get(PdfName.X);
+    if(onExitObject == null)
+      return null;
+
+    return Action.wrap(onExitObject,getContainer());
+  }
+
+  /**
+    Gets the action to be performed when the mouse button is pressed
+    inside the annotation's active area.
+  */
+  public Action getOnMouseDown(
+    )
+  {
+    /*
+      NOTE: 'D' entry may be undefined.
+    */
+    PdfDirectObject onMouseDownObject = getBaseDataObject().get(PdfName.D);
+    if(onMouseDownObject == null)
+      return null;
+
+    return Action.wrap(onMouseDownObject,getContainer());
+  }
+
+  /**
+    Gets the action to be performed when the mouse button is released
+    inside the annotation's active area.
+  */
+  public Action getOnMouseUp(
+    )
+  {
+    /*
+      NOTE: 'U' entry may be undefined.
+    */
+    PdfDirectObject onMouseUpObject = getBaseDataObject().get(PdfName.U);
+    if(onMouseUpObject == null)
+      return null;
+
+    return Action.wrap(onMouseUpObject,getContainer());
+  }
+
+  /**
+    Gets the action to be performed when the page containing the annotation is closed.
+  */
+  public Action getOnPageClose(
+    )
+  {
+    /*
+      NOTE: 'PC' entry may be undefined.
+    */
+    PdfDirectObject onPageCloseObject = getBaseDataObject().get(PdfName.PC);
+    if(onPageCloseObject == null)
+      return null;
+
+    return Action.wrap(onPageCloseObject,getContainer());
+  }
+
+  /**
+    Gets the action to be performed when the page containing the annotation
+    is no longer visible in the viewer application's user interface.
+  */
+  public Action getOnPageInvisible(
+    )
+  {
+    /*
+      NOTE: 'PI' entry may be undefined.
+    */
+    PdfDirectObject onPageInvisibleObject = getBaseDataObject().get(PdfName.PI);
+    if(onPageInvisibleObject == null)
+      return null;
+
+    return Action.wrap(onPageInvisibleObject,getContainer());
+  }
+
+  /**
+    Gets the action to be performed when the page containing the annotation is opened.
+  */
+  public Action getOnPageOpen(
+    )
+  {
+    /*
+      NOTE: 'PO' entry may be undefined.
+    */
+    PdfDirectObject onPageOpenObject = getBaseDataObject().get(PdfName.PO);
+    if(onPageOpenObject == null)
+      return null;
+
+    return Action.wrap(onPageOpenObject,getContainer());
+  }
+
+  /**
+    Gets the action to be performed when the page containing the annotation
+    becomes visible in the viewer application's user interface.
+  */
+  public Action getOnPageVisible(
+    )
+  {
+    /*
+      NOTE: 'PV' entry may be undefined.
+    */
+    PdfDirectObject onPageVisibleObject = getBaseDataObject().get(PdfName.PV);
+    if(onPageVisibleObject == null)
+      return null;
+
+    return Action.wrap(onPageVisibleObject,getContainer());
+  }
+
+  /**
+    @see #getOnActivate()
+  */
+  public void setOnActivate(
+    Action value
+    )
+  {parent.setAction(value); parent.update();}
+
+  /**
+    @see #getOnEnter()
+  */
+  public void setOnEnter(
+    Action value
+    )
+  {getBaseDataObject().put(PdfName.E, value.getBaseObject());}
+
+  /**
+    @see #getOnExit()
+  */
+  public void setOnExit(
+    Action value
+    )
+  {getBaseDataObject().put(PdfName.X, value.getBaseObject());}
+
+  /**
+    @see #getOnMouseDown()
+  */
+  public void setOnMouseDown(
+    Action value
+    )
+  {getBaseDataObject().put(PdfName.D, value.getBaseObject());}
+
+  /**
+    @see #getOnMouseUp()
+  */
+  public void setOnMouseUp(
+    Action value
+    )
+  {getBaseDataObject().put(PdfName.U, value.getBaseObject());}
+
+  /**
+    @see #getOnPageClose()
+  */
+  public void setOnPageClose(
+    Action value
+    )
+  {getBaseDataObject().put(PdfName.PC, value.getBaseObject());}
+
+  /**
+    @see #getOnPageInvisible()
+  */
+  public void setOnPageInvisible(
+    Action value
+    )
+  {getBaseDataObject().put(PdfName.PI, value.getBaseObject());}
+
+  /**
+    @see #getOnPageOpen()
+  */
+  public void setOnPageOpen(
+    Action value
+    )
+  {getBaseDataObject().put(PdfName.PO, value.getBaseObject());}
+
+  /**
+    @see #getOnPageVisible()
+  */
+  public void setOnPageVisible(
+    Action value
+    )
+  {getBaseDataObject().put(PdfName.PV, value.getBaseObject());}
+
+  // <Map>
+  public void clear(
+    )
+  {
+    getBaseDataObject().clear();
+    setOnActivate(null);
+  }
+
+  public boolean containsKey(
+    Object key
+    )
+  {
+    return getBaseDataObject().containsKey(key)
+      || (PdfName.A.equals(key) && parent.getBaseDataObject().containsKey(key));
+  }
+
+  public boolean containsValue(
+    Object value
+    )
+  {
+    return value != null
+      && (getBaseDataObject().containsValue(((Action)value).getBaseObject())
+        || (value.equals(getOnActivate())));
+  }
+
+  public Set<java.util.Map.Entry<PdfName, Action>> entrySet(
+    )
+  {throw new NotImplementedException();}
+
+  public Action get(
+    Object key
+    )
+  {
+    return Action.wrap(
+      getBaseDataObject().get(key),
+      getContainer()
+      );
+  }
+
+  public boolean isEmpty(
+    )
+  {return getBaseDataObject().isEmpty() && getOnActivate() == null;}
+
+  public Set<PdfName> keySet(
+    )
+  {
+    HashSet<PdfName> keySet = new HashSet<PdfName>(getBaseDataObject().keySet());
+    if(parent.getBaseDataObject().containsKey(PdfName.A))
+    {keySet.add(PdfName.A);}
+
+    return keySet();
+  }
+
+  public Action put(
+    PdfName key,
+    Action value
+    )
+  {
+    return Action.wrap(
+      value == null
+        ? getBaseDataObject().remove(key)
+        : getBaseDataObject().put(key,value.getBaseObject()),
+      getContainer()
+      );
+  }
+
+  public void putAll(
+    Map<? extends PdfName, ? extends Action> entries
+    )
+  {throw new NotImplementedException();}
+
+  public Action remove(
+    Object key
+    )
+  {
+    Action oldValue;
+    if(PdfName.A.equals(key))
+    {
+      oldValue = getOnActivate();
+      setOnActivate(null);
+    }
+    else
+    {
+      oldValue = Action.wrap(
+        getBaseDataObject().remove(key),
+        getContainer()
+        );
+    }
+    return oldValue;
+  }
+
+  public int size(
+    )
+  {
+    return getBaseDataObject().size()
+      + (parent.getBaseDataObject().containsKey(PdfName.A) ? 1 : 0);
+  }
+
+  public Collection<Action> values(
+    )
+  {
+    Collection<PdfDirectObject> objects = getBaseDataObject().values();
+    Collection<Action> values = new ArrayList<Action>(objects.size());
+    for(PdfDirectObject object : objects)
+    {values.add(Action.wrap(object,getContainer()));}
+    Action action = getOnActivate();
+    if(action != null)
+    {values.add(action);}
+
+    return values;
+  }
+  // </Map>
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/Appearance.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/Appearance.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/Appearance.java	(revision 23703)
@@ -0,0 +1,127 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.annotations;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.objects.PdfDictionary;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfObjectWrapper;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+/**
+  Appearance [PDF:1.6:8.4.4].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.7
+  @version 0.0.7
+*/
+public class Appearance
+  extends PdfObjectWrapper<PdfDictionary>
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  public Appearance(
+    Document context
+    )
+  {
+    super(
+      context.getFile(),
+      new PdfDictionary()
+      );
+  }
+
+  public Appearance(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {super(baseObject,container);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public Appearance clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    Gets the annotation's down appearance.
+  */
+  public AppearanceStates getDown(
+    )
+  {
+    /*
+      NOTE: 'D' entry may be undefined;
+      nonetheless, since it always has a default value, it is always exposed.
+    */
+    return new AppearanceStates(
+      PdfName.D,
+      getContainer(),//TODO:verify container/baseobject/this
+      this
+      );
+  }
+
+  /**
+    Gets the annotation's normal appearance.
+  */
+  public AppearanceStates getNormal(
+    )
+  {
+    /*
+      NOTE: 'N' entry is required.
+    */
+    return new AppearanceStates(
+      PdfName.N,
+      getContainer(),//TODO:verify container/baseobject/this
+      this
+      );
+  }
+
+  /**
+    Gets the annotation's rollover appearance.
+  */
+  public AppearanceStates getRollover(
+    )
+  {
+    /*
+      NOTE: 'R' entry may be undefined;
+      nonetheless, since it always has a default value, it is always exposed.
+    */
+    return new AppearanceStates(
+      PdfName.R,
+      getContainer(),//TODO:verify container/baseobject/this
+      this
+      );
+  }
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/AppearanceCharacteristics.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/AppearanceCharacteristics.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/AppearanceCharacteristics.java	(revision 23703)
@@ -0,0 +1,937 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.annotations;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.contents.colorSpaces.Color;
+import it.stefanochizzolini.clown.documents.contents.colorSpaces.DeviceCMYKColor;
+import it.stefanochizzolini.clown.documents.contents.colorSpaces.DeviceGrayColor;
+import it.stefanochizzolini.clown.documents.contents.colorSpaces.DeviceRGBColor;
+import it.stefanochizzolini.clown.documents.contents.composition.AlignmentXEnum;
+import it.stefanochizzolini.clown.documents.contents.composition.AlignmentYEnum;
+import it.stefanochizzolini.clown.documents.contents.xObjects.FormXObject;
+import it.stefanochizzolini.clown.objects.IPdfNumber;
+import it.stefanochizzolini.clown.objects.PdfArray;
+import it.stefanochizzolini.clown.objects.PdfBoolean;
+import it.stefanochizzolini.clown.objects.PdfDictionary;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfInteger;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfObjectWrapper;
+import it.stefanochizzolini.clown.objects.PdfReal;
+import it.stefanochizzolini.clown.objects.PdfReference;
+import it.stefanochizzolini.clown.objects.PdfTextString;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+/**
+  Appearance characteristics [PDF:1.6:8.4.5].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.7
+  @since 0.0.7
+*/
+public class AppearanceCharacteristics
+  extends PdfObjectWrapper<PdfDictionary>
+{
+  // <class>
+  // <classes>
+  /**
+    Caption position relative to its icon [PDF:1.6:8.4.5].
+  */
+  public enum CaptionPositionEnum
+  {
+    // <class>
+    // <static>
+    // <fields>
+    /**
+      Caption only (no icon).
+    */
+    CaptionOnly(0),
+    /**
+      No caption (icon only).
+    */
+    NoCaption(1),
+    /**
+      Caption below the icon.
+    */
+    Below(2),
+    /**
+      Caption above the icon.
+    */
+    Above(3),
+    /**
+      Caption to the right of the icon.
+    */
+    Right(4),
+    /**
+      Caption to the left of the icon.
+    */
+    Left(5),
+    /**
+      Caption overlaid directly on the icon.
+    */
+    Overlaid(6);
+    // </fields>
+
+    // <interface>
+    // <public>
+    /**
+      Gets the caption position corresponding to the given value.
+    */
+    public static CaptionPositionEnum get(
+      int value
+      )
+    {
+      for(CaptionPositionEnum position : CaptionPositionEnum.values())
+      {
+        if(position.getCode() == value)
+          return position;
+      }
+      return null;
+    }
+    // </public>
+    // </interface>
+    // </static>
+
+    // <dynamic>
+    // <fields>
+    private final int code;
+    // </fields>
+
+    // <constructors>
+    private CaptionPositionEnum(
+      int code
+      )
+    {this.code = code;}
+    // </constructors>
+
+    // <interface>
+    // <public>
+    public int getCode(
+      )
+    {return code;}
+    // </public>
+    // </interface>
+    // </dynamic>
+    // </class>
+  }
+
+  /**
+    Icon fit [PDF:1.6:8.6.6].
+  */
+  public static class IconFitObject
+    extends PdfObjectWrapper<PdfDictionary>
+  {
+    // <class>
+    // <classes>
+    /**
+      Scaling mode [PDF:1.6:8.6.6].
+    */
+    public enum ScaleModeEnum
+    {
+      // <class>
+      // <static>
+      // <fields>
+      /**
+        Always scale.
+      */
+      Always(PdfName.A),
+      /**
+        Scale only when the icon is bigger than the annotation box.
+      */
+      Bigger(PdfName.B),
+      /**
+        Scale only when the icon is smaller than the annotation box.
+      */
+      Smaller(PdfName.S),
+      /**
+        Never scale.
+      */
+      Never(PdfName.N);
+      // </fields>
+
+      // <interface>
+      // <public>
+      /**
+        Gets the scaling mode corresponding to the given value.
+      */
+      public static ScaleModeEnum get(
+        PdfName value
+        )
+      {
+        for(ScaleModeEnum mode : ScaleModeEnum.values())
+        {
+          if(mode.getCode().equals(value))
+            return mode;
+        }
+        return null;
+      }
+      // </public>
+      // </interface>
+      // </static>
+
+      // <dynamic>
+      // <fields>
+      private final PdfName code;
+      // </fields>
+
+      // <constructors>
+      private ScaleModeEnum(
+        PdfName code
+        )
+      {this.code = code;}
+      // </constructors>
+
+      // <interface>
+      // <public>
+      public PdfName getCode(
+        )
+      {return code;}
+      // </public>
+      // </interface>
+      // </dynamic>
+      // </class>
+    }
+
+    /**
+      Scaling type [PDF:1.6:8.6.6].
+    */
+    public enum ScaleTypeEnum
+    {
+      // <class>
+      // <static>
+      // <fields>
+      /**
+        Scale the icon to fill the annotation box exactly,
+        without regard to its original aspect ratio.
+      */
+      Anamorphic(PdfName.A),
+      /**
+        Scale the icon to fit the width or height of the annotation box,
+        while maintaining the icon's original aspect ratio.
+      */
+      Proportional(PdfName.P);
+      // </fields>
+
+      // <interface>
+      // <public>
+      /**
+        Gets the scaling type corresponding to the given value.
+      */
+      public static ScaleTypeEnum get(
+        PdfName value
+        )
+      {
+        for(ScaleTypeEnum mode : ScaleTypeEnum.values())
+        {
+          if(mode.getCode().equals(value))
+            return mode;
+        }
+        return null;
+      }
+      // </public>
+      // </interface>
+      // </static>
+
+      // <dynamic>
+      // <fields>
+      private final PdfName code;
+      // </fields>
+
+      // <constructors>
+      private ScaleTypeEnum(
+        PdfName code
+        )
+      {this.code = code;}
+      // </constructors>
+
+      // <interface>
+      // <public>
+      public PdfName getCode(
+        )
+      {return code;}
+      // </public>
+      // </interface>
+      // </dynamic>
+      // </class>
+    }
+    // </classes>
+
+    // <dynamic>
+    // <constructors>
+    public IconFitObject(
+      Document context
+      )
+    {
+      super(
+        context.getFile(),
+        new PdfDictionary()
+        );
+    }
+
+    public IconFitObject(
+      PdfDirectObject baseObject,
+      PdfIndirectObject container
+      )
+    {super(baseObject,container);}
+    // </constructors>
+
+    // <interface>
+    // <public>
+    @Override
+    public IconFitObject clone(
+      Document context
+      )
+    {throw new NotImplementedException();}
+
+    /**
+      Gets the horizontal alignment of the icon inside the annotation box.
+    */
+    public AlignmentXEnum getAlignmentX(
+      )
+    {
+      /*
+        NOTE: 'A' entry may be undefined.
+      */
+      PdfArray alignmentObject = (PdfArray)getBaseDataObject().get(PdfName.A);
+      if(alignmentObject == null)
+        return AlignmentXEnum.Center;
+
+      switch((int)Math.round(((IPdfNumber)alignmentObject.get(0)).getNumberValue()/.5))
+      {
+        case 0: return AlignmentXEnum.Left;
+        case 2: return AlignmentXEnum.Right;
+        default: return AlignmentXEnum.Center;
+      }
+    }
+
+    /**
+      Gets the vertical alignment of the icon inside the annotation box.
+    */
+    public AlignmentYEnum getAlignmentY(
+      )
+    {
+      /*
+        NOTE: 'A' entry may be undefined.
+      */
+      PdfArray alignmentObject = (PdfArray)getBaseDataObject().get(PdfName.A);
+      if(alignmentObject == null)
+        return AlignmentYEnum.Middle;
+
+      switch((int)Math.round(((IPdfNumber)alignmentObject.get(1)).getNumberValue()/.5))
+      {
+        case 0: return AlignmentYEnum.Bottom;
+        case 2: return AlignmentYEnum.Top;
+        default: return AlignmentYEnum.Middle;
+      }
+    }
+
+    /**
+      Gets the circumstances under which the icon should be scaled inside the annotation box.
+    */
+    public ScaleModeEnum getScaleMode(
+      )
+    {
+      /*
+        NOTE: 'SW' entry may be undefined.
+      */
+      PdfName scaleModeObject = (PdfName)getBaseDataObject().get(PdfName.SW);
+      if(scaleModeObject == null)
+        return ScaleModeEnum.Always;
+
+      return ScaleModeEnum.get(scaleModeObject);
+    }
+
+    /**
+      Gets the type of scaling to use.
+    */
+    public ScaleTypeEnum getScaleType(
+      )
+    {
+      /*
+        NOTE: 'S' entry may be undefined.
+      */
+      PdfName scaleTypeObject = (PdfName)getBaseDataObject().get(PdfName.S);
+      if(scaleTypeObject == null)
+        return ScaleTypeEnum.Proportional;
+
+      return ScaleTypeEnum.get(scaleTypeObject);
+    }
+
+    /**
+      Gets whether not to take into consideration the line width of the border.
+    */
+    public boolean isBorderExcluded(
+      )
+    {
+      /*
+        NOTE: 'FB' entry may be undefined.
+      */
+      PdfBoolean borderExcludedObject = (PdfBoolean)getBaseDataObject().get(PdfName.FB);
+      if(borderExcludedObject == null)
+        return false;
+
+      return ((Boolean)borderExcludedObject.getValue()).booleanValue();
+    }
+
+    /**
+      Sets the horizontal alignment of the icon inside the annotation box.
+
+      @see #getAlignmentX()
+    */
+    public void setAlignmentX(
+      AlignmentXEnum value
+      )
+    {
+      /*
+        NOTE: 'A' entry may be undefined.
+      */
+      PdfArray alignmentObject = (PdfArray)getBaseDataObject().get(PdfName.A);
+      if(alignmentObject == null)
+      {
+        alignmentObject = new PdfArray(
+          new PdfDirectObject[]
+          {
+            new PdfReal(0.5),
+            new PdfReal(0.5)
+          }
+          );
+        getBaseDataObject().put(PdfName.A, alignmentObject);
+      }
+
+      float objectValue;
+      switch(value)
+      {
+        case Left: objectValue = 0; break;
+        case Right: objectValue = 1; break;
+        default: objectValue = 0.5f; break;
+      }
+      ((IPdfNumber)alignmentObject.get(0)).setNumberValue(objectValue);
+    }
+
+    /**
+      Sets the vertical alignment of the icon inside the annotation box.
+
+      @see #getAlignmentY()
+    */
+    public void setAlignmentY(
+      AlignmentYEnum value
+      )
+    {
+      /*
+        NOTE: 'A' entry may be undefined.
+      */
+      PdfArray alignmentObject = (PdfArray)getBaseDataObject().get(PdfName.A);
+      if(alignmentObject == null)
+      {
+        alignmentObject = new PdfArray(
+          new PdfDirectObject[]
+          {
+            new PdfReal(0.5),
+            new PdfReal(0.5)
+          }
+          );
+        getBaseDataObject().put(PdfName.A, alignmentObject);
+      }
+
+      float objectValue;
+      switch(value)
+      {
+        case Bottom: objectValue = 0; break;
+        case Top: objectValue = 1; break;
+        default: objectValue = 0.5f; break;
+      }
+      ((IPdfNumber)alignmentObject.get(1)).setNumberValue(objectValue);
+    }
+
+    /**
+      Sets whether not to take into consideration the line width of the border.
+
+      @see #isBorderExcluded()
+    */
+    public void setBorderExcluded(
+      boolean value
+      )
+    {getBaseDataObject().put(PdfName.FB, new PdfBoolean(value));}
+
+    /**
+      Sets the circumstances under which the icon should be scaled inside the annotation box.
+
+      @see #getScaleMode()
+    */
+    public void setScaleMode(
+      ScaleModeEnum value
+      )
+    {getBaseDataObject().put(PdfName.SW, value.getCode());}
+
+    /**
+      Sets the type of scaling to use.
+
+      @see #getScaleType()
+    */
+    public void setScaleType(
+      ScaleTypeEnum value
+      )
+    {getBaseDataObject().put(PdfName.S, value.getCode());}
+    // </public>
+    // </interface>
+    // </class>
+  }
+
+  /**
+    Annotation orientation [PDF:1.6:8.4.5].
+  */
+  public enum OrientationEnum
+  {
+    // <class>
+    // <static>
+    // <fields>
+    /**
+      Upward.
+    */
+    Up(0),
+    /**
+      Leftward.
+    */
+    Left(90),
+    /**
+      Downward.
+    */
+    Down(180),
+    /**
+      Rightward.
+    */
+    Right(270);
+    // </fields>
+
+    // <interface>
+    // <public>
+    /**
+      Gets the orientation corresponding to the given value.
+    */
+    public static OrientationEnum get(
+      int value
+      )
+    {
+      value = value % 360 - value % 90;
+      for(OrientationEnum orientation : OrientationEnum.values())
+      {
+        if(orientation.getCode() == value)
+          return orientation;
+      }
+      return null;
+    }
+    // </public>
+    // </interface>
+    // </static>
+
+    // <dynamic>
+    // <fields>
+    private final int code;
+    // </fields>
+
+    // <constructors>
+    private OrientationEnum(
+      int code
+      )
+    {this.code = code;}
+    // </constructors>
+
+    // <interface>
+    // <public>
+    public int getCode(
+      )
+    {return code;}
+    // </public>
+    // </interface>
+    // </dynamic>
+    // </class>
+  }
+  // </classes>
+
+  // <dynamic>
+  // <constructors>
+  public AppearanceCharacteristics(
+    Document context
+    )
+  {
+    super(
+      context.getFile(),
+      new PdfDictionary()
+      );
+  }
+
+  public AppearanceCharacteristics(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {super(baseObject,container);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public AppearanceCharacteristics clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    Gets the widget annotation's alternate (down) caption,
+    displayed when the mouse button is pressed within its active area
+    (Pushbutton fields only).
+  */
+  public String getAlternateCaption(
+    )
+  {
+    /*
+      NOTE: 'AC' entry may be undefined.
+    */
+    PdfTextString alternateCaptionObject = (PdfTextString)getBaseDataObject().get(PdfName.AC);
+    if(alternateCaptionObject == null)
+      return null;
+
+    return (String)alternateCaptionObject.getValue();
+  }
+
+  /**
+    Gets the widget annotation's alternate (down) icon definition,
+    displayed when the mouse button is pressed within its active area
+    (Pushbutton fields only).
+  */
+  public FormXObject getAlternateIcon(
+    )
+  {
+    /*
+      NOTE: 'IX' entry may be undefined (anyway, MUST be an indirect reference).
+    */
+    PdfReference alternateIconObject = (PdfReference)getBaseDataObject().get(PdfName.IX);
+    if(alternateIconObject == null)
+      return null;
+
+    return new FormXObject(alternateIconObject);
+  }
+
+  /**
+    Gets the widget annotation's background color.
+  */
+  public Color getBackgroundColor(
+    )
+  {return getColor(PdfName.BG);}
+
+  /**
+    Gets the widget annotation's border color.
+  */
+  public Color getBorderColor(
+    )
+  {return getColor(PdfName.BC);}
+
+  /**
+    Gets the position of the caption relative to its icon (Pushbutton fields only).
+  */
+  public CaptionPositionEnum getCaptionPosition(
+    )
+  {
+    /*
+      NOTE: 'TP' entry may be undefined.
+    */
+    PdfInteger captionPositionObject = (PdfInteger)getBaseDataObject().get(PdfName.TP);
+    if(captionPositionObject == null)
+      return CaptionPositionEnum.CaptionOnly;
+
+    return CaptionPositionEnum.get(captionPositionObject.getRawValue());
+  }
+
+  /**
+    Gets the icon fit specifying how to display the widget annotation's icon
+    within its annotation box (Pushbutton fields only).
+    If present, the icon fit applies to all of the annotation's icons
+    (normal, rollover, and alternate).
+  */
+  public IconFitObject getIconFit(
+    )
+  {
+    /*
+      NOTE: 'IF' entry may be undefined.
+    */
+    PdfDirectObject iconFitObject = getBaseDataObject().get(PdfName.IF);
+    if(iconFitObject == null)
+      return null;
+
+    return new IconFitObject(iconFitObject,getContainer());
+  }
+
+  /**
+    Gets the widget annotation's normal caption,
+    displayed when it is not interacting with the user (Button fields only).
+  */
+  public String getNormalCaption(
+    )
+  {
+    /*
+      NOTE: 'CA' entry may be undefined.
+    */
+    PdfTextString normalCaptionObject = (PdfTextString)getBaseDataObject().get(PdfName.CA);
+    if(normalCaptionObject == null)
+      return null;
+
+    return (String)normalCaptionObject.getValue();
+  }
+
+  /**
+    Gets the widget annotation's normal icon definition,
+    displayed when it is not interacting with the user (Pushbutton fields only).
+  */
+  public FormXObject getNormalIcon(
+    )
+  {
+    /*
+      NOTE: 'I' entry may be undefined (anyway, MUST be an indirect reference).
+    */
+    PdfReference normalIconObject = (PdfReference)getBaseDataObject().get(PdfName.I);
+    if(normalIconObject == null)
+      return null;
+
+    return new FormXObject(normalIconObject);
+  }
+
+  /**
+    Gets the widget annotation's orientation.
+  */
+  public OrientationEnum getOrientation(
+    )
+  {
+    /*
+      NOTE: 'R' entry may be undefined.
+    */
+    PdfInteger orientationObject = (PdfInteger)getBaseDataObject().get(PdfName.R);
+    if(orientationObject == null)
+      return OrientationEnum.Up;
+
+    return OrientationEnum.get(orientationObject.getRawValue());
+  }
+
+  /**
+    Gets the widget annotation's rollover caption,
+    displayed when the user rolls the cursor into its active area
+    without pressing the mouse button (Pushbutton fields only).
+  */
+  public String getRolloverCaption(
+    )
+  {
+    /*
+      NOTE: 'RC' entry may be undefined.
+    */
+    PdfTextString rolloverCaptionObject = (PdfTextString)getBaseDataObject().get(PdfName.RC);
+    if(rolloverCaptionObject == null)
+      return null;
+
+    return (String)rolloverCaptionObject.getValue();
+  }
+
+  /**
+    Gets the widget annotation's rollover icon definition,
+    displayed when the user rolls the cursor into its active area
+    without pressing the mouse button (Pushbutton fields only).
+  */
+  public FormXObject getRolloverIcon(
+    )
+  {
+    /*
+      NOTE: 'RI' entry may be undefined (anyway, MUST be an indirect reference).
+    */
+    PdfReference rolloverIconObject = (PdfReference)getBaseDataObject().get(PdfName.RI);
+    if(rolloverIconObject == null)
+      return null;
+
+    return new FormXObject(rolloverIconObject);
+  }
+
+  /**
+    Sets the widget annotation's alternate (down) caption.
+
+    @see #getAlternateCaption()
+  */
+  public void setAlternateCaption(
+    String value
+    )
+  {getBaseDataObject().put(PdfName.AC, new PdfTextString(value));}
+
+  /**
+    Sets the widget annotation's alternate (down) icon definition.
+
+    @see #getAlternateIcon()
+  */
+  public void setAlternateIcon(
+    FormXObject value
+    )
+  {getBaseDataObject().put(PdfName.IX, value.getBaseObject());}
+
+  /**
+    Sets the widget annotation's background color.
+
+    @see #getBackgroundColor()
+  */
+  public void setBackgroundColor(
+    Color value
+    )
+  {setColor(PdfName.BG, value);}
+
+  /**
+    Sets the widget annotation's border color.
+
+    @see #getBorderColor()
+  */
+  public void setBorderColor(
+    Color value
+    )
+  {setColor(PdfName.BC, value);}
+
+  /**
+    Sets the position of the caption relative to its icon.
+
+    @see #getCaptionPosition()
+  */
+  public void setCaptionPosition(
+    CaptionPositionEnum value
+    )
+  {getBaseDataObject().put(PdfName.TP, new PdfInteger(value.getCode()));}
+
+  /**
+    Sets the icon fit specifying how to display the widget annotation's icon
+    within its annotation box.
+
+    @see #getIconFit()
+  */
+  public void setIconFit(
+    IconFitObject value
+    )
+  {getBaseDataObject().put(PdfName.IF, value.getBaseObject());}
+
+  /**
+    Sets the widget annotation's normal caption.
+
+    @see #getNormalCaption()
+  */
+  public void setNormalCaption(
+    String value
+    )
+  {getBaseDataObject().put(PdfName.CA, new PdfTextString(value));}
+
+  /**
+    Sets the widget annotation's normal icon definition.
+
+    @see #getNormalIcon()
+  */
+  public void setNormalIcon(
+    FormXObject value
+    )
+  {getBaseDataObject().put(PdfName.I, value.getBaseObject());}
+
+  /**
+    Sets the widget annotation's orientation.
+
+    @see #getOrientation()
+  */
+  public void setOrientation(
+    OrientationEnum value
+    )
+  {getBaseDataObject().put(PdfName.R, new PdfInteger(value.getCode()));}
+
+  /**
+    Sets the widget annotation's rollover caption.
+
+    @see #getRolloverCaption()
+  */
+  public void setRolloverCaption(
+    String value
+    )
+  {getBaseDataObject().put(PdfName.RC, new PdfTextString(value));}
+
+  /**
+    Sets the widget annotation's rollover icon definition.
+
+    @see #getRolloverIcon()
+  */
+  public void setRolloverIcon(
+    FormXObject value
+    )
+  {getBaseDataObject().put(PdfName.RI, value.getBaseObject());}
+  // </public>
+
+  // <private>
+  private Color getColor(
+    PdfName key
+    )
+  {
+    /*
+      NOTE: Color entry may be undefined.
+    */
+    PdfArray colorObject = (PdfArray)getBaseDataObject().get(key);
+    if(colorObject == null)
+      return null;
+
+    switch(colorObject.size())
+    {
+      case 0:
+        return null;
+      case 1:
+        return new DeviceGrayColor(((IPdfNumber)colorObject.get(0)).getNumberValue());
+      case 3:
+        return new DeviceRGBColor(
+          ((IPdfNumber)colorObject.get(0)).getNumberValue(),
+          ((IPdfNumber)colorObject.get(1)).getNumberValue(),
+          ((IPdfNumber)colorObject.get(2)).getNumberValue()
+          );
+      case 4:
+        return new DeviceCMYKColor(
+          ((IPdfNumber)colorObject.get(0)).getNumberValue(),
+          ((IPdfNumber)colorObject.get(1)).getNumberValue(),
+          ((IPdfNumber)colorObject.get(2)).getNumberValue(),
+          ((IPdfNumber)colorObject.get(3)).getNumberValue()
+          );
+      default:
+        return null;
+    }
+  }
+
+  private void setColor(
+    PdfName key,
+    Color value
+    )
+  {
+    PdfArray valueObject = new PdfArray();
+    for(double component : value.getComponents())
+    {valueObject.add(new PdfReal(component));}
+
+    getBaseDataObject().put(key, valueObject);
+  }
+  // </private>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/AppearanceStates.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/AppearanceStates.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/AppearanceStates.java	(revision 23703)
@@ -0,0 +1,355 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.annotations;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.contents.xObjects.FormXObject;
+import it.stefanochizzolini.clown.files.File;
+import it.stefanochizzolini.clown.objects.PdfDataObject;
+import it.stefanochizzolini.clown.objects.PdfDictionary;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfObjectWrapper;
+import it.stefanochizzolini.clown.objects.PdfStream;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+  Appearance states [PDF:1.6:8.4.4].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.7
+  @version 0.0.7
+*/
+public class AppearanceStates
+  extends PdfObjectWrapper<PdfDataObject>
+  implements Map<PdfName,FormXObject>
+{
+  // <class>
+  // <classes>
+  private class Entry
+    implements Map.Entry<PdfName,FormXObject>
+  {
+    // <class>
+    // <dynamic>
+    // <fields>
+    private final PdfName key;
+    private final FormXObject value;
+    // </fields>
+
+    // <constructors>
+    private Entry(
+      PdfName key,
+      FormXObject value
+      )
+    {
+      this.key = key;
+      this.value = value;
+    }
+    // </constructors>
+
+    // <interface>
+    // <public>
+    // <Map.Entry>
+    public PdfName getKey(
+      )
+    {return key;}
+
+    public FormXObject getValue(
+      )
+    {return value;}
+
+    public FormXObject setValue(
+      FormXObject value
+      )
+    {throw new UnsupportedOperationException();}
+    // </Map.Entry>
+    // </public>
+    // </interface>
+    // </dynamic>
+    // </class>
+  }
+  // </classes>
+
+  // <dynamic>
+  // <fields>
+  private Appearance appearance;
+
+  private PdfName statesKey;
+  // </fields>
+
+  // <constructors>
+  AppearanceStates(
+    PdfName statesKey,
+    PdfIndirectObject container,
+    Appearance appearance
+    )
+  {
+    super(
+      appearance.getBaseDataObject().get(statesKey),
+      container
+      );
+
+    this.appearance = appearance;
+    this.statesKey = statesKey;
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public AppearanceStates clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    Gets the appearance associated to these states.
+  */
+  public Appearance getAppearance(
+    )
+  {return appearance;}
+
+//TODO
+  /**
+    Gets the key associated to a given value.
+  */
+//   public PdfName getKey(
+//     FormXObject value
+//     )
+//   {return getBaseDataObject().getKey(value.getBaseObject());}
+
+  // <Map>
+  public void clear(
+    )
+  {ensureDictionary().clear();}
+
+  public boolean containsKey(
+    Object key
+    )
+  {
+    PdfDataObject baseDataObject = getBaseDataObject();
+    if(baseDataObject == null) // No state.
+      return false;
+    if(baseDataObject instanceof PdfStream) // Single state.
+      return (key == null);
+    // Multiple state.
+    return ((PdfDictionary)baseDataObject).containsKey(key);
+  }
+
+  public boolean containsValue(
+    Object value
+    )
+  {
+    if(!(value instanceof FormXObject))
+      return false;
+
+    PdfDataObject baseDataObject = getBaseDataObject();
+    if(baseDataObject == null) // No state.
+      return false;
+    if(baseDataObject instanceof PdfStream) // Single state.
+      return ((FormXObject)value).getBaseObject().equals(getBaseObject());
+    // Multiple state.
+    return ((PdfDictionary)baseDataObject).containsValue(
+      ((FormXObject)value).getBaseObject()
+      );
+  }
+
+  public Set<Map.Entry<PdfName,FormXObject>> entrySet(
+    )
+  {
+    HashSet<Map.Entry<PdfName,FormXObject>> entrySet = new HashSet<Map.Entry<PdfName,FormXObject>>();
+
+    PdfDataObject baseDataObject = getBaseDataObject();
+    if(baseDataObject == null) // No state.
+    { /* NOOP. */ }
+    else if(baseDataObject instanceof PdfStream) // Single state.
+    {
+      entrySet.add(
+        new Entry(
+          null,
+          new FormXObject(getBaseObject())
+          )
+        );
+    }
+    else // Multiple state.
+    {
+      for(Map.Entry<PdfName,PdfDirectObject> entry : ((PdfDictionary)baseDataObject).entrySet())
+      {
+        entrySet.add(
+          new Entry(
+            entry.getKey(),
+            new FormXObject(entry.getValue())
+            )
+          );
+      }
+    }
+
+    return entrySet;
+  }
+
+  public boolean equals(
+    PdfDirectObject object
+    )
+  {throw new NotImplementedException();}
+
+  public FormXObject get(
+    Object key
+    )
+  {
+    PdfDataObject baseDataObject = getBaseDataObject();
+    if(baseDataObject == null) // No state.
+      return null;
+
+    if(key == null)
+    {
+      if(baseDataObject instanceof PdfStream) // Single state.
+        return new FormXObject(getBaseObject());
+      // Multiple state, but invalid key.
+      return null;
+    }
+    // Multiple state.
+    return new FormXObject(((PdfDictionary)baseDataObject).get(key));
+  }
+
+  public int hashCode(
+    )
+  {throw new NotImplementedException();}
+
+  public boolean isEmpty(
+    )
+  {
+    PdfDataObject baseDataObject = getBaseDataObject();
+    if(baseDataObject == null) // No state.
+      return true;
+    if(baseDataObject instanceof PdfStream) // Single state.
+      return false;
+    // Multiple state.
+    return ((PdfDictionary)baseDataObject).isEmpty();
+  }
+
+  public Set<PdfName> keySet(
+    )
+  {throw new NotImplementedException();}
+
+  public FormXObject put(
+    PdfName key,
+    FormXObject value
+    )
+  {
+    PdfDirectObject previousValue;
+    if(key == null) // Single state.
+    {
+      setBaseObject(value.getBaseObject());
+      previousValue = appearance.getBaseDataObject().put(statesKey,getBaseObject());
+    }
+    else // Multiple state.
+    {previousValue = ensureDictionary().put(key,value.getBaseObject());}
+
+    if(File.resolve(previousValue) instanceof PdfStream)
+      return new FormXObject(previousValue);
+
+    return null;
+  }
+
+  public void putAll(
+    Map<? extends PdfName,? extends FormXObject> entries
+    )
+  {throw new NotImplementedException();}
+
+  public FormXObject remove(
+    Object key
+    )
+  {
+    PdfDataObject baseDataObject = getBaseDataObject();
+    if(baseDataObject == null) // No state.
+      return null;
+
+    PdfDirectObject previousValue;
+    if(baseDataObject instanceof PdfStream) // Single state.
+    {
+      if(key == null)
+      {
+        setBaseObject(null);
+        previousValue = appearance.getBaseDataObject().remove(statesKey);
+      }
+      else // Invalid key.
+      {previousValue = null;}
+    }
+    else // Multiple state.
+    {previousValue = ((PdfDictionary)baseDataObject).remove(key);}
+
+    if(File.resolve(previousValue) instanceof PdfStream)
+      return new FormXObject(previousValue);
+
+    return null;
+  }
+
+  public int size(
+    )
+  {
+    PdfDataObject baseDataObject = getBaseDataObject();
+    if(baseDataObject == null) // No state.
+      return 0;
+    if(baseDataObject instanceof PdfStream) // Single state.
+      return 1;
+    // Multiple state.
+    return ((PdfDictionary)baseDataObject).size();
+  }
+
+  public Collection<FormXObject> values(
+    )
+  {throw new NotImplementedException();}
+  // </Map>
+  // </public>
+
+  // <private>
+  private PdfDictionary ensureDictionary(
+    )
+  {
+    PdfDataObject baseDataObject = getBaseDataObject();
+    if(!(baseDataObject instanceof PdfDictionary))
+    {
+      /*
+        NOTE: Single states are erased as they have no valid key
+        to be consistently integrated within the dictionary.
+      */
+      setBaseObject((PdfDirectObject)(baseDataObject = new PdfDictionary()));
+      appearance.getBaseDataObject().put(statesKey,(PdfDictionary)baseDataObject);
+    }
+
+    return (PdfDictionary)baseDataObject;
+  }
+  // </private>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/Border.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/Border.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/Border.java	(revision 23703)
@@ -0,0 +1,285 @@
+/*
+  Copyright 2008-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.annotations;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.contents.LineDash;
+import it.stefanochizzolini.clown.objects.IPdfNumber;
+import it.stefanochizzolini.clown.objects.PdfArray;
+import it.stefanochizzolini.clown.objects.PdfDictionary;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfObjectWrapper;
+import it.stefanochizzolini.clown.objects.PdfReal;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+/**
+  Border characteristics [PDF:1.6:8.4.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.7
+  @version 0.0.8
+*/
+public class Border
+  extends PdfObjectWrapper<PdfDictionary>
+{
+  // <class>
+  // <classes>
+  /**
+    Border style [PDF:1.6:8.4.3].
+  */
+  public enum StyleEnum
+  {
+    // <class>
+    // <static>
+    // <fields>
+    /**
+      Solid.
+    */
+    Solid(PdfName.S),
+    /**
+      Dashed.
+
+      @see #getPattern()
+    */
+    Dashed(PdfName.D),
+    /**
+      Beveled.
+    */
+    Beveled(PdfName.B),
+    /**
+      Inset.
+    */
+    Inset(PdfName.I),
+    /**
+      Underline.
+    */
+    Underline(PdfName.U);
+    // </fields>
+
+    // <interface>
+    // <public>
+    /**
+      Gets the style corresponding to the given value.
+    */
+    public static StyleEnum get(
+      PdfName value
+      )
+    {
+      for(StyleEnum style : StyleEnum.values())
+      {
+        if(style.getCode().equals(value))
+          return style;
+      }
+      return null;
+    }
+    // </public>
+    // </interface>
+    // </static>
+
+    // <dynamic>
+    // <fields>
+    private final PdfName code;
+    // </fields>
+
+    // <constructors>
+    private StyleEnum(
+      PdfName code
+      )
+    {this.code = code;}
+    // </constructors>
+
+    // <interface>
+    // <public>
+    public PdfName getCode(
+      )
+    {return code;}
+    // </public>
+    // </interface>
+    // </dynamic>
+    // </class>
+  }
+  // </classes>
+
+  // <static>
+  // <fields>
+  private static final LineDash DefaultLineDash = new LineDash(new double[]{3});
+  private static final StyleEnum DefaultStyle = StyleEnum.Solid;
+  private static final double DefaultWidth = 1;
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  public Border(
+    Document context
+    )
+  {
+    super(
+      context.getFile(),
+      new PdfDictionary()
+      );
+  }
+
+  public Border(
+    Document context,
+    double width,
+    StyleEnum style,
+    LineDash pattern
+    )
+  {
+    this(context);
+
+    setWidth(width);
+    setStyle(style);
+    setPattern(pattern);
+  }
+
+  public Border(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {super(baseObject,container);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public Border clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    Gets the dash pattern used in case of dashed border.
+  */
+  public LineDash getPattern(
+    )
+  {
+    /*
+      NOTE: 'D' entry may be undefined.
+    */
+    PdfArray dashObject = (PdfArray)getBaseDataObject().get(PdfName.D);
+    if(dashObject == null)
+      return DefaultLineDash;
+
+    double[] dashArray = new double[dashObject.size()];
+    for(
+      int dashIndex = 0,
+        dashLength = dashArray.length;
+      dashIndex < dashLength;
+      dashIndex++
+      )
+    {dashArray[dashIndex] = ((IPdfNumber)dashObject.get(dashIndex)).getNumberValue();}
+
+    return new LineDash(dashArray);
+  }
+
+  /**
+    Gets the border style.
+  */
+  public StyleEnum getStyle(
+    )
+  {
+    /*
+      NOTE: 'S' entry may be undefined.
+    */
+    PdfName styleObject = (PdfName)getBaseDataObject().get(PdfName.S);
+    if(styleObject == null)
+      return DefaultStyle;
+
+    return StyleEnum.get(styleObject);
+  }
+
+  /**
+    Gets the border width in points.
+  */
+  public double getWidth(
+    )
+  {
+    /*
+      NOTE: 'W' entry may be undefined.
+    */
+    IPdfNumber widthObject = (IPdfNumber)getBaseDataObject().get(PdfName.W);
+    if(widthObject == null)
+      return DefaultWidth;
+
+    return widthObject.getNumberValue();
+  }
+
+  /**
+    @see #getPattern()
+  */
+  public void setPattern(
+    LineDash value
+    )
+  {
+    if(value == null)
+    {getBaseDataObject().remove(PdfName.D);}
+    else
+    {
+      PdfArray dashObject = new PdfArray();
+
+      double[] dashArray = value.getDashArray();
+      for(
+        int dashIndex = 0,
+          dashLength = dashArray.length;
+        dashIndex < dashLength;
+        dashIndex++
+        )
+      {dashObject.add(new PdfReal(dashArray[dashIndex]));}
+
+      getBaseDataObject().put(PdfName.D, dashObject);
+    }
+  }
+
+  /**
+    @see #getStyle()
+  */
+  public void setStyle(
+    StyleEnum value
+    )
+  {
+    if(value == null
+      || value == DefaultStyle)
+    {getBaseDataObject().remove(PdfName.S);}
+    else
+    {getBaseDataObject().put(PdfName.S, value.getCode());}
+  }
+
+  /**
+    @see #getWidth()
+  */
+  public void setWidth(
+    double value
+    )
+  {getBaseDataObject().put(PdfName.W, new PdfReal(value));}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/CalloutNote.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/CalloutNote.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/CalloutNote.java	(revision 23703)
@@ -0,0 +1,326 @@
+/*
+  Copyright 2008-2009 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.annotations;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.Page;
+import it.stefanochizzolini.clown.objects.IPdfNumber;
+import it.stefanochizzolini.clown.objects.PdfArray;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfInteger;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfObjectWrapper;
+import it.stefanochizzolini.clown.objects.PdfReal;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+
+/**
+  Free text annotation [PDF:1.6:8.4.5].
+  <p>It displays text directly on the page. Unlike an ordinary text annotation,
+  a free text annotation has no open or closed state;
+  instead of being displayed in a pop-up window, the text is always visible.</p>
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+  @since 0.0.7
+*/
+public class CalloutNote
+  extends Annotation
+{
+  // <class>
+  // <classes>
+  /**
+    Callout line [PDF:1.6:8.4.5].
+  */
+  public static class LineObject
+    extends PdfObjectWrapper<PdfArray>
+  {
+    // <class>
+    // <dynamic>
+    // <fields>
+    private Page page;
+    // </fields>
+
+    // <constructors>
+    public LineObject(
+      Page page,
+      Point2D start,
+      Point2D end
+      )
+    {
+      super(
+        page.getFile(),
+        new PdfArray()
+        );
+
+      this.page = page;
+
+      PdfArray baseDataObject = getBaseDataObject();
+      double pageHeight = page.getBox().getHeight();
+      baseDataObject.add(new PdfReal(start.getX()));
+      baseDataObject.add(new PdfReal(pageHeight - start.getY()));
+      baseDataObject.add(new PdfReal(end.getX()));
+      baseDataObject.add(new PdfReal(pageHeight - end.getY()));
+    }
+
+    public LineObject(
+      Page page,
+      Point2D start,
+      Point2D knee,
+      Point2D end
+      )
+    {
+      super(
+        page.getFile(),
+        new PdfArray()
+        );
+
+      this.page = page;
+
+      PdfArray baseDataObject = getBaseDataObject();
+      double pageHeight = page.getBox().getHeight();
+      baseDataObject.add(new PdfReal(start.getX()));
+      baseDataObject.add(new PdfReal(pageHeight - start.getY()));
+      baseDataObject.add(new PdfReal(knee.getX()));
+      baseDataObject.add(new PdfReal(pageHeight - knee.getY()));
+      baseDataObject.add(new PdfReal(end.getX()));
+      baseDataObject.add(new PdfReal(pageHeight - end.getY()));
+    }
+
+    private LineObject(
+      PdfDirectObject baseObject,
+      PdfIndirectObject container
+      )
+    {super(baseObject,container);}
+    // </constructors>
+
+    // <interface>
+    // <public>
+    @Override
+    public LineObject clone(
+      Document context
+      )
+    {throw new NotImplementedException();}
+
+    public Point2D getEnd(
+      )
+    {
+      PdfArray coordinates = getBaseDataObject();
+      if(coordinates.size() < 6)
+        return new Point2D.Double(
+          ((IPdfNumber)coordinates.get(2)).getNumberValue(),
+          page.getBox().getHeight() - ((IPdfNumber)coordinates.get(3)).getNumberValue()
+          );
+      else
+        return new Point2D.Double(
+          ((IPdfNumber)coordinates.get(4)).getNumberValue(),
+          page.getBox().getHeight() - ((IPdfNumber)coordinates.get(5)).getNumberValue()
+          );
+    }
+
+    public Point2D getKnee(
+      )
+    {
+      PdfArray coordinates = getBaseDataObject();
+      if(coordinates.size() < 6)
+        return null;
+
+      return new Point2D.Double(
+        ((IPdfNumber)coordinates.get(2)).getNumberValue(),
+        page.getBox().getHeight() - ((IPdfNumber)coordinates.get(3)).getNumberValue()
+        );
+    }
+
+    public Point2D getStart(
+      )
+    {
+      PdfArray coordinates = getBaseDataObject();
+
+      return new Point2D.Double(
+        ((IPdfNumber)coordinates.get(0)).getNumberValue(),
+        page.getBox().getHeight() - ((IPdfNumber)coordinates.get(1)).getNumberValue()
+        );
+    }
+    // </public>
+    // </interface>
+    // </dynamic>
+    // </class>
+  }
+
+  /**
+    Text justification [PDF:1.6:8.4.5].
+  */
+  public enum JustificationEnum
+  {
+    // <class>
+    // <static>
+    // <fields>
+    /**
+      Left.
+    */
+    Left(new PdfInteger(0)),
+    /**
+      Center.
+    */
+    Center(new PdfInteger(1)),
+    /**
+      Right.
+    */
+    Right(new PdfInteger(2));
+    // </fields>
+
+    // <interface>
+    // <public>
+    /**
+      Gets the highlighting mode corresponding to the given value.
+    */
+    public static JustificationEnum get(
+      PdfInteger value
+      )
+    {
+      for(JustificationEnum justification : JustificationEnum.values())
+      {
+        if(justification.getCode().equals(value))
+          return justification;
+      }
+      return null;
+    }
+    // </public>
+    // </interface>
+    // </static>
+
+    // <dynamic>
+    // <fields>
+    private final PdfInteger code;
+    // </fields>
+
+    // <constructors>
+    private JustificationEnum(
+      PdfInteger code
+      )
+    {this.code = code;}
+    // </constructors>
+
+    // <interface>
+    // <public>
+    public PdfInteger getCode(
+      )
+    {return code;}
+    // </public>
+    // </interface>
+    // </dynamic>
+    // </class>
+  }
+  // </classes>
+
+  // <dynamic>
+  // <constructors>
+  public CalloutNote(
+    Page page,
+    Rectangle2D box,
+    String text
+    )
+  {
+    super(
+      page.getDocument(),
+      PdfName.FreeText,
+      box,
+      page
+      );
+
+    setText(text);
+  }
+
+  public CalloutNote(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {super(baseObject,container);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public CalloutNote clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    Gets the justification to be used in displaying the annotation's text.
+  */
+  public JustificationEnum getJustification(
+    )
+  {
+    /*
+      NOTE: 'Q' entry may be undefined.
+    */
+    PdfInteger justificationObject = (PdfInteger)getBaseDataObject().get(PdfName.Q);
+    if(justificationObject == null)
+      return JustificationEnum.Left;
+
+    return JustificationEnum.get(justificationObject);
+  }
+
+  /**
+    Gets the callout line attached to the free text annotation.
+  */
+  public LineObject getLine(
+    )
+  {
+    /*
+      NOTE: 'CL' entry may be undefined.
+    */
+    PdfArray calloutLineObject = (PdfArray)getBaseDataObject().get(PdfName.CL);
+    if(calloutLineObject == null)
+      return null;
+
+    return new LineObject(calloutLineObject,getContainer());
+  }
+
+  /**
+    @see #getJustification()
+  */
+  public void setJustification(
+    JustificationEnum value
+    )
+  {getBaseDataObject().put(PdfName.Q, value.getCode());}
+
+  /**
+    @see #getLine()
+  */
+  public void setLine(
+    LineObject value
+    )
+  {getBaseDataObject().put(PdfName.CL,value.getBaseObject());}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/Caret.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/Caret.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/Caret.java	(revision 23703)
@@ -0,0 +1,169 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.annotations;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.Page;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.awt.geom.Rectangle2D;
+
+/**
+  Caret annotation [PDF:1.6:8.4.5].
+  <p>It displays a visual symbol that indicates the presence of text edits.</p>
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.7
+  @version 0.0.7
+*/
+public class Caret
+  extends Annotation
+{
+  // <class>
+  // <classes>
+  /**
+    Symbol type [PDF:1.6:8.4.5].
+  */
+  public enum SymbolTypeEnum
+  {
+    // <class>
+    // <static>
+    // <fields>
+    /**
+      New paragraph.
+    */
+    NewParagraph(PdfName.P),
+    /**
+      None.
+    */
+    None(PdfName.None);
+    // </fields>
+
+    // <interface>
+    // <public>
+    /**
+      Gets the symbol type corresponding to the given value.
+    */
+    public static SymbolTypeEnum get(
+      PdfName value
+      )
+    {
+      for(SymbolTypeEnum symbolType : SymbolTypeEnum.values())
+      {
+        if(symbolType.getCode().equals(value))
+          return symbolType;
+      }
+      return null;
+    }
+    // </public>
+    // </interface>
+    // </static>
+
+    // <dynamic>
+    // <fields>
+    private final PdfName code;
+    // </fields>
+
+    // <constructors>
+    private SymbolTypeEnum(
+      PdfName code
+      )
+    {this.code = code;}
+    // </constructors>
+
+    // <interface>
+    // <public>
+    public PdfName getCode(
+      )
+    {return code;}
+    // </public>
+    // </interface>
+    // </dynamic>
+    // </class>
+  }
+  // </classes>
+
+  // <dynamic>
+  // <constructors>
+  public Caret(
+    Page page,
+    Rectangle2D box
+    )
+  {
+    super(
+      page.getDocument(),
+      PdfName.Caret,
+      box,
+      page
+      );
+  }
+
+  public Caret(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {super(baseObject,container);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public Caret clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    Gets the symbol to be used in displaying the annotation.
+  */
+  public SymbolTypeEnum getSymbolType(
+    )
+  {
+    /*
+      NOTE: 'Sy' entry may be undefined.
+    */
+    PdfName symbolObject = (PdfName)getBaseDataObject().get(PdfName.Sy);
+    if(symbolObject == null)
+      return SymbolTypeEnum.None;
+
+    return SymbolTypeEnum.get(symbolObject);
+  }
+
+  /**
+    @see #getSymbolType()
+  */
+  public void setSymbolType(
+    SymbolTypeEnum value
+    )
+  {getBaseDataObject().put(PdfName.Sy, value.getCode());}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/DualWidget.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/DualWidget.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/DualWidget.java	(revision 23703)
@@ -0,0 +1,105 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.annotations;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.Page;
+import it.stefanochizzolini.clown.documents.contents.xObjects.FormXObject;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.awt.geom.Rectangle2D;
+import java.util.Map;
+
+/**
+  Dual-state widget annotation.
+  <p>As its name implies, it has two states: on and off.</p>
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.7
+  @since 0.0.7
+*/
+public class DualWidget
+  extends Widget
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  /**
+    @param widgetName Widget name. It corresponds to the on-state name.
+  */
+  public DualWidget(
+    Page page,
+    Rectangle2D box,
+    String widgetName
+    )
+  {
+    super(page,box);
+
+    // Initialize the on-state appearance!
+    /*
+      NOTE: This is necessary to keep the reference to the on-state name.
+    */
+    Appearance appearance = new Appearance(page.getDocument());
+    setAppearance(appearance);
+    AppearanceStates normalAppearance = appearance.getNormal();
+    normalAppearance.put(new PdfName(widgetName),new FormXObject(page.getDocument()));
+  }
+
+  public DualWidget(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {super(baseObject,container);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public DualWidget clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  public String getWidgetName(
+    )
+  {
+    for(Map.Entry<PdfName,FormXObject> normalAppearanceEntry : getAppearance().getNormal().entrySet())
+    {
+      PdfName key = normalAppearanceEntry.getKey();
+      if(!key.equals(PdfName.Off)) // 'On' state.
+        return (String)key.getValue();
+    }
+
+    return null; // NOTE: It MUST NOT happen (on-state should always be defined).
+  }
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/Ellipse.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/Ellipse.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/Ellipse.java	(revision 23703)
@@ -0,0 +1,81 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.annotations;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.Page;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.awt.geom.Rectangle2D;
+
+/**
+  Circle annotation [PDF:1.6:8.4.5].
+  <p>It represents an ellipse to display on a page.</p>
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.7
+  @version 0.0.7
+*/
+public class Ellipse
+  extends Shape
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  public Ellipse(
+    Page page,
+    Rectangle2D box
+    )
+  {
+    super(
+      page,
+      box,
+      PdfName.Circle
+      );
+  }
+
+  public Ellipse(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {super(baseObject,container);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public Ellipse clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/FileAttachment.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/FileAttachment.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/FileAttachment.java	(revision 23703)
@@ -0,0 +1,201 @@
+/*
+  Copyright 2008-2009 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.annotations;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.Page;
+import it.stefanochizzolini.clown.documents.fileSpecs.FileSpec;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.awt.geom.Rectangle2D;
+
+/**
+  File attachment annotation [PDF:1.6:8.4.5].
+  <p>It represents a reference to a file, which typically is embedded in the PDF file.</p>
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+  @since 0.0.7
+*/
+public class FileAttachment
+  extends Annotation
+{
+  // <class>
+  // <classes>
+  /**
+    Icon to be used in displaying the annotation [PDF:1.6:8.4.5].
+  */
+  public enum IconTypeEnum
+  {
+    // <class>
+    // <static>
+    // <fields>
+    /**
+      Graph.
+    */
+    Graph(PdfName.Graph),
+    /**
+      Paper clip.
+    */
+    PaperClip(PdfName.Paperclip),
+    /**
+      Push pin.
+    */
+    PushPin(PdfName.PushPin),
+    /**
+      Tag.
+    */
+    Tag(PdfName.Tag);
+    // </fields>
+
+    // <interface>
+    // <public>
+    /**
+      Gets the icon type corresponding to the given value.
+    */
+    public static IconTypeEnum get(
+      PdfName value
+      )
+    {
+      for(IconTypeEnum iconType : IconTypeEnum.values())
+      {
+        if(iconType.getCode().equals(value))
+          return iconType;
+      }
+      return null;
+    }
+    // </public>
+    // </interface>
+    // </static>
+
+    // <dynamic>
+    // <fields>
+    private final PdfName code;
+    // </fields>
+
+    // <constructors>
+    private IconTypeEnum(
+      PdfName code
+      )
+    {this.code = code;}
+    // </constructors>
+
+    // <interface>
+    // <public>
+    public PdfName getCode(
+      )
+    {return code;}
+    // </public>
+    // </interface>
+    // </dynamic>
+    // </class>
+  }
+  // </classes>
+
+  // <dynamic>
+  // <constructors>
+  public FileAttachment(
+    Page page,
+    Rectangle2D box,
+    FileSpec fileSpec
+    )
+  {
+    super(
+      page.getDocument(),
+      PdfName.FileAttachment,
+      box,
+      page
+      );
+
+    setFileSpec(fileSpec);
+  }
+
+  public FileAttachment(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {super(baseObject,container);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public FileAttachment clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    Gets the file associated with this annotation.
+  */
+  public FileSpec getFileSpec(
+    )
+  {
+    /*
+      NOTE: 'FS' entry MUST exist.
+    */
+    return new FileSpec(getBaseDataObject().get(PdfName.FS),getContainer(),null);
+  }
+
+  /**
+    Gets the icon to be used in displaying the annotation.
+  */
+  public IconTypeEnum getIconType(
+    )
+  {
+    /*
+      NOTE: 'Name' entry may be undefined.
+    */
+    PdfName nameObject = (PdfName)getBaseDataObject().get(PdfName.Name);
+    if(nameObject == null)
+      return IconTypeEnum.PushPin;
+
+    return IconTypeEnum.get(nameObject);
+  }
+
+  /**
+    @see #getFileSpec()
+  */
+  public void setFileSpec(
+    FileSpec value
+    )
+  {getBaseDataObject().put(PdfName.FS, value.getBaseObject());}
+
+  /**
+    @see #getIconType()
+  */
+  public void setIconType(
+    IconTypeEnum value
+    )
+  {getBaseDataObject().put(PdfName.Name, value.getCode());}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/Line.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/Line.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/Line.java	(revision 23703)
@@ -0,0 +1,458 @@
+/*
+  Copyright 2008-2009 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.annotations;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.Page;
+import it.stefanochizzolini.clown.documents.contents.colorSpaces.DeviceRGBColor;
+import it.stefanochizzolini.clown.objects.IPdfNumber;
+import it.stefanochizzolini.clown.objects.PdfArray;
+import it.stefanochizzolini.clown.objects.PdfBoolean;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfReal;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+
+/**
+  Line annotation [PDF:1.6:8.4.5].
+  <p>It displays displays a single straight line on the page.
+  When opened, it displays a pop-up window containing the text of the associated note.</p>
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+  @since 0.0.7
+*/
+public class Line
+  extends Annotation
+{
+  // <class>
+  // <classes>
+  /**
+    Line ending style [PDF:1.6:8.4.5].
+  */
+  public enum LineEndStyleEnum
+  {
+    // <class>
+    // <static>
+    // <fields>
+    /**
+      Square.
+    */
+    Square(PdfName.Square),
+    /**
+      Circle.
+    */
+    Circle(PdfName.Circle),
+    /**
+      Diamond.
+    */
+    Diamond(PdfName.Diamond),
+    /**
+      Open arrow.
+    */
+    OpenArrow(PdfName.OpenArrow),
+    /**
+      Closed arrow.
+    */
+    ClosedArrow(PdfName.ClosedArrow),
+    /**
+      None.
+    */
+    None(PdfName.None),
+    /**
+      Butt.
+    */
+    Butt(PdfName.Butt),
+    /**
+      Reverse open arrow.
+    */
+    ReverseOpenArrow(PdfName.ROpenArrow),
+    /**
+      Reverse closed arrow.
+    */
+    ReverseClosedArrow(PdfName.RClosedArrow),
+    /**
+      Slash.
+    */
+    Slash(PdfName.Slash);
+    // </fields>
+
+    // <interface>
+    // <public>
+    /**
+      Gets the line ending style corresponding to the given value.
+    */
+    public static LineEndStyleEnum get(
+      PdfName value
+      )
+    {
+      for(LineEndStyleEnum style : LineEndStyleEnum.values())
+      {
+        if(style.getCode().equals(value))
+          return style;
+      }
+      return null;
+    }
+    // </public>
+    // </interface>
+    // </static>
+
+    // <dynamic>
+    // <fields>
+    private final PdfName code;
+    // </fields>
+
+    // <constructors>
+    private LineEndStyleEnum(
+      PdfName code
+      )
+    {this.code = code;}
+    // </constructors>
+
+    // <interface>
+    // <public>
+    public PdfName getCode(
+      )
+    {return code;}
+    // </public>
+    // </interface>
+    // </dynamic>
+    // </class>
+  }
+  // </classes>
+
+  // <static>
+  // <fields>
+  private static final double DefaultLeaderLineExtensionLength = 0;
+  private static final double DefaultLeaderLineLength = 0;
+  private static final LineEndStyleEnum DefaultLineEndStyle = LineEndStyleEnum.None;
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  public Line(
+    Page page,
+    Point2D startPoint,
+    Point2D endPoint
+    )
+  {
+    super(
+      page.getDocument(),
+      PdfName.Line,
+      new Rectangle2D.Double(
+        startPoint.getX(),
+        startPoint.getY(),
+        endPoint.getX()-startPoint.getX(),
+        endPoint.getY()-startPoint.getY()
+        ),
+      page
+      );
+
+    getBaseDataObject().put(
+      PdfName.L,
+      new PdfArray(new PdfDirectObject[]{new PdfReal(0),new PdfReal(0),new PdfReal(0),new PdfReal(0)})
+      );
+    setStartPoint(startPoint);
+    setEndPoint(endPoint);
+  }
+
+  public Line(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {super(baseObject,container);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public Line clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    Gets the ending coordinates.
+  */
+  public Point2D getEndPoint(
+    )
+  {
+    /*
+      NOTE: 'L' entry MUST be defined.
+    */
+    PdfArray coordinatesObject = (PdfArray)getBaseDataObject().get(PdfName.L);
+
+    return new Point2D.Double(
+      ((IPdfNumber)coordinatesObject.get(2)).getNumberValue(),
+      ((IPdfNumber)coordinatesObject.get(3)).getNumberValue()
+      );
+  }
+
+  /**
+    Gets the style of the ending line ending.
+  */
+  public LineEndStyleEnum getEndStyle(
+    )
+  {
+    /*
+      NOTE: 'LE' entry may be undefined.
+    */
+    PdfArray endstylesObject = (PdfArray)getBaseDataObject().get(PdfName.LE);
+    if(endstylesObject == null)
+      return DefaultLineEndStyle;
+
+    return LineEndStyleEnum.get((PdfName)endstylesObject.get(1));
+  }
+
+  /**
+    Gets the color with which to fill the interior of the annotation's line endings.
+  */
+  public DeviceRGBColor getFillColor(
+    )
+  {
+    /*
+      NOTE: 'IC' entry may be undefined.
+    */
+    PdfArray fillColorObject = (PdfArray)getBaseDataObject().get(PdfName.IC);
+    if(fillColorObject == null)
+      return null;
+
+    return new DeviceRGBColor(
+      ((IPdfNumber)fillColorObject.get(0)).getNumberValue(),
+      ((IPdfNumber)fillColorObject.get(1)).getNumberValue(),
+      ((IPdfNumber)fillColorObject.get(2)).getNumberValue()
+      );
+  }
+
+  /**
+    Gets the length of leader line extensions that extend
+    in the opposite direction from the leader lines.
+  */
+  public double getLeaderLineExtensionLength(
+    )
+  {
+    /*
+      NOTE: 'LLE' entry may be undefined.
+    */
+    IPdfNumber leaderLineExtensionLengthObject = (IPdfNumber)getBaseDataObject().get(PdfName.LLE);
+    if(leaderLineExtensionLengthObject == null)
+      return DefaultLeaderLineExtensionLength;
+
+    return leaderLineExtensionLengthObject.getNumberValue();
+  }
+
+  /**
+    Gets the length of leader lines that extend from each endpoint
+    of the line perpendicular to the line itself.
+    <p>A positive value means that the leader lines appear in the direction
+    that is clockwise when traversing the line from its starting point
+    to its ending point; a negative value indicates the opposite direction.</p>
+  */
+  public double getLeaderLineLength(
+    )
+  {
+    /*
+      NOTE: 'LL' entry may be undefined.
+    */
+    IPdfNumber leaderLineLengthObject = (IPdfNumber)getBaseDataObject().get(PdfName.LL);
+    if(leaderLineLengthObject == null)
+      return DefaultLeaderLineLength;
+
+    return -leaderLineLengthObject.getNumberValue();
+  }
+
+  /**
+    Gets the starting coordinates.
+  */
+  public Point2D getStartPoint(
+    )
+  {
+    /*
+      NOTE: 'L' entry MUST be defined.
+    */
+    PdfArray coordinatesObject = (PdfArray)getBaseDataObject().get(PdfName.L);
+
+    return new Point2D.Double(
+      ((IPdfNumber)coordinatesObject.get(0)).getNumberValue(),
+      ((IPdfNumber)coordinatesObject.get(1)).getNumberValue()
+      );
+  }
+
+  /**
+    Gets the style of the starting line ending.
+  */
+  public LineEndStyleEnum getStartStyle(
+    )
+  {
+    /*
+      NOTE: 'LE' entry may be undefined.
+    */
+    PdfArray endstylesObject = (PdfArray)getBaseDataObject().get(PdfName.LE);
+    if(endstylesObject == null)
+      return DefaultLineEndStyle;
+
+    return LineEndStyleEnum.get((PdfName)endstylesObject.get(0));
+  }
+
+  /**
+    Gets whether the contents should be shown as a caption.
+  */
+  public boolean isCaptionVisible(
+    )
+  {
+    /*
+      NOTE: 'Cap' entry may be undefined.
+    */
+    PdfBoolean captionVisibleObject = (PdfBoolean)getBaseDataObject().get(PdfName.Cap);
+    if(captionVisibleObject == null)
+      return false;
+
+    return ((Boolean)captionVisibleObject.getValue()).booleanValue();
+  }
+
+  /**
+    @see #isCaptionVisible()
+  */
+  public void setCaptionVisible(
+    boolean value
+    )
+  {getBaseDataObject().put(PdfName.Cap,new PdfBoolean(value));}
+
+  /**
+    @see #getEndPoint()
+  */
+  public void setEndPoint(
+    Point2D value
+    )
+  {
+    PdfArray coordinatesObject = (PdfArray)getBaseDataObject().get(PdfName.L);
+    coordinatesObject.set(2,new PdfReal(value.getX()));
+    coordinatesObject.set(3,new PdfReal(getPage().getBox().getHeight()-value.getY()));
+  }
+
+  /**
+    @see #getEndStyle()
+  */
+  public void setEndStyle(
+    LineEndStyleEnum value
+    )
+  {ensureLineEndStylesObject().set(1,value.getCode());}
+
+  /**
+    @see #getFillColor()
+  */
+  public void setFillColor(
+     DeviceRGBColor value
+    )
+  {
+    getBaseDataObject().put(
+      PdfName.IC,
+      new PdfArray(
+        new PdfDirectObject[]
+        {
+          new PdfReal(value.getRedComponent()),
+          new PdfReal(value.getGreenComponent()),
+          new PdfReal(value.getBlueComponent())
+        }
+        )
+      );
+  }
+
+  /**
+    @see #getLeaderLineExtensionLength()
+  */
+  public void setLeaderLineExtensionLength(
+    double value
+    )
+  {
+    getBaseDataObject().put(PdfName.LLE,new PdfReal(value));
+    /*
+      NOTE: If leader line extension entry is present, leader line MUST be too.
+    */
+    if(!getBaseDataObject().containsKey(PdfName.LL))
+    {setLeaderLineLength(DefaultLeaderLineLength);}
+  }
+
+  /**
+    @see #getLeaderLineLength()
+  */
+  public void setLeaderLineLength(
+    double value
+    )
+  {getBaseDataObject().put(PdfName.LL,new PdfReal(-value));}
+
+  /**
+    @see #getStartPoint()
+  */
+  public void setStartPoint(
+    Point2D value
+    )
+  {
+    PdfArray coordinatesObject = (PdfArray)getBaseDataObject().get(PdfName.L);
+    coordinatesObject.set(0,new PdfReal(value.getX()));
+    coordinatesObject.set(1,new PdfReal(getPage().getBox().getHeight()-value.getY()));
+  }
+
+  /**
+    @see #getStartStyle()
+  */
+  public void setStartStyle(
+    LineEndStyleEnum value
+    )
+  {ensureLineEndStylesObject().set(0,value.getCode());}
+  // </public>
+
+  // <private>
+  private PdfArray ensureLineEndStylesObject(
+    )
+  {
+    PdfArray endStylesObject = (PdfArray)getBaseDataObject().get(PdfName.LE);
+    if(endStylesObject == null)
+    {
+      getBaseDataObject().put(
+        PdfName.LE,
+        endStylesObject = new PdfArray(
+          new PdfDirectObject[]
+          {
+            DefaultLineEndStyle.getCode(),
+            DefaultLineEndStyle.getCode()
+          }
+          )
+        );
+    }
+
+    return endStylesObject;
+  }
+  // </private>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/Link.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/Link.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/Link.java	(revision 23703)
@@ -0,0 +1,190 @@
+/*
+  Copyright 2008-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.annotations;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.Page;
+import it.stefanochizzolini.clown.documents.interaction.ILink;
+import it.stefanochizzolini.clown.documents.interaction.actions.Action;
+import it.stefanochizzolini.clown.documents.interaction.navigation.document.Destination;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfObjectWrapper;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.awt.geom.Rectangle2D;
+
+/**
+  Link annotation [PDF:1.6:8.4.5].
+  <p>It represents either a hypertext link to a destination elsewhere in the document
+  or an action to be performed.</p>
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+  @since 0.0.7
+*/
+public class Link
+  extends Annotation
+  implements ILink
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  public Link(
+    Page page,
+    Rectangle2D box,
+    Destination destination
+    )
+  {
+    this(page,box);
+
+    setDestination(destination);
+  }
+
+  public Link(
+    Page page,
+    Rectangle2D box,
+    Action action
+    )
+  {
+    this(page,box);
+
+    AnnotationActions actions = new AnnotationActions(this);
+    actions.setOnActivate(action);
+    setActions(actions);
+  }
+
+  public Link(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {super(baseObject,container);}
+
+  private Link(
+    Page page,
+    Rectangle2D box
+    )
+  {
+    super(
+      page.getDocument(),
+      PdfName.Link,
+      box,
+      page
+      );
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public Link clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  // <ILink>
+  public Destination getDestination(
+    )
+  {
+    /*
+      NOTE: 'Dest' entry may be undefined.
+    */
+    PdfDirectObject destinationObject = getBaseDataObject().get(PdfName.Dest);
+    if(destinationObject == null)
+      return null;
+
+    return Document.resolveName(
+      Destination.class,
+      destinationObject,
+      getContainer()
+      );
+  }
+
+  public PdfObjectWrapper<?> getTarget(
+    )
+  {
+    if(getBaseDataObject().containsKey(PdfName.Dest))
+      return getDestination();
+    else if(getBaseDataObject().containsKey(PdfName.A))
+      return getAction();
+    else
+      return null;
+  }
+
+  @Override
+  public void setAction(
+    Action value
+    )
+  {
+    /*
+      NOTE: This entry is not permitted in link annotations if a 'Dest' entry is present.
+    */
+    if(getBaseDataObject().containsKey(PdfName.Dest)
+      && value != null)
+    {getBaseDataObject().remove(PdfName.Dest);}
+    
+    super.setAction(value);
+  }
+  
+  /**
+    @see #getDestination()
+  */
+  public void setDestination(
+    Destination value
+    )
+  {
+    if(value == null)
+    {getBaseDataObject().remove(PdfName.Dest);}
+    else
+    {
+      /*
+        NOTE: This entry is not permitted in link annotations if an 'A' entry is present.
+      */
+      if(getBaseDataObject().containsKey(PdfName.A))
+      {getBaseDataObject().remove(PdfName.A);}
+
+      getBaseDataObject().put(PdfName.Dest,value.getNamedBaseObject());
+    }
+  }
+
+  public void setTarget(
+    PdfObjectWrapper<?> value
+    )
+  {
+    if(value instanceof Destination)
+    {setDestination((Destination)value);}
+    else if(value instanceof Action)
+    {setAction((Action)value);}
+    else
+      throw new IllegalArgumentException("It MUST be either a Destination or an Action.");
+  }
+  // </ILink>
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/MovieAnnotation.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/MovieAnnotation.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/MovieAnnotation.java	(revision 23703)
@@ -0,0 +1,113 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.annotations;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.Page;
+import it.stefanochizzolini.clown.documents.multimedia.Movie;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.awt.geom.Rectangle2D;
+
+/**
+  Movie annotation [PDF:1.6:8.4.5].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.7
+  @version 0.0.7
+*/
+public class MovieAnnotation
+  extends Annotation
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  public MovieAnnotation(
+    Page page,
+    Rectangle2D box,
+    Movie movie
+    )
+  {
+    super(
+      page.getDocument(),
+      PdfName.Movie,
+      box,
+      page
+      );
+
+    setMovie(movie);
+  }
+
+  public MovieAnnotation(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {super(baseObject,container);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public MovieAnnotation clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    Gets the movie to be played.
+  */
+  public Movie getMovie(
+    )
+  {
+    /*
+      NOTE: 'Movie' entry MUST exist.
+    */
+    return new Movie(
+      getBaseDataObject().get(PdfName.Movie),
+      getContainer()
+      );
+  }
+
+  /**
+    @see #getMovie()
+  */
+  public void setMovie(
+    Movie value
+    )
+  {
+    if(value == null)
+      throw new IllegalArgumentException("Movie MUST be defined.");
+
+    getBaseDataObject().put(PdfName.Movie,value.getBaseObject());
+  }
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/Note.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/Note.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/Note.java	(revision 23703)
@@ -0,0 +1,220 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.annotations;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.Page;
+import it.stefanochizzolini.clown.objects.PdfBoolean;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+
+/**
+  Text annotation [PDF:1.6:8.4.5].
+  <p>It represents a sticky note attached to a point in the PDF document.</p>
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.7
+  @version 0.0.7
+*/
+public class Note
+  extends Annotation
+{
+  // <class>
+  // <classes>
+  /**
+    Icon to be used in displaying the annotation [PDF:1.6:8.4.5].
+  */
+  public enum IconTypeEnum
+  {
+    // <class>
+    // <static>
+    // <fields>
+    /**
+      Comment.
+    */
+    Comment(PdfName.Comment),
+    /**
+      Help.
+    */
+    Help(PdfName.Help),
+    /**
+      Insert.
+    */
+    Insert(PdfName.Insert),
+    /**
+      Key.
+    */
+    Key(PdfName.Key),
+    /**
+      New paragraph.
+    */
+    NewParagraph(PdfName.NewParagraph),
+    /**
+      Note.
+    */
+    Note(PdfName.Note),
+    /**
+      Paragraph.
+    */
+    Paragraph(PdfName.Paragraph);
+    // </fields>
+
+    // <interface>
+    // <public>
+    /**
+      Gets the highlighting mode corresponding to the given value.
+    */
+    public static IconTypeEnum get(
+      PdfName value
+      )
+    {
+      for(IconTypeEnum iconType : IconTypeEnum.values())
+      {
+        if(iconType.getCode().equals(value))
+          return iconType;
+      }
+      return null;
+    }
+    // </public>
+    // </interface>
+    // </static>
+
+    // <dynamic>
+    // <fields>
+    private final PdfName code;
+    // </fields>
+
+    // <constructors>
+    private IconTypeEnum(
+      PdfName code
+      )
+    {this.code = code;}
+    // </constructors>
+
+    // <interface>
+    // <public>
+    public PdfName getCode(
+      )
+    {return code;}
+    // </public>
+    // </interface>
+    // </dynamic>
+    // </class>
+  }
+  // </classes>
+
+  // <dynamic>
+  // <constructors>
+  public Note(
+    Page page,
+    Point2D location,
+    String text
+    )
+  {
+    super(
+      page.getDocument(),
+      PdfName.Text,
+      new Rectangle2D.Double(location.getX(),location.getY(),0,0),
+      page
+      );
+
+    setText(text);
+  }
+
+  public Note(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {super(baseObject,container);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public Note clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    Gets the icon to be used in displaying the annotation.
+  */
+  public IconTypeEnum getIconType(
+    )
+  {
+    /*
+      NOTE: 'Name' entry may be undefined.
+    */
+    PdfName nameObject = (PdfName)getBaseDataObject().get(PdfName.Name);
+    if(nameObject == null)
+      return IconTypeEnum.Note;
+
+    return IconTypeEnum.get(nameObject);
+  }
+
+  /**
+    Gets whether the annotation should initially be displayed open.
+  */
+  public boolean isOpen(
+    )
+  {
+    /*
+      NOTE: 'Open' entry may be undefined.
+    */
+    PdfBoolean openObject = (PdfBoolean)getBaseDataObject().get(PdfName.Open);
+    if(openObject == null)
+      return false;
+
+    return ((Boolean)openObject.getValue()).booleanValue();
+  }
+
+//TODO:State and StateModel!!!
+
+  /**
+    @see #getIconType()
+  */
+  public void setIconType(
+    IconTypeEnum value
+    )
+  {getBaseDataObject().put(PdfName.Name, value.getCode());}
+
+  /**
+    @see #isOpen()
+  */
+  public void setOpen(
+    boolean value
+    )
+  {getBaseDataObject().put(PdfName.Open, new PdfBoolean(value));}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/Polygon.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/Polygon.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/Polygon.java	(revision 23703)
@@ -0,0 +1,81 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.annotations;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.Page;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.awt.geom.Rectangle2D;
+
+/**
+  Polygon annotation [PDF:1.6:8.4.5].
+  <p>It represents a closed polygon to display on a page.</p>
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.7
+  @version 0.0.7
+*/
+public class Polygon
+  extends VertexShape
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  public Polygon(
+    Page page,
+    Rectangle2D box
+    )
+  {
+    super(
+      page,
+      box,
+      PdfName.Polygon
+      );
+  }
+
+  public Polygon(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {super(baseObject,container);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public Polygon clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/Polyline.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/Polyline.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/Polyline.java	(revision 23703)
@@ -0,0 +1,81 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.annotations;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.Page;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.awt.geom.Rectangle2D;
+
+/**
+  Polyline annotation [PDF:1.6:8.4.5].
+  <p>It represents a (possibly-open) polygon to display on a page.</p>
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.7
+  @version 0.0.7
+*/
+public class Polyline
+  extends VertexShape
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  public Polyline(
+    Page page,
+    Rectangle2D box
+    )
+  {
+    super(
+      page,
+      box,
+      PdfName.PolyLine
+      );
+  }
+
+  public Polyline(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {super(baseObject,container);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public Polyline clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/Popup.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/Popup.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/Popup.java	(revision 23703)
@@ -0,0 +1,134 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.annotations;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.Page;
+import it.stefanochizzolini.clown.objects.PdfBoolean;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfReference;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.awt.geom.Rectangle2D;
+
+/**
+  Pop-up annotation [PDF:1.6:8.4.5].
+  <p>It displays text in a pop-up window for entry and editing.
+  It typically does not appear alone but is associated with a markup annotation,
+  its parent annotation, and is used for editing the parent's text.</p>
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.7
+  @version 0.0.7
+*/
+public class Popup
+  extends Annotation
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  protected Popup(
+    Page page,
+    Rectangle2D box
+    )
+  {
+    super(
+      page.getDocument(),
+      PdfName.Popup,
+      box,
+      page
+      );
+  }
+
+  protected Popup(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {super(baseObject,container);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public Popup clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    Gets whether the annotation should initially be displayed open.
+  */
+  public boolean isOpen(
+    )
+  {
+    /*
+      NOTE: 'Open' entry may be undefined.
+    */
+    PdfBoolean openObject = (PdfBoolean)getBaseDataObject().get(PdfName.Open);
+    if(openObject == null)
+      return false;
+
+    return ((Boolean)openObject.getValue()).booleanValue();
+  }
+
+  /**
+    Gets the parent annotation.
+  */
+  public Annotation getParent(
+    )
+  {
+    /*
+      NOTE: 'Parent' entry may be undefined.
+    */
+    PdfReference parentObject = (PdfReference)getBaseDataObject().get(PdfName.Parent);
+    if(parentObject == null)
+      return null;
+
+    return Annotation.wrap(parentObject);
+  }
+
+  /**
+    @see #isOpen()
+  */
+  public void setOpen(
+    boolean value
+    )
+  {getBaseDataObject().put(PdfName.Open, new PdfBoolean(value));}
+
+  /**
+    @see #getParent()
+  */
+  public void setParent(
+    Annotation value
+    )
+  {getBaseDataObject().put(PdfName.Parent,value.getBaseObject());}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/Rectangle.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/Rectangle.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/Rectangle.java	(revision 23703)
@@ -0,0 +1,81 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.annotations;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.Page;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.awt.geom.Rectangle2D;
+
+/**
+  Square annotation [PDF:1.6:8.4.5].
+  <p>It represents a rectangle to display on a page.</p>
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.7
+  @version 0.0.7
+*/
+public class Rectangle
+  extends Shape
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  public Rectangle(
+    Page page,
+    Rectangle2D box
+    )
+  {
+    super(
+      page,
+      box,
+      PdfName.Square
+      );
+  }
+
+  public Rectangle(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {super(baseObject,container);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public Rectangle clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/RubberStamp.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/RubberStamp.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/RubberStamp.java	(revision 23703)
@@ -0,0 +1,221 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.annotations;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.Page;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.awt.geom.Rectangle2D;
+
+/**
+  Rubber stamp annotation [PDF:1.6:8.4.5].
+  <p>It displays text or graphics intended to look as if they were stamped
+  on the page with a rubber stamp.</p>
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.7
+  @version 0.0.7
+*/
+public class RubberStamp
+  extends Annotation
+{
+  // <class>
+  // <classes>
+  /**
+    Icon to be used in displaying the annotation [PDF:1.6:8.4.5].
+  */
+  public enum IconTypeEnum
+  {
+    // <class>
+    // <static>
+    // <fields>
+    /**
+      Approved.
+    */
+    Approved(PdfName.Approved),
+    /**
+      As is.
+    */
+    AsIs(PdfName.AsIs),
+    /**
+      Confidential.
+    */
+    Confidential(PdfName.Confidential),
+    /**
+      Departmental.
+    */
+    Departmental(PdfName.Departmental),
+    /**
+      Draft.
+    */
+    Draft(PdfName.Draft),
+    /**
+      Experimental.
+    */
+    Experimental(PdfName.Experimental),
+    /**
+      Expired.
+    */
+    Expired(PdfName.Expired),
+    /**
+      Final.
+    */
+    Final(PdfName.Final),
+    /**
+      For comment.
+    */
+    ForComment(PdfName.ForComment),
+    /**
+      For public release.
+    */
+    ForPublicRelease(PdfName.ForPublicRelease),
+    /**
+      Not approved.
+    */
+    NotApproved(PdfName.NotApproved),
+    /**
+      Not for public release.
+    */
+    NotForPublicRelease(PdfName.NotForPublicRelease),
+    /**
+      Sold.
+    */
+    Sold(PdfName.Sold),
+    /**
+      Top secret.
+    */
+    TopSecret(PdfName.TopSecret);
+    // </fields>
+
+    // <interface>
+    // <public>
+    /**
+      Gets the markup type corresponding to the given value.
+    */
+    public static IconTypeEnum get(
+      PdfName value
+      )
+    {
+      for(IconTypeEnum iconType : IconTypeEnum.values())
+      {
+        if(iconType.getCode().equals(value))
+          return iconType;
+      }
+      return null;
+    }
+    // </public>
+    // </interface>
+    // </static>
+
+    // <dynamic>
+    // <fields>
+    private final PdfName code;
+    // </fields>
+
+    // <constructors>
+    private IconTypeEnum(
+      PdfName code
+      )
+    {this.code = code;}
+    // </constructors>
+
+    // <interface>
+    // <public>
+    public PdfName getCode(
+      )
+    {return code;}
+    // </public>
+    // </interface>
+    // </dynamic>
+    // </class>
+  }
+  // </classes>
+
+  // <dynamic>
+  // <constructors>
+  public RubberStamp(
+    Page page,
+    Rectangle2D box,
+    IconTypeEnum iconType
+    )
+  {
+    super(
+      page.getDocument(),
+      PdfName.Stamp,
+      box,
+      page
+      );
+
+    setIconType(iconType);
+  }
+
+  public RubberStamp(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {super(baseObject,container);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public RubberStamp clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    Gets the icon to be used in displaying the annotation.
+  */
+  public IconTypeEnum getIconType(
+    )
+  {
+    /*
+      NOTE: 'Name' entry may be undefined.
+    */
+    PdfName nameObject = (PdfName)getBaseDataObject().get(PdfName.Name);
+    if(nameObject == null)
+      return IconTypeEnum.Draft;
+
+    return IconTypeEnum.get(nameObject);
+  }
+
+  /**
+    @see #getIconType()
+  */
+  public void setIconType(
+    IconTypeEnum value
+    )
+  {getBaseDataObject().put(PdfName.Name, value.getCode());}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/Scribble.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/Scribble.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/Scribble.java	(revision 23703)
@@ -0,0 +1,154 @@
+/*
+  Copyright 2008-2009 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.annotations;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.Page;
+import it.stefanochizzolini.clown.objects.IPdfNumber;
+import it.stefanochizzolini.clown.objects.PdfArray;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfReal;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+  Freehand "scribble" composed of one or more disjoint paths [PDF:1.6:8.4.5].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+  @since 0.0.7
+*/
+public class Scribble
+  extends Annotation
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  public Scribble(
+    Page page,
+    Rectangle2D box,
+    List<List<Point2D>> paths
+    )
+  {
+    super(
+      page.getDocument(),
+      PdfName.Ink,
+      box,
+      page
+      );
+
+    setPaths(paths);
+  }
+
+  public Scribble(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {super(baseObject,container);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public Scribble clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    Gets the coordinates of each path.
+  */
+  public List<List<Point2D>> getPaths(
+    )
+  {
+    /*
+      NOTE: 'InkList' entry MUST be present.
+    */
+    PdfArray pathsObject = (PdfArray)getBaseDataObject().get(PdfName.InkList);
+    List<List<Point2D>> paths = new ArrayList<List<Point2D>>();
+    double pageHeight = getPage().getBox().getHeight();
+    for(
+      int pathIndex = 0,
+        pathLength = pathsObject.size();
+      pathIndex < pathLength;
+      pathIndex++
+      )
+    {
+      PdfArray pathObject = (PdfArray)pathsObject.get(pathIndex);
+      List<Point2D> path = new ArrayList<Point2D>();
+      for(
+        int pointIndex = 0,
+          pointLength = pathObject.size();
+        pointIndex < pointLength;
+        pointIndex += 2
+        )
+      {
+        path.add(
+          new Point2D.Double(
+            ((IPdfNumber)pathObject.get(pointIndex)).getNumberValue(),
+            pageHeight - ((IPdfNumber)pathObject.get(pointIndex+1)).getNumberValue()
+            )
+          );
+      }
+      paths.add(path);
+    }
+
+    return paths;
+  }
+
+  /**
+    @see #getPaths()
+  */
+  public void setPaths(
+    List<List<Point2D>> value
+    )
+  {
+    PdfArray pathsObject = new PdfArray();
+    double pageHeight = getPage().getBox().getHeight();
+    for(List<Point2D> path : value)
+    {
+      PdfArray pathObject = new PdfArray();
+      for(Point2D point : path)
+      {
+        pathObject.add(new PdfReal(point.getX())); // x.
+        pathObject.add(new PdfReal(pageHeight-point.getY())); // y.
+      }
+      pathsObject.add(pathObject);
+    }
+
+    getBaseDataObject().put(PdfName.InkList,pathsObject);
+  }
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/Shape.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/Shape.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/Shape.java	(revision 23703)
@@ -0,0 +1,126 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.annotations;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.Page;
+import it.stefanochizzolini.clown.documents.contents.colorSpaces.DeviceRGBColor;
+import it.stefanochizzolini.clown.objects.IPdfNumber;
+import it.stefanochizzolini.clown.objects.PdfArray;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfReal;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.awt.geom.Rectangle2D;
+
+/**
+  Abstract shape annotation.
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.7
+  @version 0.0.7
+*/
+public abstract class Shape
+  extends Annotation
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  protected Shape(
+    Page page,
+    Rectangle2D box,
+    PdfName subtype
+    )
+  {
+    super(
+      page.getDocument(),
+      subtype,
+      box,
+      page
+      );
+  }
+
+  protected Shape(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {super(baseObject,container);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public Shape clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    Gets the color with which to fill the interior of the annotation's shape.
+  */
+  public DeviceRGBColor getFillColor(
+    )
+  {
+    /*
+      NOTE: 'IC' entry may be undefined.
+    */
+    PdfArray fillColorObject = (PdfArray)getBaseDataObject().get(PdfName.IC);
+    if(fillColorObject == null)
+      return null;
+
+    return new DeviceRGBColor(
+      ((IPdfNumber)fillColorObject.get(0)).getNumberValue(),
+      ((IPdfNumber)fillColorObject.get(1)).getNumberValue(),
+      ((IPdfNumber)fillColorObject.get(2)).getNumberValue()
+      );
+  }
+
+  /**
+    @see #getFillColor()
+  */
+  public void setFillColor(
+     DeviceRGBColor value
+    )
+  {
+    getBaseDataObject().put(
+      PdfName.IC,
+      new PdfArray(
+        new PdfDirectObject[]
+        {
+          new PdfReal(value.getRedComponent()),
+          new PdfReal(value.getGreenComponent()),
+          new PdfReal(value.getBlueComponent())
+        }
+        )
+      );
+  }
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/SoundAnnotation.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/SoundAnnotation.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/SoundAnnotation.java	(revision 23703)
@@ -0,0 +1,200 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.annotations;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.Page;
+import it.stefanochizzolini.clown.documents.multimedia.Sound;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.awt.geom.Rectangle2D;
+
+/**
+  Sound annotation [PDF:1.6:8.4.5].
+  <p>When the annotation is activated, the sound is played.</p>
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.7
+  @version 0.0.7
+*/
+public class SoundAnnotation
+  extends Annotation
+{
+  // <class>
+  // <classes>
+  /**
+    Icon to be used in displaying the annotation [PDF:1.6:8.4.5].
+  */
+  public enum IconTypeEnum
+  {
+    // <class>
+    // <static>
+    // <fields>
+    /**
+      Speaker.
+    */
+    Speaker(PdfName.Speaker),
+    /**
+      Microphone.
+    */
+    Microphone(PdfName.Mic);
+    // </fields>
+
+    // <interface>
+    // <public>
+    /**
+      Gets the highlighting mode corresponding to the given value.
+    */
+    public static IconTypeEnum get(
+      PdfName value
+      )
+    {
+      for(IconTypeEnum iconType : IconTypeEnum.values())
+      {
+        if(iconType.getCode().equals(value))
+          return iconType;
+      }
+      return null;
+    }
+    // </public>
+    // </interface>
+    // </static>
+
+    // <dynamic>
+    // <fields>
+    private final PdfName code;
+    // </fields>
+
+    // <constructors>
+    private IconTypeEnum(
+      PdfName code
+      )
+    {this.code = code;}
+    // </constructors>
+
+    // <interface>
+    // <public>
+    public PdfName getCode(
+      )
+    {return code;}
+    // </public>
+    // </interface>
+    // </dynamic>
+    // </class>
+  }
+  // </classes>
+
+  // <dynamic>
+  // <constructors>
+  public SoundAnnotation(
+    Page page,
+    Rectangle2D box,
+    Sound sound
+    )
+  {
+    super(
+      page.getDocument(),
+      PdfName.Sound,
+      box,
+      page
+      );
+
+    setSound(sound);
+  }
+
+  public SoundAnnotation(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {super(baseObject,container);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public SoundAnnotation clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    Gets the icon to be used in displaying the annotation.
+  */
+  public IconTypeEnum getIconType(
+    )
+  {
+    /*
+      NOTE: 'Name' entry may be undefined.
+    */
+    PdfName nameObject = (PdfName)getBaseDataObject().get(PdfName.Name);
+    if(nameObject == null)
+      return IconTypeEnum.Speaker;
+
+    return IconTypeEnum.get(nameObject);
+  }
+
+  /**
+    Gets the sound to be played.
+  */
+  public Sound getSound(
+    )
+  {
+    /*
+      NOTE: 'Sound' entry MUST exist.
+    */
+    return new Sound(
+      getBaseDataObject().get(PdfName.Sound)
+      );
+  }
+
+  /**
+    @see #getIconType()
+  */
+  public void setIconType(
+    IconTypeEnum value
+    )
+  {getBaseDataObject().put(PdfName.Name, value.getCode());}
+
+  /**
+    @see #getSound()
+  */
+  public void setSound(
+    Sound value
+    )
+  {
+    if(value == null)
+      throw new IllegalArgumentException("Sound MUST be defined.");
+
+    getBaseDataObject().put(PdfName.Sound,value.getBaseObject());
+  }
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/TextMarkup.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/TextMarkup.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/TextMarkup.java	(revision 23703)
@@ -0,0 +1,236 @@
+/*
+  Copyright 2008-2009 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.annotations;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.Page;
+import it.stefanochizzolini.clown.objects.IPdfNumber;
+import it.stefanochizzolini.clown.objects.PdfArray;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfReal;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.awt.geom.Rectangle2D;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+  Text markup annotation [PDF:1.6:8.4.5].
+  <p>It displays highlights, underlines, strikeouts, or jagged ("squiggly") underlines
+  in the text of a document.</p>
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+  @since 0.0.7
+*/
+public class TextMarkup
+  extends Annotation
+{
+  // <class>
+  // <classes>
+  /**
+    Markup type [PDF:1.6:8.4.5].
+  */
+  public enum MarkupTypeEnum
+  {
+    // <class>
+    // <static>
+    // <fields>
+    /**
+      Highlight.
+    */
+    Highlight(PdfName.Highlight),
+    /**
+      Squiggly.
+    */
+    Squiggly(PdfName.Squiggly),
+    /**
+      StrikeOut.
+    */
+    StrikeOut(PdfName.StrikeOut),
+    /**
+      Underline.
+    */
+    Underline(PdfName.Underline);
+    // </fields>
+
+    // <interface>
+    // <public>
+    /**
+      Gets the markup type corresponding to the given value.
+    */
+    public static MarkupTypeEnum get(
+      PdfName value
+      )
+    {
+      for(MarkupTypeEnum markupType : MarkupTypeEnum.values())
+      {
+        if(markupType.getCode().equals(value))
+          return markupType;
+      }
+      return null;
+    }
+    // </public>
+    // </interface>
+    // </static>
+
+    // <dynamic>
+    // <fields>
+    private final PdfName code;
+    // </fields>
+
+    // <constructors>
+    private MarkupTypeEnum(
+      PdfName code
+      )
+    {this.code = code;}
+    // </constructors>
+
+    // <interface>
+    // <public>
+    public PdfName getCode(
+      )
+    {return code;}
+    // </public>
+    // </interface>
+    // </dynamic>
+    // </class>
+  }
+  // </classes>
+
+  // <dynamic>
+  // <constructors>
+  public TextMarkup(
+    Page page,
+    Rectangle2D box,
+    MarkupTypeEnum type
+    )
+  {
+    super(
+      page.getDocument(),
+      type.getCode(),
+      box,
+      page
+      );
+  }
+
+  public TextMarkup(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {super(baseObject,container);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public TextMarkup clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    Gets the quadrilaterals encompassing a word or group of contiguous words
+    in the text underlying the annotation.
+  */
+  public List<Rectangle2D> getBoxes(
+    )
+  {
+    /*
+      NOTE: 'QuadPoints' entry MUST be present.
+    */
+    PdfArray quadPointsObject = (PdfArray)getBaseDataObject().get(PdfName.QuadPoints);
+    List<Rectangle2D> boxes = new ArrayList<Rectangle2D>();
+    double pageHeight = getPage().getBox().getHeight();
+    for(
+      int index = 0,
+        length = quadPointsObject.size();
+      index < length;
+      index += 8
+      )
+    {
+      double x = ((IPdfNumber)quadPointsObject.get(index+6)).getNumberValue();
+      double y = pageHeight - ((IPdfNumber)quadPointsObject.get(index+7)).getNumberValue();
+      double width = ((IPdfNumber)quadPointsObject.get(index+2)).getNumberValue() - ((IPdfNumber)quadPointsObject.get(index)).getNumberValue();
+      double height = ((IPdfNumber)quadPointsObject.get(index+3)).getNumberValue() - ((IPdfNumber)quadPointsObject.get(index+1)).getNumberValue();
+      boxes.add(
+        new Rectangle2D.Double(x,y,width,height)
+        );
+    }
+
+    return boxes;
+  }
+
+  /**
+    Gets the markup type.
+  */
+  public MarkupTypeEnum getMarkupType(
+    )
+  {
+    /*
+      NOTE: 'Subtype' entry MUST be present.
+    */
+    return MarkupTypeEnum.get((PdfName)getBaseDataObject().get(PdfName.Subtype));
+  }
+
+  /**
+    @see #getBoxes()
+  */
+  public void setBoxes(
+    List<Rectangle2D> value
+    )
+  {
+    PdfArray quadPointsObject = new PdfArray();
+    double pageHeight = getPage().getBox().getHeight();
+    for(Rectangle2D box : value)
+    {
+      quadPointsObject.add(new PdfReal(box.getX())); // x1.
+      quadPointsObject.add(new PdfReal(pageHeight-(box.getY()+box.getHeight()))); // y1.
+      quadPointsObject.add(new PdfReal(box.getX()+box.getWidth())); // x2.
+      quadPointsObject.add(quadPointsObject.get(1)); // y2.
+      quadPointsObject.add(quadPointsObject.get(2)); // x3.
+      quadPointsObject.add(new PdfReal(pageHeight-box.getY())); // y3.
+      quadPointsObject.add(quadPointsObject.get(0)); // x4.
+      quadPointsObject.add(quadPointsObject.get(5)); // y4.
+    }
+
+    getBaseDataObject().put(PdfName.QuadPoints,quadPointsObject);
+  }
+
+  /**
+    @see #getMarkupType()
+  */
+  public void setMarkupType(
+    MarkupTypeEnum value
+    )
+  {getBaseDataObject().put(PdfName.Subtype, value.getCode());}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/VertexShape.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/VertexShape.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/VertexShape.java	(revision 23703)
@@ -0,0 +1,134 @@
+/*
+  Copyright 2008-2009 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.annotations;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.Page;
+import it.stefanochizzolini.clown.objects.IPdfNumber;
+import it.stefanochizzolini.clown.objects.PdfArray;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfReal;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+  Abstract vertexed shape annotation.
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+  @since 0.0.7
+*/
+public abstract class VertexShape
+  extends Shape
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  protected VertexShape(
+    Page page,
+    Rectangle2D box,
+    PdfName subtype
+    )
+  {
+    super(
+      page,
+      box,
+      subtype
+      );
+  }
+
+  protected VertexShape(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {super(baseObject,container);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public VertexShape clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    Gets the coordinates of each vertex.
+  */
+  public List<Point2D> getVertices(
+    )
+  {
+    /*
+      NOTE: 'Vertices' entry MUST be present.
+    */
+    PdfArray verticesObject = (PdfArray)getBaseDataObject().get(PdfName.Vertices);
+    List<Point2D> vertices = new ArrayList<Point2D>();
+    double pageHeight = getPage().getBox().getHeight();
+    for(
+      int index = 0,
+        length = verticesObject.size();
+      index < length;
+      index += 2
+      )
+    {
+      double x = ((IPdfNumber)verticesObject.get(index)).getNumberValue();
+      double y = pageHeight - ((IPdfNumber)verticesObject.get(index+1)).getNumberValue();
+      vertices.add(
+        new Point2D.Double(x,y)
+        );
+    }
+
+    return vertices;
+  }
+
+  /**
+    @see #getVertices()
+  */
+  public void setVertices(
+    List<Point2D> value
+    )
+  {
+    PdfArray verticesObject = new PdfArray();
+    double pageHeight = getPage().getBox().getHeight();
+    for(Point2D vertex : value)
+    {
+      verticesObject.add(new PdfReal(vertex.getX())); // x.
+      verticesObject.add(new PdfReal(pageHeight-vertex.getY())); // y.
+    }
+
+    getBaseDataObject().put(PdfName.Vertices,verticesObject);
+  }
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/Widget.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/Widget.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/Widget.java	(revision 23703)
@@ -0,0 +1,224 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.annotations;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.Page;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.awt.geom.Rectangle2D;
+import java.util.EnumSet;
+
+/**
+  Widget annotation [PDF:1.6:8.4.5].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.7
+  @since 0.0.7
+*/
+public class Widget
+  extends Annotation
+{
+  // <class>
+  // <classes>
+  /**
+    Highlighting mode [PDF:1.6:8.4.5].
+  */
+  public enum HighlightModeEnum
+  {
+    // <class>
+    // <static>
+    // <fields>
+    /**
+      No highlighting.
+    */
+    None(PdfName.N),
+    /**
+      Invert the contents of the annotation rectangle.
+    */
+    Invert(PdfName.I),
+    /**
+      Invert the annotation's border.
+    */
+    Outline(PdfName.O),
+    /**
+      Display the annotation's down appearance.
+    */
+    Push(PdfName.P),
+    /**
+      Same as Push (which is preferred).
+    */
+    Toggle(PdfName.T);
+    // </fields>
+
+    // <interface>
+    // <public>
+    /**
+      Gets the highlighting mode corresponding to the given value.
+    */
+    public static HighlightModeEnum get(
+      PdfName value
+      )
+    {
+      for(HighlightModeEnum mode : HighlightModeEnum.values())
+      {
+        if(mode.getCode().equals(value))
+          return mode;
+      }
+      return null;
+    }
+    // </public>
+    // </interface>
+    // </static>
+
+    // <dynamic>
+    // <fields>
+    private final PdfName code;
+    // </fields>
+
+    // <constructors>
+    private HighlightModeEnum(
+      PdfName code
+      )
+    {this.code = code;}
+    // </constructors>
+
+    // <interface>
+    // <public>
+    public PdfName getCode(
+      )
+    {return code;}
+    // </public>
+    // </interface>
+    // </dynamic>
+    // </class>
+  }
+  // </classes>
+
+  // <dynamic>
+  // <constructors>
+  public Widget(
+    Page page,
+    Rectangle2D box
+    )
+  {
+    super(
+      page.getDocument(),
+      PdfName.Widget,
+      box,
+      page
+      );
+
+    EnumSet<FlagsEnum> flags = getFlags(); flags.add(FlagsEnum.Print); setFlags(flags);
+  }
+
+  public Widget(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {super(baseObject,container);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public Widget clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  @Override
+  public AnnotationActions getActions(
+    )
+  {
+    PdfDirectObject actionsObject = getBaseDataObject().get(PdfName.AA);
+    if(actionsObject == null)
+      return null;
+
+    return new WidgetActions(this,actionsObject,getContainer());
+  }
+
+  /**
+    Gets the annotation's appearance characteristics
+    to be used for its visual presentation on the page.
+  */
+  public AppearanceCharacteristics getAppearanceCharacteristics(
+    )
+  {
+    /*
+      NOTE: 'MK' entry may be undefined.
+    */
+    PdfDirectObject appearanceObject = getBaseDataObject().get(PdfName.MK);
+    if(appearanceObject == null)
+      return null;
+
+    return new AppearanceCharacteristics(appearanceObject,getContainer());
+  }
+
+  /**
+    Gets the annotation's highlighting mode, the visual effect to be used
+    when the mouse button is pressed or held down inside its active area.
+  */
+  public HighlightModeEnum getHighlightMode(
+    )
+  {
+    /*
+      NOTE: 'H' entry may be undefined.
+    */
+    PdfName highlightModeObject = (PdfName)getBaseDataObject().get(PdfName.H);
+    if(highlightModeObject == null)
+      return HighlightModeEnum.Invert;
+
+    return HighlightModeEnum.get(highlightModeObject);
+  }
+
+  /**
+    Sets the annotation's appearance characteristics.
+
+    @see #getAppearanceCharacteristics()
+  */
+  public void setAppearanceCharacteristics(
+    AppearanceCharacteristics value
+    )
+  {getBaseDataObject().put(PdfName.MK, value.getBaseObject());}
+
+  /**
+    Sets the annotation's highlighting mode.
+
+    @see #getHighlightMode()
+  */
+  public void setHighlightMode(
+    HighlightModeEnum value
+    )
+  {getBaseDataObject().put(PdfName.H, value.getCode());}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/WidgetActions.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/WidgetActions.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/WidgetActions.java	(revision 23703)
@@ -0,0 +1,120 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.annotations;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.interaction.actions.Action;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+/**
+  Widget actions [PDF:1.6:8.5.2].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.7
+  @since 0.0.7
+*/
+public class WidgetActions
+  extends AnnotationActions
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  public WidgetActions(
+    Annotation parent
+    )
+  {super(parent);}
+
+  public WidgetActions(
+    Annotation parent,
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {super(parent,baseObject,container);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public WidgetActions clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    Gets the action to be performed when the annotation loses the input focus.
+  */
+  public Action getOnBlur(
+    )
+  {
+    /*
+      NOTE: 'Bl' entry may be undefined.
+    */
+    PdfDirectObject onBlurObject = getBaseDataObject().get(PdfName.Bl);
+    if(onBlurObject == null)
+      return null;
+
+    return Action.wrap(onBlurObject,getContainer());
+  }
+
+  /**
+    Gets the action to be performed when the annotation receives the input focus.
+  */
+  public Action getOnFocus(
+    )
+  {
+    /*
+      NOTE: 'Fo' entry may be undefined.
+    */
+    PdfDirectObject onFocusObject = getBaseDataObject().get(PdfName.Fo);
+    if(onFocusObject == null)
+      return null;
+
+    return Action.wrap(onFocusObject,getContainer());
+  }
+
+  /**
+    @see #getOnBlur()
+  */
+  public void setOnBlur(
+    Action value
+    )
+  {getBaseDataObject().put(PdfName.Bl, value.getBaseObject());}
+
+  /**
+    @see #getOnFocus()
+  */
+  public void setOnFocus(
+    Action value
+    )
+  {getBaseDataObject().put(PdfName.Fo, value.getBaseObject());}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/package.html
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/package.html	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/annotations/package.html	(revision 23703)
@@ -0,0 +1,39 @@
+<html>
+<head>
+<!--
+  Copyright 2008-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+-->
+</head>
+<body>
+<p>Annotations used to associate an object such as a note, sound, or movie with a location
+on a page of a PDF document, or to provide a way to interact with the user by means of
+the mouse and keyboard [PDF:1.6:8.4].</p>
+
+<h2>Related Documentation</h2>
+<p>For overviews, tutorials, examples, guides, and tool documentation, please see:</p>
+<ul>
+  <li><a href="http://clown.stefanochizzolini.it">PDF Clown Home Page</a>
+</ul>
+</body>
+</html>
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/ButtonField.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/ButtonField.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/ButtonField.java	(revision 23703)
@@ -0,0 +1,78 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.forms;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.interaction.annotations.Widget;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+/**
+  Button field [PDF:1.6:8.6.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.7
+  @since 0.0.7
+*/
+public abstract class ButtonField
+  extends Field
+{
+  // <dynamic>
+  // <constructors>
+  /**
+    Creates a new button field within the given document context.
+  */
+  protected ButtonField(
+    String name,
+    Widget widget
+    )
+  {
+    super(
+      PdfName.Btn,
+      name,
+      widget
+      );
+  }
+
+  protected ButtonField(
+    PdfDirectObject baseObject
+    )
+  {super(baseObject);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public ButtonField clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/CheckBox.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/CheckBox.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/CheckBox.java	(revision 23703)
@@ -0,0 +1,105 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.forms;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.interaction.annotations.Widget;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+/**
+  Check box field [PDF:1.6:8.6.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8.1
+  @since 0.0.7
+*/
+public class CheckBox
+  extends ButtonField
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  /**
+    Creates a new checkbox within the given document context.
+  */
+  public CheckBox(
+    String name,
+    Widget widget,
+    boolean checked
+    )
+  {
+    super(
+      name,
+      widget
+      );
+
+    setChecked(checked);
+  }
+
+  public CheckBox(
+    PdfDirectObject baseObject
+    )
+  {super(baseObject);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public CheckBox clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  public boolean isChecked(
+    )
+  {
+    PdfName value = (PdfName)getBaseDataObject().get(PdfName.V);
+
+    return !(value == null
+      || value.equals(PdfName.Off));
+  }
+
+  public void setChecked(
+    boolean value
+    )
+  {
+    PdfName baseValue = (value ? PdfName.Yes : PdfName.Off);
+    getBaseDataObject().put(PdfName.V,baseValue);
+    getWidgets().get(0).getBaseDataObject().put(PdfName.AS,baseValue);
+  }
+
+  @Override
+  public void setValue(
+    Object value
+    )
+  {setChecked(!value.equals("Off"));}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/ChoiceField.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/ChoiceField.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/ChoiceField.java	(revision 23703)
@@ -0,0 +1,152 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.forms;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.interaction.annotations.Widget;
+import it.stefanochizzolini.clown.files.File;
+import it.stefanochizzolini.clown.objects.PdfArray;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.util.EnumSet;
+
+/**
+  Choice field [PDF:1.6:8.6.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.7
+  @version 0.0.7
+*/
+public abstract class ChoiceField
+  extends Field
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  /**
+    Creates a new choice field within the given document context.
+  */
+  protected ChoiceField(
+    String name,
+    Widget widget
+    )
+  {
+    super(
+      PdfName.Ch,
+      name,
+      widget
+      );
+  }
+
+  protected ChoiceField(
+    PdfDirectObject baseObject
+    )
+  {super(baseObject);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public ChoiceField clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  public ChoiceItems getItems(
+    )
+  {
+    /*
+      NOTE: 'Opt' entry may be undefined [PDF:1.6:8.6.3].
+    */
+    PdfArray items = (PdfArray)File.resolve(getBaseDataObject().get(PdfName.Opt));
+    if(items == null)
+      return null;
+
+    return new ChoiceItems(
+      items,
+      getContainer()
+      );
+  }
+
+  /**
+    Gets whether more than one of the field's items may be selected simultaneously.
+  */
+  public boolean isMultiSelect(
+    )
+  {return getFlags().contains(FlagsEnum.MultiSelect);}
+
+  /**
+    Gets whether validation action is triggered as soon as a selection is made,
+    without requiring the user to exit the field.
+  */
+  public boolean isValidatedOnChange(
+    )
+  {return getFlags().contains(FlagsEnum.CommitOnSelChange);}
+
+  /**
+    @see #getItems()
+  */
+  public void setItems(
+    ChoiceItems value
+    )
+  {getBaseDataObject().put(PdfName.Opt,value.getBaseObject());}
+
+  /**
+    @see #isMultiSelect()
+  */
+  public void setMultiSelect(
+    boolean value
+    )
+  {
+    EnumSet<FlagsEnum> flags = getFlags();
+    if(value)
+    {flags.add(FlagsEnum.MultiSelect);}
+    else
+    {flags.remove(FlagsEnum.MultiSelect);}
+    setFlags(flags);
+  }
+
+  /**
+    @see #isValidatedOnChange()
+  */
+  public void setValidatedOnChange(
+    boolean value
+    )
+  {
+    EnumSet<FlagsEnum> flags = getFlags();
+    if(value)
+    {flags.add(FlagsEnum.CommitOnSelChange);}
+    else
+    {flags.remove(FlagsEnum.CommitOnSelChange);}
+    setFlags(flags);
+  }
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/ChoiceItem.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/ChoiceItem.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/ChoiceItem.java	(revision 23703)
@@ -0,0 +1,183 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.forms;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.objects.PdfArray;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfObjectWrapper;
+import it.stefanochizzolini.clown.objects.PdfTextString;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+/**
+  Field option [PDF:1.6:8.6.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.7
+  @version 0.0.7
+*/
+public class ChoiceItem
+  extends PdfObjectWrapper<PdfDirectObject>
+{
+  // <fields>
+  private ChoiceItems items;
+  // </fields>
+
+  // <constructors>
+  public ChoiceItem(
+    String value
+    )
+  {super(new PdfTextString(value),null);}
+
+  public ChoiceItem(
+    Document context,
+    String value,
+    String text
+    )
+  {
+    super(
+      context.getFile(),
+      new PdfArray(
+        new PdfDirectObject[]
+        {
+          new PdfTextString(value),
+          new PdfTextString(text)
+        }
+        )
+      );
+  }
+
+  ChoiceItem(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container,
+    ChoiceItems items
+    )
+  {
+    super(baseObject,container);
+
+    setItems(items);
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public ChoiceItem clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    Gets the displayed text.
+  */
+  public String getText()
+  {
+    PdfDirectObject baseDataObject = getBaseDataObject();
+    if(baseDataObject instanceof PdfArray) // <value,text> pair.
+      return (String)((PdfTextString)((PdfArray)baseDataObject).get(1)).getValue();
+    else // Single text string.
+      return (String)((PdfTextString)baseDataObject).getValue();
+  }
+
+  /**
+    Gets the export value.
+  */
+  public String getValue()
+  {
+    PdfDirectObject baseDataObject = getBaseDataObject();
+    if(baseDataObject instanceof PdfArray) // <value,text> pair.
+      return (String)((PdfTextString)((PdfArray)baseDataObject).get(0)).getValue();
+    else // Single text string.
+      return (String)((PdfTextString)baseDataObject).getValue();
+  }
+
+  //TODO:make the class immutable (to avoid needing wiring it up to its collection...)!!!
+  /**
+    @see #getText()
+  */
+  public void setText(
+    String value
+    )
+  {
+    PdfDirectObject baseDataObject = getBaseDataObject();
+    if(baseDataObject instanceof PdfTextString)
+    {
+      PdfDirectObject oldBaseDataObject = baseDataObject;
+
+      setBaseObject(
+        baseDataObject = new PdfArray(
+          new PdfDirectObject[]
+          {
+            oldBaseDataObject
+          }
+          )
+        );
+      ((PdfArray)baseDataObject).add(new PdfTextString());
+
+      if(items != null)
+      {
+        // Force list update!
+        /*
+          NOTE: This operation is necessary in order to substitute
+          the previous base object with the new one within the list.
+        */
+        PdfArray itemsObject = items.getBaseDataObject();
+        itemsObject.set(itemsObject.indexOf(oldBaseDataObject),baseDataObject);
+      }
+    }
+
+    ((PdfTextString)((PdfArray)baseDataObject).get(1)).setValue(value);
+  }
+
+  /**
+    @see #getValue()
+  */
+  public void setValue(
+    String value
+    )
+  {
+    PdfDirectObject baseDataObject = getBaseDataObject();
+    if(baseDataObject instanceof PdfArray) // <value,text> pair.
+      ((PdfTextString)((PdfArray)baseDataObject).get(0)).setValue(value);
+    else // Single text string.
+      ((PdfTextString)baseDataObject).setValue(value);
+  }
+  // </public>
+
+  // <internal>
+  void setItems(
+    ChoiceItems value
+    )
+  {
+    if(items != null)
+      throw new IllegalArgumentException("Item already associated to another choice field.");
+
+    items = value;
+  }
+  // </internal>
+  // </interface>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/ChoiceItems.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/ChoiceItems.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/ChoiceItems.java	(revision 23703)
@@ -0,0 +1,343 @@
+/*
+  Copyright 2008-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.forms;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.objects.PdfArray;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfObjectWrapper;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.NoSuchElementException;
+
+/**
+  Field options [PDF:1.6:8.6.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.7
+  @version 0.0.8
+*/
+public class ChoiceItems
+  extends PdfObjectWrapper<PdfArray>
+  implements List<ChoiceItem>
+{
+  // <class>
+  // <dynamic>
+  // <fields>
+  // </fields>
+
+  // <constructors>
+  public ChoiceItems(
+    Document context
+    )
+  {
+    super(
+      context.getFile(),
+      new PdfArray()
+      );
+  }
+
+  public ChoiceItems(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {super(baseObject,container);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  public ChoiceItem add(
+    String value
+    )
+  {
+    ChoiceItem item = new ChoiceItem(value);
+    add(item);
+
+    return item;
+  }
+
+  public ChoiceItem add(
+    int index,
+    String value
+    )
+  {
+    ChoiceItem item = new ChoiceItem(value);
+    add(index, item);
+
+    return item;
+  }
+
+  @Override
+  public ChoiceItems clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  // <List>
+  public void add(
+    int index,
+    ChoiceItem value
+    )
+  {
+    getBaseDataObject().add(index,value.getBaseObject());
+    value.setItems(this);
+  }
+
+  public boolean addAll(
+    int index,
+    Collection<? extends ChoiceItem> values
+    )
+  {
+    for(ChoiceItem value : values)
+    {add(index++,value);}
+
+    return true;
+  }
+
+  public ChoiceItem get(
+    int index
+    )
+  {return new ChoiceItem(getBaseDataObject().get(index),getContainer(),this);}
+
+  public int indexOf(
+    Object value
+    )
+  {
+    if(!(value instanceof ChoiceItem))
+      return -1;
+
+    return getBaseDataObject().indexOf(((ChoiceItem)value).getBaseObject());
+  }
+
+  public int lastIndexOf(
+    Object value
+    )
+  {
+    /*
+      NOTE: Items are expected not to be duplicate.
+    */
+    return indexOf(value);
+  }
+
+  public ListIterator<ChoiceItem> listIterator(
+    )
+  {throw new NotImplementedException();}
+
+  public ListIterator<ChoiceItem> listIterator(
+    int index
+    )
+  {throw new NotImplementedException();}
+
+  public ChoiceItem remove(
+    int index
+    )
+  {
+    PdfDirectObject itemObject = getBaseDataObject().remove(index);
+
+    return new ChoiceItem(itemObject,getContainer(),null);
+  }
+
+  public ChoiceItem set(
+    int index,
+    ChoiceItem value
+    )
+  {
+    PdfDirectObject oldValueObject = getBaseDataObject().set(index,value.getBaseObject());
+    value.setItems(this);
+
+    return new ChoiceItem(
+      oldValueObject,
+      getContainer(),
+      null
+      );
+  }
+
+  public List<ChoiceItem> subList(
+    int fromIndex,
+    int toIndex
+    )
+  {throw new NotImplementedException();}
+
+  // <Collection>
+  public boolean add(
+    ChoiceItem value
+    )
+  {
+    getBaseDataObject().add(value.getBaseObject());
+    value.setItems(this);
+
+    return true;
+  }
+
+  public boolean addAll(
+    Collection<? extends ChoiceItem> values
+    )
+  {
+    for(ChoiceItem value : values)
+    {add(value);}
+
+    return true;
+  }
+
+  public void clear(
+    )
+  {getBaseDataObject().clear();}
+
+  public boolean contains(
+    Object value
+    )
+  {
+    if(!(value instanceof ChoiceItem))
+      return false;
+
+    return getBaseDataObject().contains(((ChoiceItem)value).getBaseObject());
+  }
+
+  public boolean containsAll(
+    Collection<?> values
+    )
+  {throw new NotImplementedException();}
+
+  public boolean equals(
+    Object object
+    )
+  {throw new NotImplementedException();}
+
+  public int hashCode(
+    )
+  {throw new NotImplementedException();}
+
+  public boolean isEmpty(
+    )
+  {return getBaseDataObject().isEmpty();}
+
+  public boolean remove(
+    Object value
+    )
+  {
+    if(!(value instanceof ChoiceItem))
+      return false;
+
+    return getBaseDataObject().remove(((ChoiceItem)value).getBaseObject());
+  }
+
+  public boolean removeAll(
+    Collection<?> values
+    )
+  {throw new NotImplementedException();}
+
+  public boolean retainAll(
+    Collection<?> values
+    )
+  {throw new NotImplementedException();}
+
+  public int size(
+    )
+  {return getBaseDataObject().size();}
+
+  public Object[] toArray(
+    )
+  {return toArray(new ChoiceItem[0]);}
+
+  @SuppressWarnings("unchecked")
+  public <T> T[] toArray(
+    T[] values
+    )
+  {
+    PdfArray itemObjects = (PdfArray)getBaseDataObject();
+    if(values.length < itemObjects.size())
+    {values = (T[])new Object[itemObjects.size()];}
+
+    PdfIndirectObject container = getContainer();
+    for(
+      int index = 0,
+        length = itemObjects.size();
+      index < length;
+      index++
+      )
+    {values[index] = (T)new ChoiceItem(itemObjects.get(index),container,this);}
+
+    return values;
+  }
+
+  // <Iterable>
+  public Iterator<ChoiceItem> iterator(
+    )
+  {
+    return new Iterator<ChoiceItem>()
+    {
+      // <class>
+      // <dynamic>
+      // <fields>
+      /**
+        Index of the next item.
+      */
+      private int index = 0;
+      /**
+        Collection size.
+      */
+      private int size = size();
+      // </fields>
+
+      // <interface>
+      // <public>
+      // <Iterator>
+      public boolean hasNext(
+        )
+      {return (index < size);}
+
+      public ChoiceItem next(
+        )
+      {
+        if(!hasNext())
+          throw new NoSuchElementException();
+
+        return get(index++);
+      }
+
+      public void remove(
+        )
+      {throw new UnsupportedOperationException();}
+      // </Iterator>
+      // </public>
+      // </interface>
+      // </dynamic>
+      // </class>
+    };
+  }
+  // </Iterable>
+  // </Collection>
+  // </List>
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/ComboBox.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/ComboBox.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/ComboBox.java	(revision 23703)
@@ -0,0 +1,125 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.forms;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.interaction.annotations.Widget;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.util.EnumSet;
+
+/**
+  Combo box [PDF:1.6:8.6.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.7
+  @since 0.0.7
+*/
+public class ComboBox
+  extends ChoiceField
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  /**
+    Creates a new combobox within the given document context.
+  */
+  public ComboBox(
+    String name,
+    Widget widget
+    )
+  {
+    super(
+      name,
+      widget
+      );
+
+    EnumSet<FlagsEnum> flags = getFlags(); flags.add(FlagsEnum.Combo); setFlags(flags);
+  }
+
+  public ComboBox(
+    PdfDirectObject baseObject
+    )
+  {super(baseObject);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public ComboBox clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    Gets whether the text is editable.
+  */
+  public boolean isEditable(
+    )
+  {return getFlags().contains(FlagsEnum.Edit);}
+
+  /**
+    Gets whether the edited text is spell checked.
+  */
+  public boolean isSpellChecked(
+    )
+  {return !getFlags().contains(FlagsEnum.DoNotSpellCheck);}
+
+  /**
+    @see #isEditable()
+  */
+  public void setEditable(
+    boolean value
+    )
+  {
+    EnumSet<FlagsEnum> flags = getFlags();
+    if(value)
+    {flags.add(FlagsEnum.Edit);}
+    else
+    {flags.remove(FlagsEnum.Edit);}
+    setFlags(flags);
+  }
+
+  /**
+    @see #isSpellChecked()
+  */
+  public void setSpellChecked(
+    boolean value
+    )
+  {
+    EnumSet<FlagsEnum> flags = getFlags();
+    if(value)
+    {flags.remove(FlagsEnum.DoNotSpellCheck);}
+    else
+    {flags.add(FlagsEnum.DoNotSpellCheck);}
+    setFlags(flags);
+  }
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/Field.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/Field.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/Field.java	(revision 23703)
@@ -0,0 +1,575 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.forms;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.interaction.annotations.Widget;
+import it.stefanochizzolini.clown.files.File;
+import it.stefanochizzolini.clown.objects.PdfAtomicObject;
+import it.stefanochizzolini.clown.objects.PdfDictionary;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfInteger;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfObjectWrapper;
+import it.stefanochizzolini.clown.objects.PdfReference;
+import it.stefanochizzolini.clown.objects.PdfString;
+import it.stefanochizzolini.clown.objects.PdfTextString;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.util.ArrayList;
+import java.util.EnumSet;
+import java.util.List;
+
+/**
+  Interactive form field [PDF:1.6:8.6.2].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8.1
+  @since 0.0.7
+*/
+public abstract class Field
+  extends PdfObjectWrapper<PdfDictionary>
+{
+  /*
+    NOTE: Inheritable attributes are NOT early-collected, as they are NOT part
+    of the explicit representation of a page. They are retrieved everytime
+    clients call.
+  */
+  // <class>
+  // <classes>
+  /**
+    Field flags [PDF:1.6:8.6.2].
+  */
+  public enum FlagsEnum
+  {
+    // <class>
+    // <static>
+    // <fields>
+    /**
+      The user may not change the value of the field.
+    */
+    ReadOnly(0x1),
+    /**
+      The field must have a value at the time it is exported by a submit-form action.
+    */
+    Required(0x2),
+    /**
+      The field must not be exported by a submit-form action.
+    */
+    NoExport(0x4),
+    /**
+      (Text fields only) The field can contain multiple lines of text.
+    */
+    Multiline(0x1000),
+    /**
+      (Text fields only) The field is intended for entering a secure password
+      that should not be echoed visibly to the screen.
+    */
+    Password(0x2000),
+    /**
+      (Radio buttons only) Exactly one radio button must be selected at all times.
+    */
+    NoToggleToOff(0x4000),
+    /**
+      (Button fields only) The field is a set of radio buttons (otherwise, a check box).
+      This flag is meaningful only if the Pushbutton flag isn't selected.
+    */
+    Radio(0x8000),
+    /**
+      (Button fields only) The field is a pushbutton that does not retain a permanent value.
+    */
+    Pushbutton(0x10000),
+    /**
+      (Choice fields only) The field is a combo box (otherwise, a list box).
+    */
+    Combo(0x20000),
+    /**
+      (Choice fields only) The combo box includes an editable text box as well as a dropdown list
+      (otherwise, it includes only a drop-down list).
+    */
+    Edit(0x40000),
+    /**
+      (Choice fields only) The field's option items should be sorted alphabetically.
+    */
+    Sort(0x80000),
+    /**
+      (Text fields only) Text entered in the field represents the pathname of a file
+      whose contents are to be submitted as the value of the field.
+    */
+    FileSelect(0x100000),
+    /**
+      (Choice fields only) More than one of the field's option items may be selected simultaneously.
+    */
+    MultiSelect(0x200000),
+    /**
+      (Choice and text fields only) Text entered in the field is not spell-checked.
+    */
+    DoNotSpellCheck(0x400000),
+    /**
+      (Text fields only) The field does not scroll to accommodate more text
+      than fits within its annotation rectangle.
+      Once the field is full, no further text is accepted.
+    */
+    DoNotScroll(0x800000),
+    /**
+      (Text fields only) The field is automatically divided into as many equally spaced positions,
+      or combs, as the value of MaxLen, and the text is laid out into those combs.
+    */
+    Comb(0x1000000),
+    /**
+      (Text fields only) The value of the field should be represented as a rich text string.
+    */
+    RichText(0x2000000),
+    /**
+      (Button fields only) A group of radio buttons within a radio button field that use
+      the same value for the on state will turn on and off in unison
+      (otherwise, the buttons are mutually exclusive).
+    */
+    RadiosInUnison(0x2000000),
+    /**
+      (Choice fields only) The new value is committed as soon as a selection is made with the pointing device.
+    */
+    CommitOnSelChange(0x4000000);
+    // </fields>
+
+    // <interface>
+    // <public>
+    /**
+      Converts an enumeration set into its corresponding bit mask representation.
+    */
+    public static int toInt(
+      EnumSet<FlagsEnum> flags
+      )
+    {
+      int flagsMask = 0;
+      for(FlagsEnum flag : flags)
+      {flagsMask |= flag.getCode();}
+
+      return flagsMask;
+    }
+
+    /**
+      Converts a bit mask into its corresponding enumeration representation.
+    */
+    public static EnumSet<FlagsEnum> toEnumSet(
+      int flagsMask
+      )
+    {
+      EnumSet<FlagsEnum> flags = EnumSet.noneOf(FlagsEnum.class);
+      for(FlagsEnum flag : FlagsEnum.values())
+      {
+        if((flagsMask & flag.getCode()) > 0)
+        {flags.add(flag);}
+      }
+
+      return flags;
+    }
+    // </public>
+    // </interface>
+    // </static>
+
+    // <dynamic>
+    // <fields>
+    /**
+      <h3>Remarks</h3>
+      <p>Bitwise code MUST be explicitly distinct from the ordinal position of the enum constant
+      as they don't coincide.</p>
+    */
+    private final int code;
+    // </fields>
+
+    // <constructors>
+    private FlagsEnum(
+      int code
+      )
+    {this.code = code;}
+    // </constructors>
+
+    // <interface>
+    // <public>
+    public int getCode(
+      )
+    {return code;}
+    // </public>
+    // </interface>
+    // </dynamic>
+    // </class>
+  }
+  // </classes>
+
+  // <static>
+  // <fields>
+  // </fields>
+
+  // <interface>
+  // <public>
+  /**
+    Wraps a field reference into a field object.
+
+    @param reference Reference to a field object.
+    @return Field object associated to the reference.
+  */
+  public static final Field wrap(
+    PdfReference reference
+    )
+  {
+    /*
+      NOTE: This is a factory method for any field-derived object.
+    */
+    if(reference == null)
+      return null;
+
+    PdfDictionary dataObject = (PdfDictionary)reference.getDataObject();
+    PdfName fieldType = (PdfName)dataObject.get(PdfName.FT);
+    PdfInteger fieldFlags = (PdfInteger)dataObject.get(PdfName.Ff);
+    int fieldFlagsValue = (fieldFlags == null ? 0 : fieldFlags.getRawValue());
+    if(fieldType.equals(PdfName.Btn)) // Button.
+    {
+      if((fieldFlagsValue & FlagsEnum.Pushbutton.getCode()) > 0) // Pushbutton.
+        return new PushButton(reference);
+      if((fieldFlagsValue & FlagsEnum.Radio.getCode()) > 0) // Radio.
+        return new RadioButton(reference);
+      // Check box.
+      return new CheckBox(reference);
+    }
+    if(fieldType.equals(PdfName.Tx)) // Text.
+      return new TextField(reference);
+    if(fieldType.equals(PdfName.Ch)) // Choice.
+    {
+      if((fieldFlagsValue & FlagsEnum.Combo.getCode()) > 0) // Combo box.
+        return new ComboBox(reference);
+      // List box.
+      return new ListBox(reference);
+    }
+    if(fieldType.equals(PdfName.Sig)) // Signature.
+      return new SignatureField(reference);
+    // Unknown.
+    return null;
+  }
+  // </public>
+  // </interface>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  /**
+    Creates a new field within the given document context.
+  */
+  protected Field(
+    PdfName fieldType,
+    String name,
+    Widget widget
+    )
+  {
+    this(widget.getBaseObject());
+
+    PdfDictionary baseDataObject = getBaseDataObject();
+    baseDataObject.put(PdfName.FT, fieldType);
+    baseDataObject.put(PdfName.T, new PdfTextString(name));
+  }
+
+  protected Field(
+    PdfDirectObject baseObject
+    )
+  {
+    super(
+      baseObject,
+      null // NO container (baseObject MUST be an indirect reference).
+      );
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public Field clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    Gets the field's behavior in response to trigger events.
+  */
+  public FieldActions getActions(
+    )
+  {
+    PdfDirectObject actionsObject = getBaseDataObject().get(PdfName.AA);
+    if(actionsObject == null)
+      return null;
+
+    return new FieldActions(actionsObject,getContainer());
+  }
+
+  /**
+    Gets the field default value.
+  */
+  public Object getDefaultValue(
+    )
+  {
+    PdfAtomicObject<?> defaultValueObject = (PdfAtomicObject<?>)File.resolve(
+      getInheritableAttribute(PdfName.DV)
+      );
+    if(defaultValueObject == null)
+      return null;
+
+    return defaultValueObject.getValue();
+  }
+
+  /**
+    Gets the field flags.
+  */
+  public EnumSet<FlagsEnum> getFlags(
+    )
+  {
+    PdfInteger flagsObject = (PdfInteger)File.resolve(
+      getInheritableAttribute(PdfName.Ff)
+      );
+    if(flagsObject == null)
+      return EnumSet.noneOf(FlagsEnum.class);
+
+    return FlagsEnum.toEnumSet(flagsObject.getRawValue());
+  }
+
+  /**
+    Gets the widget annotations that are associated with this field.
+  */
+  public FieldWidgets getWidgets(
+    )
+  {
+    /*
+      NOTE: Terminal fields MUST be associated at least to one widget annotation.
+      If there is only one associated widget annotation and its contents
+      have been merged into the field dictionary, 'Kids' entry MUST be omitted.
+    */
+    PdfDirectObject widgetsObject = getBaseDataObject().get(PdfName.Kids);
+    if(widgetsObject == null) // Merged annotation.
+      return new FieldWidgets(getBaseObject(), null, this);
+    else // Annotation array.
+    	return new FieldWidgets(widgetsObject, getContainer(), this);
+  }
+
+  /**
+    Gets the fully-qualified field name.
+  */
+  public String getFullName(
+    )
+  {
+    List<String> partialNames = new ArrayList<String>();
+    PdfDictionary parent = getBaseDataObject();
+    while(parent != null)
+    {
+      partialNames.add((String)((PdfTextString)parent.get(PdfName.T)).getValue());
+
+      parent = (PdfDictionary)File.resolve(parent.get(PdfName.Parent));
+    }
+
+    StringBuilder buffer = new StringBuilder();
+    for(
+      int index = partialNames.size() - 1;
+      index >= 0;
+      index--
+      )
+    {
+      buffer.append(partialNames.get(index));
+      if(index > 0)
+      {buffer.append(".");}
+    }
+
+    return buffer.toString();
+  }
+
+  /**
+    Gets the partial field name.
+  */
+  public String getName(
+    )
+  {return (String)((PdfTextString)getBaseDataObject().get(PdfName.T)).getValue();}
+
+  /**
+    Gets the field value.
+  */
+  public Object getValue(
+    )
+  {
+    PdfAtomicObject<?> valueObject = (PdfAtomicObject<?>)File.resolve(
+      getInheritableAttribute(PdfName.V)
+      );
+    if(valueObject == null)
+      return null;
+
+    return valueObject.getValue();
+  }
+
+  /**
+    Gets whether the field is exported by a submit-form action.
+  */
+  public boolean isExportable(
+    )
+  {return !getFlags().contains(FlagsEnum.NoExport);}
+
+  /**
+    Gets whether the user may not change the value of the field.
+  */
+  public boolean isReadOnly(
+    )
+  {return getFlags().contains(FlagsEnum.ReadOnly);}
+
+  /**
+    Gets whether the field must have a value at the time
+    it is exported by a submit-form action.
+  */
+  public boolean isRequired(
+    )
+  {return getFlags().contains(FlagsEnum.Required);}
+
+  /**
+    @see #getActions()
+  */
+  public void setActions(
+    FieldActions value
+    )
+  {getBaseDataObject().put(PdfName.AA,value.getBaseObject());}
+
+  /**
+    @see #isExportable()
+  */
+  public void setExportable(
+    boolean value
+    )
+  {
+    EnumSet<FlagsEnum> flags = getFlags();
+    if(value)
+    {flags.remove(FlagsEnum.NoExport);}
+    else
+    {flags.add(FlagsEnum.NoExport);}
+    setFlags(flags);
+  }
+
+  /**
+    @see #getFlags()
+  */
+  public void setFlags(
+    EnumSet<FlagsEnum> value
+    )
+  {
+    /*
+      NOTE: As flags may be inherited from a parent field dictionary,
+      we MUST ensure that the change will affect just this one;
+      so, if such flags are implicit (inherited), they MUST be cloned
+      and explicitly assigned to this field in order to apply changes.
+    */
+    PdfDictionary baseDataObject = getBaseDataObject();
+    PdfInteger entry = (PdfInteger)baseDataObject.get(PdfName.Ff);
+    if(entry == null) // Implicit flags.
+    {
+      // Clone the inherited attribute in order to restrict its change to this field's scope only!
+      entry = (PdfInteger)getInheritableAttribute(PdfName.Ff).clone(getFile());
+      // Associate the cloned attribute to this field's dictionary!
+      baseDataObject.put(PdfName.Ff,entry);
+    }
+
+    entry.setRawValue(FlagsEnum.toInt(value));
+  }
+
+  /**
+    @see #getName()
+  */
+  public void setName(
+    String value
+    )
+  {getBaseDataObject().put(PdfName.T, new PdfTextString(value));}
+
+  /**
+    @see #isReadOnly()
+  */
+  public void setReadOnly(
+    boolean value
+    )
+  {
+    EnumSet<FlagsEnum> flags = getFlags();
+    if(value)
+    {flags.add(FlagsEnum.ReadOnly);}
+    else
+    {flags.remove(FlagsEnum.ReadOnly);}
+    setFlags(flags);
+  }
+
+  /**
+    @see #isRequired()
+  */
+  public void setRequired(
+    boolean value
+    )
+  {
+    EnumSet<FlagsEnum> flags = getFlags();
+    if(value)
+    {flags.add(FlagsEnum.Required);}
+    else
+    {flags.remove(FlagsEnum.Required);}
+    setFlags(flags);
+  }
+
+  /**
+    @see #getValue()
+  */
+  public void setValue(
+    Object value
+    )
+  {getBaseDataObject().put(PdfName.V, new PdfString((String)value));}
+  // </public>
+
+  // <protected>
+  protected PdfDirectObject getInheritableAttribute(
+    PdfName key
+    )
+  {
+    /*
+      NOTE: It moves upward until it finds the inherited attribute.
+    */
+    PdfDictionary dictionary = getBaseDataObject();
+    while(true)
+    {
+      PdfDirectObject entry = dictionary.get(key);
+      if(entry != null)
+        return entry;
+
+      dictionary = (PdfDictionary)File.resolve(
+        dictionary.get(PdfName.Parent)
+        );
+      if(dictionary == null)
+      {
+        if(key.equals(PdfName.Ff))
+          return new PdfInteger(0);
+
+        return null;
+      }
+    }
+  }
+  // </protected>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/FieldActions.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/FieldActions.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/FieldActions.java	(revision 23703)
@@ -0,0 +1,180 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.forms;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.interaction.actions.Action;
+import it.stefanochizzolini.clown.documents.interaction.actions.JavaScript;
+import it.stefanochizzolini.clown.objects.PdfDictionary;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfObjectWrapper;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+/**
+  Form field actions [PDF:1.6:8.5.2].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.7
+  @since 0.0.7
+*/
+public class FieldActions
+  extends PdfObjectWrapper<PdfDictionary>
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  public FieldActions(
+    Document context
+    )
+  {
+    super(
+      context.getFile(),
+      new PdfDictionary()
+      );
+  }
+
+  public FieldActions(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {super(baseObject,container);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public FieldActions clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    Gets a JavaScript action to be performed to recalculate the value
+    of this field when that of another field changes.
+  */
+  public JavaScript getOnCalculate(
+    )
+  {
+    /*
+      NOTE: 'C' entry may be undefined.
+    */
+    PdfDirectObject onCalculateObject = getBaseDataObject().get(PdfName.C);
+    if(onCalculateObject == null)
+      return null;
+
+    return (JavaScript)Action.wrap(onCalculateObject,getContainer());
+  }
+
+  /**
+    Gets a JavaScript action to be performed when the user types a keystroke
+    into a text field or combo box or modifies the selection in a scrollable list box.
+  */
+  public JavaScript getOnChange(
+    )
+  {
+    /*
+      NOTE: 'K' entry may be undefined.
+    */
+    PdfDirectObject onChangeObject = getBaseDataObject().get(PdfName.K);
+    if(onChangeObject == null)
+      return null;
+
+    return (JavaScript)Action.wrap(onChangeObject,getContainer());
+  }
+
+  /**
+    Gets a JavaScript action to be performed before the field is formatted
+    to display its current value.
+    <p>This action can modify the field's value before formatting.</p>
+  */
+  public JavaScript getOnFormat(
+    )
+  {
+    /*
+      NOTE: 'F' entry may be undefined.
+    */
+    PdfDirectObject onFormatObject = getBaseDataObject().get(PdfName.F);
+    if(onFormatObject == null)
+      return null;
+
+    return (JavaScript)Action.wrap(onFormatObject,getContainer());
+  }
+
+  /**
+    Gets a JavaScript action to be performed when the field's value is changed.
+    This action can check the new value for validity.
+  */
+  public JavaScript getOnValidate(
+    )
+  {
+    /*
+      NOTE: 'V' entry may be undefined.
+    */
+    PdfDirectObject onValidateObject = getBaseDataObject().get(PdfName.V);
+    if(onValidateObject == null)
+      return null;
+
+    return (JavaScript)Action.wrap(onValidateObject,getContainer());
+  }
+
+  /**
+    @see #getOnCalculate()
+  */
+  public void setOnCalculate(
+    JavaScript value
+    )
+  {getBaseDataObject().put(PdfName.C, value.getBaseObject());}
+
+  /**
+    @see #getOnChange()
+  */
+  public void setOnChange(
+    JavaScript value
+    )
+  {getBaseDataObject().put(PdfName.K, value.getBaseObject());}
+
+  /**
+    @see #getOnFormat()
+  */
+  public void setOnFormat(
+    JavaScript value
+    )
+  {getBaseDataObject().put(PdfName.F, value.getBaseObject());}
+
+  /**
+    @see #getOnValidate()
+  */
+  public void setOnValidate(
+    JavaScript value
+    )
+  {getBaseDataObject().put(PdfName.V, value.getBaseObject());}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/FieldWidgets.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/FieldWidgets.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/FieldWidgets.java	(revision 23703)
@@ -0,0 +1,460 @@
+/*
+  Copyright 2008-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.forms;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.interaction.annotations.DualWidget;
+import it.stefanochizzolini.clown.documents.interaction.annotations.Widget;
+import it.stefanochizzolini.clown.files.File;
+import it.stefanochizzolini.clown.objects.PdfArray;
+import it.stefanochizzolini.clown.objects.PdfDataObject;
+import it.stefanochizzolini.clown.objects.PdfDictionary;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfObjectWrapper;
+import it.stefanochizzolini.clown.objects.PdfReference;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.NoSuchElementException;
+
+/**
+  Field widget annotations [PDF:1.6:8.6].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+  @since 0.0.7
+*/
+public class FieldWidgets
+  extends PdfObjectWrapper<PdfDataObject>
+  implements List<Widget>
+{
+  /*
+    NOTE: Widget annotations may be singular (either merged to their field or within an array)
+    or multiple (within an array).
+    This implementation hides such a complexity to the user, smoothly exposing just the most
+    general case (array) yet preserving its internal state.
+  */
+  // <class>
+  // <dynamic>
+  // <fields>
+  private Field field;
+
+  private boolean isDual;
+  // </fields>
+
+  // <constructors>
+  FieldWidgets(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container,
+    Field field
+    )
+  {
+    super(
+      baseObject,
+      container
+      );
+
+    this.field = field;
+
+    isDual = (field instanceof CheckBox
+      || field instanceof RadioButton);
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public FieldWidgets clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    Gets the field associated to these widgets.
+  */
+  public Field getField(
+    )
+  {return field;}
+
+  // <List>
+  public void add(
+    int index,
+    Widget value
+    )
+  {ensureArray().add(index,value.getBaseObject());}
+
+  public boolean addAll(
+    int index,
+    Collection<? extends Widget> values
+    )
+  {
+    PdfArray items = ensureArray();
+    for(Widget value : values)
+    {items.add(index++,value.getBaseObject());}
+
+    return true;
+  }
+
+  public Widget get(
+    int index
+    )
+  {
+    PdfDataObject baseDataObject = getBaseDataObject();
+    if(baseDataObject instanceof PdfDictionary) // Single annotation.
+    {
+      if(index != 0)
+        throw new IndexOutOfBoundsException("Index: " + index + ", Size: 1");
+
+      return newWidget(getBaseObject());
+    }
+    else // Array.
+    {
+      return newWidget(((PdfArray)baseDataObject).get(index));
+    }
+  }
+
+  public int indexOf(
+    Object value
+    )
+  {
+    if(!(value instanceof Widget))
+      return -1;
+
+    PdfDataObject baseDataObject = getBaseDataObject();
+    if(baseDataObject instanceof PdfDictionary) // Single annotation.
+    {
+      if(((Widget)value).getBaseObject().equals(getBaseObject()))
+        return 0;
+      else
+        return -1;
+    }
+
+    return ((PdfArray)baseDataObject).indexOf(((Widget)value).getBaseObject());
+  }
+
+  public int lastIndexOf(
+    Object value
+    )
+  {
+    /*
+      NOTE: Widgets are expected not to be duplicate.
+    */
+    return indexOf(value);
+  }
+
+  public ListIterator<Widget> listIterator(
+    )
+  {throw new NotImplementedException();}
+
+  public ListIterator<Widget> listIterator(
+    int index
+    )
+  {throw new NotImplementedException();}
+
+  public Widget remove(
+    int index
+    )
+  {
+    PdfDirectObject widgetObject = ensureArray().remove(index);
+
+    return newWidget(widgetObject);
+  }
+
+  public Widget set(
+    int index,
+    Widget value
+    )
+  {return newWidget(ensureArray().set(index,value.getBaseObject()));}
+
+  public List<Widget> subList(
+    int fromIndex,
+    int toIndex
+    )
+  {throw new NotImplementedException();}
+
+  // <Collection>
+  public boolean add(
+    Widget value
+    )
+  {
+    value.getBaseDataObject().put(PdfName.Parent,field.getBaseObject());
+
+    return ensureArray().add(value.getBaseObject());
+  }
+
+  public boolean addAll(
+    Collection<? extends Widget> values
+    )
+  {
+    for(Widget value : values)
+    {add(value);}
+
+    return true;
+  }
+
+  public void clear(
+    )
+  {ensureArray().clear();}
+
+  public boolean contains(
+    Object value
+    )
+  {
+    if(!(value instanceof Widget))
+      return false;
+
+    PdfDataObject baseDataObject = getBaseDataObject();
+    if(baseDataObject instanceof PdfDictionary) // Single annotation.
+      return ((Widget)value).getBaseObject().equals(getBaseObject());
+
+    return ((PdfArray)baseDataObject).contains(((Widget)value).getBaseObject());
+  }
+
+  public boolean containsAll(
+    Collection<?> values
+    )
+  {throw new NotImplementedException();}
+
+  public boolean equals(
+    Object object
+    )
+  {throw new NotImplementedException();}
+
+  public int hashCode(
+    )
+  {throw new NotImplementedException();}
+
+  public boolean isEmpty(
+    )
+  {
+    PdfDataObject baseDataObject = getBaseDataObject();
+    if(baseDataObject instanceof PdfDictionary) // Single annotation.
+      return false;
+    else // Array.
+      return ((PdfArray)baseDataObject).isEmpty();
+  }
+
+  public boolean remove(
+    Object value
+    )
+  {
+    if(!(value instanceof Widget))
+      return false;
+
+    return ensureArray().remove(((Widget)value).getBaseObject());
+  }
+
+  public boolean removeAll(
+    Collection<?> values
+    )
+  {throw new NotImplementedException();}
+
+  public boolean retainAll(
+    Collection<?> values
+    )
+  {throw new NotImplementedException();}
+
+  public int size(
+    )
+  {
+    PdfDataObject baseDataObject = getBaseDataObject();
+    if(baseDataObject instanceof PdfDictionary) // Single annotation.
+      return 1;
+    else // Array.
+      return ((PdfArray)baseDataObject).size();
+  }
+
+  public Object[] toArray(
+    )
+  {return toArray(new Widget[0]);}
+
+  @SuppressWarnings("unchecked")
+  public <T> T[] toArray(
+    T[] values
+    )
+  {
+    PdfDataObject baseDataObject = getBaseDataObject();
+    if(baseDataObject instanceof PdfDictionary) // Single annotation.
+    {
+      if(values.length == 0)
+      {values = (T[])new Object[1];}
+
+      values[0] = (T)newWidget(getBaseObject());
+    }
+    else // Array.
+    {
+      PdfArray widgetObjects = (PdfArray)baseDataObject;
+      if(values.length < widgetObjects.size())
+      {values = (T[])new Object[widgetObjects.size()];}
+
+      for(
+        int index = 0,
+          length = widgetObjects.size();
+        index < length;
+        index++
+        )
+      {values[index] = (T)newWidget(widgetObjects.get(index));}
+    }
+    return values;
+  }
+
+  // <Iterable>
+  public Iterator<Widget> iterator(
+    )
+  {
+    return new Iterator<Widget>()
+    {
+      // <class>
+      // <dynamic>
+      // <fields>
+      /**
+        Index of the next item.
+      */
+      private int index = 0;
+      /**
+        Collection size.
+      */
+      private int size = size();
+      // </fields>
+
+      // <interface>
+      // <public>
+      // <Iterator>
+      public boolean hasNext(
+        )
+      {return (index < size);}
+
+      public Widget next(
+        )
+      {
+        if(!hasNext())
+          throw new NoSuchElementException();
+
+        return get(index++);
+      }
+
+      public void remove(
+        )
+      {throw new UnsupportedOperationException();}
+      // </Iterator>
+      // </public>
+      // </interface>
+      // </dynamic>
+      // </class>
+    };
+  }
+  // </Iterable>
+  // </Collection>
+  // </List>
+  // </public>
+
+  // <private>
+  private PdfArray ensureArray(
+    )
+  {
+    PdfDataObject baseDataObject = getBaseDataObject();
+    if(baseDataObject instanceof PdfDictionary) // Merged annotation.
+    {
+      PdfArray widgetsArray = new PdfArray();
+      {
+        PdfDictionary fieldDictionary = (PdfDictionary)baseDataObject;
+        PdfDictionary widgetDictionary = null;
+        // Extracting widget entries from the field...
+        for(PdfName key : new HashMap<PdfName,PdfDirectObject>(fieldDictionary).keySet())
+        {
+          // Is it a widget entry?
+          if(key.equals(PdfName.Type)
+            || key.equals(PdfName.Subtype)
+            || key.equals(PdfName.Rect)
+            || key.equals(PdfName.Contents)
+            || key.equals(PdfName.P)
+            || key.equals(PdfName.NM)
+            || key.equals(PdfName.M)
+            || key.equals(PdfName.F)
+            || key.equals(PdfName.BS)
+            || key.equals(PdfName.AP)
+            || key.equals(PdfName.AS)
+            || key.equals(PdfName.Border)
+            || key.equals(PdfName.C)
+            || key.equals(PdfName.A)
+            || key.equals(PdfName.AA)
+            || key.equals(PdfName.StructParent)
+            || key.equals(PdfName.OC)
+            || key.equals(PdfName.H)
+            || key.equals(PdfName.MK))
+          {
+            if(widgetDictionary == null)
+            {
+              widgetDictionary = new PdfDictionary();
+              PdfReference widgetReference = getFile().register(widgetDictionary);
+
+              // Remove the field from the page annotations (as the widget annotation is decoupled from it)!
+              PdfArray pageAnnotationsArray = (PdfArray)File.resolve(((PdfDictionary)File.resolve(fieldDictionary.get(PdfName.P))).get(PdfName.Annots));
+              pageAnnotationsArray.remove(field.getBaseObject());
+
+              // Add the widget to the page annotations!
+              pageAnnotationsArray.add(widgetReference);
+              // Add the widget to the field widgets!
+              widgetsArray.add(widgetReference);
+              // Associate the field to the widget!
+              widgetDictionary.put(PdfName.Parent,field.getBaseObject());
+            }
+
+            // Transfer the entry from the field to the widget!
+            widgetDictionary.put(key,fieldDictionary.get(key));
+            fieldDictionary.remove(key);
+          }
+        }
+      }
+      setBaseObject(widgetsArray);
+      field.getBaseDataObject().put(PdfName.Kids,widgetsArray);
+
+      baseDataObject = widgetsArray;
+    }
+
+    return (PdfArray)baseDataObject;
+  }
+
+  private Widget newWidget(
+    PdfDirectObject baseObject
+    )
+  {
+    if(isDual)
+      return new DualWidget(baseObject,getContainer());
+    else
+      return new Widget(baseObject,getContainer());
+  }
+  // </private>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/Fields.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/Fields.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/Fields.java	(revision 23703)
@@ -0,0 +1,223 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.forms;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.files.File;
+import it.stefanochizzolini.clown.objects.PdfArray;
+import it.stefanochizzolini.clown.objects.PdfDictionary;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfObjectWrapper;
+import it.stefanochizzolini.clown.objects.PdfReference;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Map;
+import java.util.List;
+import java.util.Set;
+
+/**
+  Interactive form fields [PDF:1.6:8.6.1].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.7
+  @since 0.0.7
+*/
+public class Fields
+  extends PdfObjectWrapper<PdfArray>
+  implements Map<String,Field>
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  public Fields(
+    Document context
+    )
+  {
+    super(
+      context.getFile(),
+      new PdfArray()
+      );
+  }
+
+  Fields(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {super(baseObject,container);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  public boolean add(
+    Field value
+    )
+  {
+    getBaseDataObject().add(value.getBaseObject());
+
+    return true;
+  }
+
+  @Override
+  public Fields clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  // <Map>
+  public void clear(
+    )
+  {
+    //TODO:verify whether to recursively unregister the fields!!!
+    getBaseDataObject().clear();
+  }
+
+  public boolean containsKey(
+    Object key
+    )
+  {throw new NotImplementedException();}
+
+  public boolean containsValue(
+    Object value
+    )
+  {throw new NotImplementedException();}
+
+  public Set<Map.Entry<String,Field>> entrySet(
+    )
+  {throw new NotImplementedException();}
+
+  public boolean equals(
+    PdfDirectObject object
+    )
+  {throw new NotImplementedException();}
+
+  public Field get(
+    Object key
+    )
+  {throw new NotImplementedException();}
+
+  public int hashCode(
+    )
+  {throw new NotImplementedException();}
+
+  public boolean isEmpty(
+    )
+  {
+    throw new NotImplementedException();
+  //TODO:verify whether the fields collection is empty!!!
+//     return getBaseDataObject().isEmpty();
+  }
+
+  public Set<String> keySet(
+    )
+  {
+    throw new NotImplementedException();
+  //TODO: retrieve all the full names (keys)!!!
+//     return getBaseDataObject().keySet();
+  }
+
+  public Field put(
+    String key,
+    Field value
+    )
+  {
+    throw new NotImplementedException();
+/*
+TODO:put the field into the correct position, based on the full name (key)!!!
+  return Field.wrap(
+      getBaseDataObject().put(key,value.getBaseObject())
+      );*/
+  }
+
+  public void putAll(
+    Map<? extends String,? extends Field> entries
+    )
+  {throw new NotImplementedException();}
+
+  public Field remove(
+    Object key
+    )
+  {
+    throw new NotImplementedException();
+/*
+TODO:search through the full name (key)!
+    return Field.wrap(
+      getBaseDataObject().remove(key)
+      );*/
+  }
+
+  public int size(
+    )
+  {return getBaseDataObject().size();}
+
+  public Collection<Field> values(
+    )
+  {
+    List<Field> values = new ArrayList<Field>();
+    retrieveValues(getBaseDataObject(), values);
+
+    return values;
+  }
+  // </Map>
+  // </public>
+
+  // <private>
+  private void retrieveValues(
+    PdfArray fieldObjects,
+    List<Field> values
+    )
+  {
+    for(
+      PdfDirectObject fieldObject : fieldObjects
+      )
+    {
+      PdfReference fieldReference = (PdfReference)fieldObject;
+      PdfArray kidReferences = (PdfArray)File.resolve(
+        ((PdfDictionary)fieldReference.getDataObject()).get(PdfName.Kids)
+        );
+      PdfDictionary kidObject;
+      if(kidReferences == null)
+      {kidObject = null;}
+      else
+      {kidObject = (PdfDictionary)((PdfReference)kidReferences.get(0)).getDataObject();}
+      // Terminal field?
+      if(kidObject == null // Merged single widget annotation.
+        || (!kidObject.containsKey(PdfName.FT) // Multiple widget annotations.
+          && kidObject.containsKey(PdfName.Subtype)
+          && kidObject.get(PdfName.Subtype).equals(PdfName.Widget)))
+      {values.add(Field.wrap(fieldReference));}
+      else // Non-terminal field.
+      {retrieveValues(kidReferences, values);}
+    }
+  }
+  // </private>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/Form.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/Form.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/Form.java	(revision 23703)
@@ -0,0 +1,127 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.forms;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.contents.Resources;
+import it.stefanochizzolini.clown.objects.PdfArray;
+import it.stefanochizzolini.clown.objects.PdfDictionary;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfObjectWrapper;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+/**
+  Interactive form (AcroForm) [PDF:1.6:8.6.1].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.7
+  @since 0.0.7
+*/
+public class Form
+  extends PdfObjectWrapper<PdfDictionary>
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  public Form(
+    Document context
+    )
+  {
+    super(
+      context.getFile(),
+      new PdfDictionary(
+        new PdfName[]
+        {PdfName.Fields},
+        new PdfDirectObject[]
+        {new PdfArray()}
+        )
+      );
+  }
+
+  public Form(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {super(baseObject,container);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public Form clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    Gets the fields collection.
+  */
+  public Fields getFields(
+    )
+  {return new Fields(getBaseDataObject().get(PdfName.Fields), getContainer());}
+
+  /**
+    Gets the default resources used by fields.
+  */
+  public Resources getResources(
+    )
+  {
+    /*
+      NOTE: Resources entry may be undefined.
+    */
+    PdfDirectObject resourcesObject = getBaseDataObject().get(PdfName.DR);
+    if(resourcesObject == null)
+      return null;
+
+    return new Resources(resourcesObject, getContainer());
+  }
+
+  /**
+    Sets the fields collection.
+
+    @see #getFields()
+  */
+  public void setFields(
+    Fields value
+    )
+  {getBaseDataObject().put(PdfName.Fields, value.getBaseObject());}
+
+  /**
+    Sets the default resources used by fields.
+
+    @see #getResources()
+  */
+  public void setResources(
+    Resources value
+    )
+  {getBaseDataObject().put(PdfName.DR, value.getBaseObject());}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/ListBox.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/ListBox.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/ListBox.java	(revision 23703)
@@ -0,0 +1,77 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.forms;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.interaction.annotations.Widget;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+/**
+  List box [PDF:1.6:8.6.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.7
+  @version 0.0.7
+*/
+public class ListBox
+  extends ChoiceField
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  /**
+    Creates a new listbox within the given document context.
+  */
+  public ListBox(
+    String name,
+    Widget widget
+    )
+  {
+    super(
+      name,
+      widget
+      );
+  }
+
+  public ListBox(
+    PdfDirectObject baseObject
+    )
+  {super(baseObject);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public ListBox clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/PushButton.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/PushButton.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/PushButton.java	(revision 23703)
@@ -0,0 +1,83 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.forms;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.interaction.annotations.Widget;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.util.EnumSet;
+
+/**
+  Pushbutton field [PDF:1.6:8.6.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.7
+  @since 0.0.7
+*/
+public class PushButton
+  extends ButtonField
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  /**
+    Creates a new pushbutton within the given document context.
+  */
+  public PushButton(
+    String name,
+    Widget widget,
+    String caption
+    )
+  {
+    super(
+      name,
+      widget
+      );
+
+    EnumSet<FlagsEnum> flags = getFlags(); flags.add(FlagsEnum.Pushbutton); setFlags(flags);
+    setValue(caption);
+  }
+
+  public PushButton(
+    PdfDirectObject baseObject
+    )
+  {super(baseObject);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public PushButton clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/RadioButton.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/RadioButton.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/RadioButton.java	(revision 23703)
@@ -0,0 +1,142 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.forms;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.interaction.annotations.DualWidget;
+import it.stefanochizzolini.clown.documents.interaction.annotations.Widget;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.util.EnumSet;
+
+/**
+  Radio button field [PDF:1.6:8.6.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.7
+  @since 0.0.7
+*/
+public class RadioButton
+  extends ButtonField
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  /**
+    Creates a new radiobutton within the given document context.
+  */
+  public RadioButton(
+    String name,
+    DualWidget[] widgets,
+    String value
+    )
+  {
+    super(
+      name,
+      widgets[0]
+      );
+
+    EnumSet<FlagsEnum> flags = getFlags(); flags.add(FlagsEnum.Radio); flags.add(FlagsEnum.NoToggleToOff); setFlags(flags);
+
+    FieldWidgets fieldWidgets = getWidgets();
+    for(
+      int index = 1,
+        length = widgets.length;
+      index < length;
+      index++
+      )
+    {fieldWidgets.add(widgets[index]);}
+
+    setValue(value);
+  }
+
+  public RadioButton(
+    PdfDirectObject baseObject
+    )
+  {super(baseObject);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public RadioButton clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    Gets whether all the field buttons can be deselected at the same time.
+  */
+  public boolean isToggleable(
+    )
+  {return !getFlags().contains(FlagsEnum.NoToggleToOff);}
+
+  /**
+    @see #isToggleable()
+  */
+  public void setToggleable(
+    boolean value
+    )
+  {
+    EnumSet<FlagsEnum> flags = getFlags();
+    if(value)
+    {flags.remove(FlagsEnum.NoToggleToOff);}
+    else
+    {flags.add(FlagsEnum.NoToggleToOff);}
+    setFlags(flags);
+  }
+
+  @Override
+  public void setValue(
+    Object value
+    )
+  {
+    PdfName selectedWidgetName = new PdfName((String)value);
+    boolean selected = false;
+    // Selecting the current appearance state for each widget...
+    for(Widget widget : getWidgets())
+    {
+      PdfName currentState;
+      if(((DualWidget)widget).getWidgetName().equals(value)) // Selected state.
+      {
+        selected = true;
+        currentState = selectedWidgetName;
+      }
+      else // Unselected state.
+      {currentState = PdfName.Off;}
+
+      widget.getBaseDataObject().put(PdfName.AS,currentState);
+    }
+    // Select the current widget!
+    getBaseDataObject().put(PdfName.V, selected ? selectedWidgetName : null);
+  }
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/SignatureField.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/SignatureField.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/SignatureField.java	(revision 23703)
@@ -0,0 +1,81 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.forms;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.interaction.annotations.Widget;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+/**
+  Signature field [PDF:1.6:8.6.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.7
+  @since 0.0.7
+*/
+public class SignatureField
+  extends Field
+{
+  //TODO
+  // <class>
+  // <dynamic>
+  // <constructors>
+  /**
+    Creates a new signature field within the given document context.
+  */
+  public SignatureField(
+    String name,
+    Widget widget
+    )
+  {
+//TODO:dictionary mandatory items (if any)!!!
+    super(
+      PdfName.Sig,
+      name,
+      widget
+      );
+  }
+
+  public SignatureField(
+    PdfDirectObject baseObject
+    )
+  {super(baseObject);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public SignatureField clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/TextField.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/TextField.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/TextField.java	(revision 23703)
@@ -0,0 +1,185 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.forms;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.interaction.annotations.Widget;
+import it.stefanochizzolini.clown.files.File;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfInteger;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfTextString;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.util.EnumSet;
+
+/**
+  Text field [PDF:1.6:8.6.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.7
+  @since 0.0.7
+*/
+public class TextField
+  extends Field
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  /**
+    Creates a new text field within the given document context.
+  */
+  public TextField(
+    String name,
+    Widget widget,
+    String value
+    )
+  {
+    super(
+      PdfName.Tx,
+      name,
+      widget
+      );
+
+    setValue(value);
+  }
+
+  public TextField(
+    PdfDirectObject baseObject
+    )
+  {super(baseObject);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public TextField clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    Gets the maximum length of the field's text, in characters.
+  */
+  public int getMaxLength(
+    )
+  {
+    PdfInteger maxLengthObject = (PdfInteger)File.resolve(
+      getInheritableAttribute(PdfName.MaxLen)
+      );
+    if(maxLengthObject == null)
+      return Integer.MAX_VALUE;//TODO:verify!!!
+
+    return maxLengthObject.getRawValue();
+  }
+
+  /**
+    Gets whether the field can contain multiple lines of text.
+  */
+  public boolean isMultiline(
+    )
+  {return getFlags().contains(FlagsEnum.Multiline);}
+
+  /**
+    Gets whether the field is intended for entering a secure password.
+  */
+  public boolean isPassword(
+    )
+  {return getFlags().contains(FlagsEnum.Password);}
+
+  /**
+    Gets whether text entered in the field is spell-checked.
+  */
+  public boolean isSpellChecked(
+    )
+  {return !getFlags().contains(FlagsEnum.DoNotSpellCheck);}
+
+  /**
+    @see #getMaxLength()
+  */
+  public void setMaxLength(
+    int value
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    @see #isMultiline()
+  */
+  public void setMultiline(
+    boolean value
+    )
+  {
+    EnumSet<FlagsEnum> flags = getFlags();
+    if(value)
+    {flags.add(FlagsEnum.Multiline);}
+    else
+    {flags.remove(FlagsEnum.Multiline);}
+    setFlags(flags);
+  }
+
+  /**
+    @see #isPassword()
+  */
+  public void setPassword(
+    boolean value
+    )
+  {
+    EnumSet<FlagsEnum> flags = getFlags();
+    if(value)
+    {flags.add(FlagsEnum.Password);}
+    else
+    {flags.remove(FlagsEnum.Password);}
+    setFlags(flags);
+  }
+
+  /**
+    @see #isSpellChecked()
+  */
+  public void setSpellChecked(
+    boolean value
+    )
+  {
+    EnumSet<FlagsEnum> flags = getFlags();
+    if(value)
+    {flags.remove(FlagsEnum.DoNotSpellCheck);}
+    else
+    {flags.add(FlagsEnum.DoNotSpellCheck);}
+    setFlags(flags);
+  }
+
+  @Override
+  public void setValue(
+    Object value
+    )
+  {
+    getBaseDataObject().put(PdfName.V,new PdfTextString((String)value));
+    getBaseDataObject().put(PdfName.DV,new PdfTextString((String)value));
+  }
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/package.html
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/package.html	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/package.html	(revision 23703)
@@ -0,0 +1,38 @@
+<html>
+<head>
+<!--
+  Copyright 2008-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+-->
+</head>
+<body>
+<p>Interactive forms (aka AcroForm) used to gather information interactively
+from the user [PDF:1.6:8.6].</p>
+
+<h2>Related Documentation</h2>
+<p>For overviews, tutorials, examples, guides, and tool documentation, please see:</p>
+<ul>
+  <li><a href="http://clown.stefanochizzolini.it">PDF Clown Home Page</a>
+</ul>
+</body>
+</html>
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/styles/DefaultStyle.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/styles/DefaultStyle.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/styles/DefaultStyle.java	(revision 23703)
@@ -0,0 +1,587 @@
+/*
+  Copyright 2008-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.forms.styles;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.contents.colorSpaces.DeviceRGBColor;
+import it.stefanochizzolini.clown.documents.contents.composition.AlignmentXEnum;
+import it.stefanochizzolini.clown.documents.contents.composition.AlignmentYEnum;
+import it.stefanochizzolini.clown.documents.contents.composition.BlockFilter;
+import it.stefanochizzolini.clown.documents.contents.composition.PrimitiveFilter;
+import it.stefanochizzolini.clown.documents.contents.fonts.StandardType1Font;
+import it.stefanochizzolini.clown.documents.contents.xObjects.FormXObject;
+import it.stefanochizzolini.clown.documents.interaction.annotations.Appearance;
+import it.stefanochizzolini.clown.documents.interaction.annotations.AppearanceStates;
+import it.stefanochizzolini.clown.documents.interaction.annotations.DualWidget;
+import it.stefanochizzolini.clown.documents.interaction.annotations.Widget;
+import it.stefanochizzolini.clown.documents.interaction.forms.CheckBox;
+import it.stefanochizzolini.clown.documents.interaction.forms.ChoiceItem;
+import it.stefanochizzolini.clown.documents.interaction.forms.ComboBox;
+import it.stefanochizzolini.clown.documents.interaction.forms.Field;
+import it.stefanochizzolini.clown.documents.interaction.forms.ListBox;
+import it.stefanochizzolini.clown.documents.interaction.forms.PushButton;
+import it.stefanochizzolini.clown.documents.interaction.forms.RadioButton;
+import it.stefanochizzolini.clown.documents.interaction.forms.TextField;
+import it.stefanochizzolini.clown.objects.PdfArray;
+import it.stefanochizzolini.clown.objects.PdfDictionary;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfInteger;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfReal;
+import it.stefanochizzolini.clown.objects.PdfString;
+import it.stefanochizzolini.clown.util.math.geom.Dimension;
+
+import java.awt.geom.Dimension2D;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+
+/**
+  Default field appearance style.
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+  @since 0.0.7
+*/
+public class DefaultStyle
+  extends FieldStyle
+{
+  // <dynamic>
+  // <constructors>
+  public DefaultStyle(
+    )
+  {
+    setBackColor(new DeviceRGBColor(.9,.9,.9));
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public void apply(
+    Field field
+    )
+  {
+    if(field instanceof PushButton)
+    {apply((PushButton)field);}
+    else if(field instanceof CheckBox)
+    {apply((CheckBox)field);}
+    else if(field instanceof TextField)
+    {apply((TextField)field);}
+    else if(field instanceof ComboBox)
+    {apply((ComboBox)field);}
+    else if(field instanceof ListBox)
+    {apply((ListBox)field);}
+    else if(field instanceof RadioButton)
+    {apply((RadioButton)field);}
+  }
+
+  private void apply(
+    CheckBox field
+    )
+  {
+    Document document = field.getDocument();
+    for(Widget widget : field.getWidgets())
+    {
+      {
+        PdfDictionary widgetDataObject = widget.getBaseDataObject();
+        widgetDataObject.put(
+          PdfName.DA,
+          new PdfString("/ZaDb 0 Tf 0 0 0 rg")
+          );
+        widgetDataObject.put(
+          PdfName.MK,
+          new PdfDictionary(
+            new PdfName[]
+            {
+              PdfName.BG,
+              PdfName.BC,
+              PdfName.CA
+            },
+            new PdfDirectObject[]
+            {
+              new PdfArray(new PdfDirectObject[]{new PdfReal(0.9412),new PdfReal(0.9412),new PdfReal(0.9412)}),
+              new PdfArray(new PdfDirectObject[]{new PdfInteger(0),new PdfInteger(0),new PdfInteger(0)}),
+              new PdfString("4")
+            }
+            )
+          );
+        widgetDataObject.put(
+          PdfName.BS,
+          new PdfDictionary(
+            new PdfName[]
+            {
+              PdfName.W,
+              PdfName.S
+            },
+            new PdfDirectObject[]
+            {
+              new PdfReal(0.8),
+              PdfName.S
+            }
+            )
+          );
+        widgetDataObject.put(
+          PdfName.H,
+          PdfName.P
+          );
+      }
+
+      Appearance appearance = widget.getAppearance();
+      if(appearance == null)
+      {widget.setAppearance(appearance = new Appearance(document));}
+
+      AppearanceStates normalAppearance = appearance.getNormal();
+      FormXObject onState = new FormXObject(document);
+      normalAppearance.put(PdfName.Yes,onState);
+
+//TODO:verify!!!
+//   appearance.getRollover().put(PdfName.Yes,onState);
+//   appearance.getDown().put(PdfName.Yes,onState);
+//   appearance.getRollover().put(PdfName.Off,offState);
+//   appearance.getDown().put(PdfName.Off,offState);
+
+      Rectangle2D widgetBox = widget.getBox();
+      Dimension2D size = new Dimension(widgetBox.getWidth(),widgetBox.getHeight());
+      Rectangle2D frame = new Rectangle2D.Double(0,0,size.getWidth(),size.getHeight());
+      {
+        onState.setSize(size);
+
+        PrimitiveFilter builder = new PrimitiveFilter(onState);
+
+        builder.beginLocalState();
+        builder.setFillColor(getBackColor());
+        builder.setStrokeColor(getForeColor());
+        builder.drawRectangle(frame);
+        builder.fillStroke();
+        builder.end();
+
+        BlockFilter blockFilter = new BlockFilter(builder);
+        blockFilter.begin(frame,AlignmentXEnum.Center,AlignmentYEnum.Middle);
+        builder.setFillColor(getForeColor());
+        builder.setFont(
+          new StandardType1Font(
+            document,
+            StandardType1Font.FamilyEnum.ZapfDingbats,
+            true,
+            false
+            ),
+          size.getHeight() * 0.8
+          );
+        blockFilter.showText(new String(new char[]{getCheckSymbol()}));
+        blockFilter.end();
+
+        builder.flush();
+      }
+
+      FormXObject offState = new FormXObject(document);
+      normalAppearance.put(PdfName.Off,offState);
+      {
+        offState.setSize(size);
+
+        PrimitiveFilter builder = new PrimitiveFilter(offState);
+
+        builder.beginLocalState();
+        builder.setFillColor(getBackColor());
+        builder.setStrokeColor(getForeColor());
+        builder.drawRectangle(frame);
+        builder.fillStroke();
+        builder.end();
+
+        builder.flush();
+      }
+    }
+  }
+
+  private void apply(
+    RadioButton field
+    )
+  {
+    Document document = field.getDocument();
+    for(Widget widget : field.getWidgets())
+    {
+      {
+        PdfDictionary widgetDataObject = widget.getBaseDataObject();
+        widgetDataObject.put(
+          PdfName.DA,
+          new PdfString("/ZaDb 0 Tf 0 0 0 rg")
+          );
+        widgetDataObject.put(
+          PdfName.MK,
+          new PdfDictionary(
+            new PdfName[]
+            {
+              PdfName.BG,
+              PdfName.BC,
+              PdfName.CA
+            },
+            new PdfDirectObject[]
+            {
+              new PdfArray(new PdfDirectObject[]{new PdfReal(0.9412),new PdfReal(0.9412),new PdfReal(0.9412)}),
+              new PdfArray(new PdfDirectObject[]{new PdfInteger(0),new PdfInteger(0),new PdfInteger(0)}),
+              new PdfString("l")
+            }
+            )
+          );
+        widgetDataObject.put(
+          PdfName.BS,
+          new PdfDictionary(
+            new PdfName[]
+            {
+              PdfName.W,
+              PdfName.S
+            },
+            new PdfDirectObject[]
+            {
+              new PdfReal(0.8),
+              PdfName.S
+            }
+            )
+          );
+        widgetDataObject.put(
+          PdfName.H,
+          PdfName.P
+          );
+      }
+
+      Appearance appearance = widget.getAppearance();
+      if(appearance == null)
+      {widget.setAppearance(appearance = new Appearance(document));}
+
+      AppearanceStates normalAppearance = appearance.getNormal();
+      FormXObject onState = normalAppearance.get(new PdfName(((DualWidget)widget).getWidgetName()));
+
+//TODO:verify!!!
+//   appearance.getRollover().put(new PdfName(...),onState);
+//   appearance.getDown().put(new PdfName(...),onState);
+//   appearance.getRollover().put(PdfName.Off,offState);
+//   appearance.getDown().put(PdfName.Off,offState);
+
+      Rectangle2D widgetBox = widget.getBox();
+      Dimension2D size = new Dimension(widgetBox.getWidth(),widgetBox.getHeight());
+      Rectangle2D frame = new Rectangle2D.Double(1,1,size.getWidth()-2,size.getHeight()-2);
+      {
+        onState.setSize(size);
+
+        PrimitiveFilter builder = new PrimitiveFilter(onState);
+
+        builder.beginLocalState();
+        builder.setFillColor(getBackColor());
+        builder.setStrokeColor(getForeColor());
+        builder.drawEllipse(frame);
+        builder.fillStroke();
+        builder.end();
+
+        BlockFilter blockFilter = new BlockFilter(builder);
+        blockFilter.begin(frame,AlignmentXEnum.Center,AlignmentYEnum.Middle);
+        builder.setFillColor(getForeColor());
+        builder.setFont(
+          new StandardType1Font(
+            document,
+            StandardType1Font.FamilyEnum.ZapfDingbats,
+            true,
+            false
+            ),
+          size.getHeight() * 0.8
+          );
+        blockFilter.showText(new String(new char[]{getRadioSymbol()}));
+        blockFilter.end();
+
+        builder.flush();
+      }
+
+      FormXObject offState = new FormXObject(document);
+      normalAppearance.put(PdfName.Off,offState);
+      {
+        offState.setSize(size);
+
+        PrimitiveFilter builder = new PrimitiveFilter(offState);
+
+        builder.beginLocalState();
+        builder.setFillColor(getBackColor());
+        builder.setStrokeColor(getForeColor());
+        builder.drawEllipse(frame);
+        builder.fillStroke();
+        builder.end();
+
+        builder.flush();
+      }
+    }
+  }
+
+  private void apply(
+    PushButton field
+    )
+  {
+    Document document = field.getDocument();
+    Widget widget = field.getWidgets().get(0);
+
+    Appearance appearance = widget.getAppearance();
+    if(appearance == null)
+    {widget.setAppearance(appearance = new Appearance(document));}
+
+    FormXObject normalAppearanceState = new FormXObject(document);
+    {
+      Rectangle2D widgetBox = widget.getBox();
+      Dimension2D size = new Dimension(widgetBox.getWidth(),widgetBox.getHeight());
+      normalAppearanceState.setSize(size);
+      PrimitiveFilter builder = new PrimitiveFilter(normalAppearanceState);
+
+      builder.beginLocalState();
+      double lineWidth = 1;
+      builder.setLineWidth(lineWidth);
+      builder.setFillColor(getBackColor());
+      builder.setStrokeColor(getForeColor());
+      Rectangle2D frame = new Rectangle2D.Double(lineWidth/2,lineWidth/2,size.getWidth()-lineWidth,size.getHeight()-lineWidth);
+      builder.drawRectangle(frame,5);
+      builder.fillStroke();
+      builder.end();
+
+      String caption = (String)field.getValue();
+      if(caption != null)
+      {
+        BlockFilter blockFilter = new BlockFilter(builder);
+        blockFilter.begin(frame,AlignmentXEnum.Center,AlignmentYEnum.Middle);
+        builder.setFillColor(getForeColor());
+        builder.setFont(
+          new StandardType1Font(
+            document,
+            StandardType1Font.FamilyEnum.Helvetica,
+            true,
+            false
+            ),
+          size.getHeight() * 0.5
+          );
+        blockFilter.showText(caption);
+        blockFilter.end();
+      }
+
+      builder.flush();
+    }
+    appearance.getNormal().put(null,normalAppearanceState);
+  }
+
+  private void apply(
+    TextField field
+    )
+  {
+    Document document = field.getDocument();
+    Widget widget = field.getWidgets().get(0);
+
+    Appearance appearance = widget.getAppearance();
+    if(appearance == null)
+    {widget.setAppearance(appearance = new Appearance(document));}
+
+    widget.getBaseDataObject().put(
+      PdfName.DA,
+      new PdfString("/Helv " + getFontSize() + " Tf 0 0 0 rg")
+      );
+
+    FormXObject normalAppearanceState = new FormXObject(document);
+    {
+      Rectangle2D widgetBox = widget.getBox();
+      Dimension2D size = new Dimension(widgetBox.getWidth(),widgetBox.getHeight());
+      normalAppearanceState.setSize(size);
+      PrimitiveFilter builder = new PrimitiveFilter(normalAppearanceState);
+
+      builder.beginLocalState();
+      double lineWidth = 1;
+      builder.setLineWidth(lineWidth);
+      builder.setFillColor(getBackColor());
+      builder.setStrokeColor(getForeColor());
+      Rectangle2D frame = new Rectangle2D.Double(lineWidth/2,lineWidth/2,size.getWidth()-lineWidth,size.getHeight()-lineWidth);
+      builder.drawRectangle(frame,5);
+      builder.fillStroke();
+      builder.end();
+
+      builder.beginMarkedContent(PdfName.Tx);
+      builder.setFont(
+        new StandardType1Font(
+          document,
+          StandardType1Font.FamilyEnum.Helvetica,
+          false,
+          false
+          ),
+        getFontSize()
+        );
+      builder.showText(
+        (String)field.getValue(),
+        new Point2D.Double(0,size.getHeight()/2),
+        AlignmentXEnum.Left,
+        AlignmentYEnum.Middle,
+        0
+        );
+      builder.end();
+
+      builder.flush();
+    }
+    appearance.getNormal().put(null,normalAppearanceState);
+  }
+
+  private void apply(
+    ComboBox field
+    )
+  {
+    Document document = field.getDocument();
+    Widget widget = field.getWidgets().get(0);
+
+    Appearance appearance = widget.getAppearance();
+    if(appearance == null)
+    {widget.setAppearance(appearance = new Appearance(document));}
+
+    widget.getBaseDataObject().put(
+      PdfName.DA,
+      new PdfString("/Helv " + getFontSize() + " Tf 0 0 0 rg")
+      );
+
+    FormXObject normalAppearanceState = new FormXObject(document);
+    {
+      Rectangle2D widgetBox = widget.getBox();
+      Dimension2D size = new Dimension(widgetBox.getWidth(),widgetBox.getHeight());
+      normalAppearanceState.setSize(size);
+      PrimitiveFilter builder = new PrimitiveFilter(normalAppearanceState);
+
+      builder.beginLocalState();
+      double lineWidth = 1;
+      builder.setLineWidth(lineWidth);
+      builder.setFillColor(getBackColor());
+      builder.setStrokeColor(getForeColor());
+      Rectangle2D frame = new Rectangle2D.Double(lineWidth/2,lineWidth/2,size.getWidth()-lineWidth,size.getHeight()-lineWidth);
+      builder.drawRectangle(frame,5);
+      builder.fillStroke();
+      builder.end();
+
+      builder.beginMarkedContent(PdfName.Tx);
+      builder.setFont(
+        new StandardType1Font(
+          document,
+          StandardType1Font.FamilyEnum.Helvetica,
+          false,
+          false
+          ),
+        getFontSize()
+        );
+      builder.showText(
+        (String)field.getValue(),
+        new Point2D.Double(0,size.getHeight()/2),
+        AlignmentXEnum.Left,
+        AlignmentYEnum.Middle,
+        0
+        );
+      builder.end();
+
+      builder.flush();
+    }
+    appearance.getNormal().put(null,normalAppearanceState);
+  }
+
+  private void apply(
+    ListBox field
+    )
+  {
+    Document document = field.getDocument();
+    Widget widget = field.getWidgets().get(0);
+
+    Appearance appearance = widget.getAppearance();
+    if(appearance == null)
+    {widget.setAppearance(appearance = new Appearance(document));}
+
+    {
+      PdfDictionary widgetDataObject = widget.getBaseDataObject();
+      widgetDataObject.put(
+        PdfName.DA,
+        new PdfString("/Helv " + getFontSize() + " Tf 0 0 0 rg")
+        );
+      widgetDataObject.put(
+        PdfName.MK,
+        new PdfDictionary(
+          new PdfName[]
+          {
+            PdfName.BG,
+            PdfName.BC
+          },
+          new PdfDirectObject[]
+          {
+            new PdfArray(new PdfDirectObject[]{new PdfReal(.9),new PdfReal(.9),new PdfReal(.9)}),
+            new PdfArray(new PdfDirectObject[]{new PdfInteger(0),new PdfInteger(0),new PdfInteger(0)})
+          }
+          )
+        );
+    }
+
+    FormXObject normalAppearanceState = new FormXObject(document);
+    {
+      Rectangle2D widgetBox = widget.getBox();
+      Dimension2D size = new Dimension(widgetBox.getWidth(),widgetBox.getHeight());
+      normalAppearanceState.setSize(size);
+      PrimitiveFilter builder = new PrimitiveFilter(normalAppearanceState);
+
+      builder.beginLocalState();
+      double lineWidth = 1;
+      builder.setLineWidth(lineWidth);
+      builder.setFillColor(getBackColor());
+      builder.setStrokeColor(getForeColor());
+      Rectangle2D frame = new Rectangle2D.Double(lineWidth/2,lineWidth/2,size.getWidth()-lineWidth,size.getHeight()-lineWidth);
+      builder.drawRectangle(frame,5);
+      builder.fillStroke();
+      builder.end();
+
+      builder.beginLocalState();
+      builder.drawRectangle(frame,5);
+      builder.clip(); // Ensures that the visible content is clipped within the rounded frame.
+
+      builder.beginMarkedContent(PdfName.Tx);
+      builder.setFont(
+        new StandardType1Font(
+          document,
+          StandardType1Font.FamilyEnum.Helvetica,
+          false,
+          false
+          ),
+        getFontSize()
+        );
+      double y = 3;
+      for(ChoiceItem item : field.getItems())
+      {
+        builder.showText(
+          item.getText(),
+          new Point2D.Double(0,y)
+          );
+        y += getFontSize() * 1.175;
+        if(y > size.getHeight())
+          break;
+      }
+      builder.end();
+      builder.end();
+
+      builder.flush();
+    }
+    appearance.getNormal().put(null,normalAppearanceState);
+  }
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/styles/FieldStyle.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/styles/FieldStyle.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/styles/FieldStyle.java	(revision 23703)
@@ -0,0 +1,111 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.forms.styles;
+
+import it.stefanochizzolini.clown.documents.contents.colorSpaces.Color;
+import it.stefanochizzolini.clown.documents.contents.colorSpaces.DeviceRGBColor;
+import it.stefanochizzolini.clown.documents.interaction.forms.Field;
+
+/**
+  Abstract field appearance style.
+  <p>It automates the definition of field appearance, applying a common look.</p>
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.7
+  @since 0.0.7
+*/
+public abstract class FieldStyle
+{
+  // <dynamic>
+  // <fields>
+  private Color backColor = DeviceRGBColor.White;
+  private char checkSymbol = (char)52;
+  private double fontSize = 10;
+  private Color foreColor = DeviceRGBColor.Black;
+  private char radioSymbol = (char)108;
+  // </fields>
+
+  // <constructors>
+  protected FieldStyle(
+    )
+  {}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  public abstract void apply(
+    Field field
+    );
+
+  public Color getBackColor(
+    )
+  {return backColor;}
+
+  public char getCheckSymbol(
+    )
+  {return checkSymbol;}
+
+  public double getFontSize(
+    )
+  {return fontSize;}
+
+  public Color getForeColor(
+    )
+  {return foreColor;}
+
+  public char getRadioSymbol(
+    )
+  {return radioSymbol;}
+
+  public void setBackColor(
+    Color value
+    )
+  {backColor = value;}
+
+  public void setCheckSymbol(
+    char value
+    )
+  {checkSymbol = value;}
+
+  public void setFontSize(
+    double value
+    )
+  {fontSize = value;}
+
+  public void setForeColor(
+    Color value
+    )
+  {foreColor = value;}
+
+  public void setRadioSymbol(
+    char value
+    )
+  {radioSymbol = value;}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/styles/package.html
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/styles/package.html	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/forms/styles/package.html	(revision 23703)
@@ -0,0 +1,38 @@
+<html>
+<head>
+<!--
+  Copyright 2008-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+-->
+</head>
+<body>
+<p>Custom form field appearance.</p>
+<p>This package provides ready-to-use formatters to automate the composition of the graphic style of form fields.</p>
+
+<h2>Related Documentation</h2>
+<p>For overviews, tutorials, examples, guides, and tool documentation, please see:</p>
+<ul>
+  <li><a href="http://clown.stefanochizzolini.it">PDF Clown Home Page</a>
+</ul>
+</body>
+</html>
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/navigation/document/Bookmark.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/navigation/document/Bookmark.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/navigation/document/Bookmark.java	(revision 23703)
@@ -0,0 +1,268 @@
+/*
+  Copyright 2006-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.navigation.document;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.interaction.ILink;
+import it.stefanochizzolini.clown.documents.interaction.actions.Action;
+import it.stefanochizzolini.clown.files.File;
+import it.stefanochizzolini.clown.objects.PdfDictionary;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfInteger;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfObjectWrapper;
+import it.stefanochizzolini.clown.objects.PdfReference;
+import it.stefanochizzolini.clown.objects.PdfTextString;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+/**
+  Outline item [PDF:1.6:8.2.2].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+*/
+public class Bookmark
+  extends PdfObjectWrapper<PdfDictionary>
+  implements ILink
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  public Bookmark(
+    Document context,
+    String title
+    )
+  {
+    super(
+      context.getFile(),
+      new PdfDictionary()
+      );
+    setTitle(title);
+  }
+
+  public Bookmark(
+    Document context,
+    String title,
+    LocalDestination destination
+    )
+  {
+    this(context,title);
+    setDestination(destination);
+  }
+
+  public Bookmark(
+    Document context,
+    String title,
+    Action action
+    )
+  {
+    this(context,title);
+    setAction(action);
+  }
+  
+  Bookmark(
+    PdfDirectObject baseObject
+    )
+  {
+    super(
+      baseObject,
+      null // NO container (bookmark MUST be an indirect object [PDF:1.6:8.2.2]).
+      );
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public Bookmark clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    Gets the child bookmarks.
+  */
+  public Bookmarks getBookmarks(
+    )
+  {return new Bookmarks(getBaseObject());}
+
+  /**
+    Gets the parent bookmark.
+  */
+  public Bookmark getParent(
+    )
+  {
+    PdfReference reference = (PdfReference)getBaseDataObject().get(PdfName.Parent);
+    // Is its parent a bookmark?
+    /*
+      NOTE: the Title entry can be used as a flag to distinguish bookmark
+      (outline item) dictionaries from outline (root) dictionaries.
+    */
+    if(((PdfDictionary)File.resolve(reference)).containsKey(PdfName.Title)) // Bookmark.
+      return new Bookmark(reference);
+    else // Outline root.
+      return null; // NO parent bookmark.
+  }
+
+  /**
+    Gets the text to be displayed for this bookmark.
+  */
+  public String getTitle(
+    )
+  {return (String)((PdfTextString)getBaseDataObject().get(PdfName.Title)).getValue();}
+
+  /**
+    Gets whether this bookmark's children are displayed.
+  */
+  public boolean isExpanded(
+    )
+  {
+    PdfInteger countObject = (PdfInteger)getBaseDataObject().get(PdfName.Count);
+
+    return (countObject == null
+        || countObject.getRawValue() >= 0);
+  }
+
+  /**
+    @see #isExpanded()
+  */
+  public void setExpanded(
+    boolean value
+    )
+  {
+    PdfInteger countObject = (PdfInteger)getBaseDataObject().get(PdfName.Count);
+    if(countObject == null)
+      return;
+
+    /*
+      NOTE: Non-negative Count entry means open, negative Count entry means closed [PDF:1.6:8.2.2].
+    */
+    countObject.setRawValue((value ? 1 : -1) * Math.abs(countObject.getRawValue()));
+  }
+
+  /**
+    @see #getTitle()
+  */
+  public void setTitle(
+    String value
+    )
+  {getBaseDataObject().put(PdfName.Title,new PdfTextString(value));}
+  
+  // <ILink>
+  public Action getAction(
+    )
+  {
+    /*
+      NOTE: 'A' entry may be undefined.
+    */
+    PdfDirectObject actionObject = getBaseDataObject().get(PdfName.A);
+    if(actionObject == null)
+      return null;
+  
+    return Action.wrap(actionObject,getContainer());
+  }
+
+  public Destination getDestination(
+    )
+  {
+    /*
+      NOTE: 'Dest' entry may be undefined.
+    */
+    PdfDirectObject destinationObject = getBaseDataObject().get(PdfName.Dest);
+    if(destinationObject == null)
+      return null;
+
+    return Document.resolveName(
+      LocalDestination.class,
+      destinationObject,
+      getContainer()
+      );
+  }
+
+  public PdfObjectWrapper<?> getTarget(
+    )
+  {
+    if(getBaseDataObject().containsKey(PdfName.Dest))
+      return getDestination();
+    else if(getBaseDataObject().containsKey(PdfName.A))
+      return getAction();
+    else
+      return null;
+  }
+
+  public void setAction(
+    Action value
+    )
+  {
+    if(value == null)
+    {getBaseDataObject().remove(PdfName.A);}
+    else
+    {
+      /*
+        NOTE: This entry is not permitted in bookmarks if a 'Dest' entry already exists.
+      */
+      if(getBaseDataObject().containsKey(PdfName.Dest))
+      {getBaseDataObject().remove(PdfName.Dest);}
+      
+      getBaseDataObject().put(PdfName.A,value.getBaseObject());
+    }
+  }
+  
+  public void setDestination(
+    Destination value
+    )
+  {
+    if(value == null)
+    {getBaseDataObject().remove(PdfName.Dest);}
+    else
+    {
+      /*
+        NOTE: This entry is not permitted in bookmarks if an 'A' entry already exists.
+      */
+      if(getBaseDataObject().containsKey(PdfName.A))
+      {getBaseDataObject().remove(PdfName.A);}
+
+      getBaseDataObject().put(PdfName.Dest,value.getNamedBaseObject());
+    }
+  }
+
+  public void setTarget(
+    PdfObjectWrapper<?> value
+    )
+  {
+    if(value instanceof Destination)
+    {setDestination((Destination)value);}
+    else if(value instanceof Action)
+    {setAction((Action)value);}
+    else
+      throw new IllegalArgumentException("It MUST be either a Destination or an Action.");
+  }
+  // </ILink>
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/navigation/document/Bookmarks.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/navigation/document/Bookmarks.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/navigation/document/Bookmarks.java	(revision 23703)
@@ -0,0 +1,347 @@
+/*
+  Copyright 2006-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.navigation.document;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.files.File;
+import it.stefanochizzolini.clown.objects.IPdfNumber;
+import it.stefanochizzolini.clown.objects.PdfDictionary;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfInteger;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfObjectWrapper;
+import it.stefanochizzolini.clown.objects.PdfReference;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.NoSuchElementException;
+
+/**
+  Collection of bookmarks [PDF:1.6:8.2.2].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+*/
+public class Bookmarks
+  extends PdfObjectWrapper<PdfDictionary>
+  implements List<Bookmark>
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  public Bookmarks(
+    Document context
+    )
+  {
+    super(
+      context.getFile(),
+      new PdfDictionary(
+        new PdfName[]
+        {
+          PdfName.Type,
+          PdfName.Count
+        },
+        new PdfDirectObject[]
+        {
+          PdfName.Outlines,
+          new PdfInteger(0)
+        }
+        )
+      );
+  }
+
+  /**
+    For internal use only.
+  */
+  public Bookmarks(
+    PdfDirectObject baseObject
+    )
+  {
+    super(
+      baseObject,
+      null // NO container (bookmark MUST be an indirect object [PDF:1.6:8.2.2]).
+      );
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public Bookmarks clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  // <List>
+  public void add(
+    int index,
+    Bookmark bookmark
+    )
+  {throw new NotImplementedException();}
+
+  public boolean addAll(
+    int index,
+    Collection<? extends Bookmark> bookmarks
+    )
+  {throw new NotImplementedException();}
+
+  public Bookmark get(
+    int index
+    )
+  {
+    PdfReference bookmarkObject = (PdfReference)getBaseDataObject().get(PdfName.First);
+    while(index > 0)
+    {
+      bookmarkObject = (PdfReference)((PdfDictionary)File.resolve(bookmarkObject)).get(PdfName.Next);
+      // Did we go past the collection range?
+      if(bookmarkObject == null)
+        throw new IndexOutOfBoundsException();
+
+      index--;
+    }
+
+    return new Bookmark(bookmarkObject);
+  }
+
+  public int indexOf(
+    Object bookmark
+    )
+  {throw new NotImplementedException();}
+
+  public int lastIndexOf(
+    Object bookmark
+    )
+  {return indexOf(bookmark);}
+
+  public ListIterator<Bookmark> listIterator(
+    )
+  {throw new NotImplementedException();}
+
+  public ListIterator<Bookmark> listIterator(
+    int index
+    )
+  {throw new NotImplementedException();}
+
+  public Bookmark remove(
+    int index
+    )
+  {throw new NotImplementedException();}
+
+  public Bookmark set(
+    int index,
+    Bookmark bookmark
+    )
+  {throw new NotImplementedException();}
+
+  public List<Bookmark> subList(
+    int fromIndex,
+    int toIndex
+    )
+  {throw new NotImplementedException();}
+
+  // <Collection>
+  public boolean add(
+    Bookmark bookmark
+    )
+  {
+    /*
+      NOTE: Bookmarks imported from alien PDF files MUST be cloned
+      before being added.
+    */
+    bookmark.getBaseDataObject().put(PdfName.Parent,getBaseObject());
+
+    PdfInteger countObject = ensureCountObject();
+    // Is it the first bookmark?
+    if(countObject.getRawValue() == 0) // First bookmark.
+    {
+      getBaseDataObject().put(PdfName.First,bookmark.getBaseObject());
+      getBaseDataObject().put(PdfName.Last,bookmark.getBaseObject());
+
+      ((IPdfNumber)countObject).translateNumberValue(+1);
+    }
+    else // Non-first bookmark.
+    {
+      PdfReference oldLastBookmarkReference = (PdfReference)getBaseDataObject().get(PdfName.Last);
+      getBaseDataObject().put(PdfName.Last,bookmark.getBaseObject()); // Added bookmark is the last in the collection...
+      ((PdfDictionary)File.resolve(oldLastBookmarkReference)).put(PdfName.Next,bookmark.getBaseObject()); // ...and the next of the previously-last bookmark.
+      bookmark.getBaseDataObject().put(PdfName.Prev,oldLastBookmarkReference);
+
+      /*
+        NOTE: The Count entry is a relative number (whose sign represents
+        the node open state).
+      */
+      ((IPdfNumber)countObject).translateNumberValue(Math.signum(countObject.getRawValue()));
+    }
+
+    return true;
+  }
+
+  public boolean addAll(
+    Collection<? extends Bookmark> bookmarks
+    )
+  {throw new NotImplementedException();}
+
+  public void clear(
+    )
+  {throw new NotImplementedException();}
+
+  public boolean contains(
+    Object bookmark
+    )
+  {throw new NotImplementedException();}
+
+  public boolean containsAll(
+    Collection<?> bookmarks
+    )
+  {throw new NotImplementedException();}
+
+  public boolean equals(
+    Object object
+    )
+  {throw new NotImplementedException();}
+
+  public int hashCode(
+    )
+  {throw new NotImplementedException();}
+
+  public boolean isEmpty(
+    )
+  {throw new NotImplementedException();}
+
+  public boolean remove(
+    Object bookmark
+    )
+  {throw new NotImplementedException();}
+
+  public boolean removeAll(
+    Collection<?> bookmarks
+    )
+  {throw new NotImplementedException();}
+
+  public boolean retainAll(
+    Collection<?> bookmarks
+    )
+  {throw new NotImplementedException();}
+
+  public int size(
+    )
+  {
+    /*
+      NOTE: The Count entry may be absent [PDF:1.6:8.2.2].
+    */
+    PdfInteger countObject = (PdfInteger)getBaseDataObject().get(PdfName.Count);
+    if(countObject == null)
+      return 0;
+
+    return countObject.getRawValue();
+  }
+
+  public Bookmark[] toArray(
+    )
+  {throw new NotImplementedException();}
+
+  public <T> T[] toArray(
+    T[] values
+    )
+  {throw new NotImplementedException();}
+
+  // <Iterable>
+  public Iterator<Bookmark> iterator(
+    )
+  {
+    return new Iterator<Bookmark>()
+    {
+      // <class>
+      // <dynamic>
+      // <fields>
+      /**
+        Current bookmark.
+      */
+      private PdfDirectObject currentBookmarkObject = null;
+      /**
+        Next bookmark.
+      */
+      private PdfDirectObject nextBookmarkObject = getBaseDataObject().get(PdfName.First);
+      // </fields>
+
+      // <interface>
+      // <public>
+      // <Iterator>
+      public boolean hasNext(
+        )
+      {return (nextBookmarkObject != null);}
+
+      public Bookmark next(
+        )
+      {
+        if(!hasNext())
+          throw new NoSuchElementException();
+
+        currentBookmarkObject = nextBookmarkObject;
+        nextBookmarkObject = ((PdfDictionary)File.resolve(currentBookmarkObject)).get(PdfName.Next);
+
+        return new Bookmark(currentBookmarkObject);
+      }
+
+      public void remove(
+        )
+      {throw new UnsupportedOperationException();}
+      // </Iterator>
+      // </public>
+      // </interface>
+      // </dynamic>
+      // </class>
+    };
+  }
+  // </Iterable>
+  // </Collection>
+  // </List>
+  // </public>
+
+  // <protected>
+  /**
+    Gets the count object, forcing its creation if it doesn't exist.
+  */
+  protected PdfInteger ensureCountObject(
+    )
+  {
+    /*
+      NOTE: The Count entry may be absent [PDF:1.6:8.2.2].
+    */
+    PdfInteger countObject = (PdfInteger)getBaseDataObject().get(PdfName.Count);
+    if(countObject == null)
+      getBaseDataObject().put(PdfName.Count,countObject = new PdfInteger(0));
+
+    return countObject;
+  }
+  // </protected>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/navigation/document/Destination.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/navigation/document/Destination.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/navigation/document/Destination.java	(revision 23703)
@@ -0,0 +1,312 @@
+/*
+  Copyright 2006-2009 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.navigation.document;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.files.File;
+import it.stefanochizzolini.clown.objects.PdfArray;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfInteger;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfNamedObjectWrapper;
+import it.stefanochizzolini.clown.objects.PdfReal;
+import it.stefanochizzolini.clown.objects.PdfReference;
+import it.stefanochizzolini.clown.objects.PdfString;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+/**
+  Interaction target [PDF:1.6:8.2.1].
+
+  <h3>Remarks</h3>
+  <p>It represents a particular view of a document, consisting of the following items:</p>
+  <ul>
+    <li>the page of the document to be displayed;</li>
+    <li>the location of the document window on that page;</li>
+    <li>the magnification (zoom) factor to use when displaying the page.</li>
+  </ul>
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+*/
+public abstract class Destination
+  extends PdfNamedObjectWrapper<PdfArray>
+{
+  // <class>
+  // <classes>
+  /**
+    Destination mode [PDF:1.6:8.2.1].
+  */
+  public enum ModeEnum
+  {
+    /**
+      Display the page at the given upper-left position,
+      applying the given magnification.
+
+      <p>View parameters:</p>
+      <ol>
+        <li>left coordinate</li>
+        <li>top coordinate</li>
+        <li>zoom</li>
+      </ol>
+    */
+    XYZ,
+    /**
+      Display the page with its contents magnified just enough to fit
+      the entire page within the window both horizontally and vertically.
+
+      <p>No view parameters.</p>
+    */
+    Fit,
+    /**
+      Display the page with the vertical coordinate <code>top</code> positioned
+      at the top edge of the window and the contents of the page magnified
+      just enough to fit the entire width of the page within the window.
+
+      <p>View parameters:</p>
+      <ol>
+        <li>top coordinate</li>
+      </ol>
+    */
+    FitHorizontal,
+    /**
+      Display the page with the horizontal coordinate <code>left</code> positioned
+      at the left edge of the window and the contents of the page magnified
+      just enough to fit the entire height of the page within the window.
+
+      <p>View parameters:</p>
+      <ol>
+        <li>left coordinate</li>
+      </ol>
+    */
+    FitVertical,
+    /**
+      Display the page with its contents magnified just enough to fit
+      the rectangle specified by the given coordinates entirely
+      within the window both horizontally and vertically.
+
+      <p>View parameters:</p>
+      <ol>
+        <li>left coordinate</li>
+        <li>bottom coordinate</li>
+        <li>right coordinate</li>
+        <li>top coordinate</li>
+      </ol>
+    */
+    FitRectangle,
+    /**
+      Display the page with its contents magnified just enough to fit
+      its bounding box entirely within the window both horizontally and vertically.
+
+      <p>No view parameters.</p>
+    */
+    FitBoundingBox,
+    /**
+      Display the page with the vertical coordinate <code>top</code> positioned
+      at the top edge of the window and the contents of the page magnified
+      just enough to fit the entire width of its bounding box within the window.
+
+      <p>View parameters:</p>
+      <ol>
+        <li>top coordinate</li>
+      </ol>
+    */
+    FitBoundingBoxHorizontal,
+    /**
+      Display the page with the horizontal coordinate <code>left</code> positioned
+      at the left edge of the window and the contents of the page magnified
+      just enough to fit the entire height of its bounding box within the window.
+
+      <p>View parameters:</p>
+      <ol>
+        <li>left coordinate</li>
+      </ol>
+    */
+    FitBoundingBoxVertical
+  }
+  // </classes>
+
+  // <static>
+  // <interface>
+  // <public>
+  /**
+    Wraps a destination base object into a destination object.
+
+    @param baseObject Destination base object.
+    @param container Destination base object container.
+    @param name Destination name.
+    @return Destination object associated to the base object.
+  */
+  public static final Destination wrap(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container,
+    PdfString name
+    )
+  {
+    /*
+      NOTE: This is a factory method for any destination-derived object.
+    */
+    if(baseObject == null)
+      return null;
+
+    PdfArray dataObject = (PdfArray)File.resolve(baseObject);
+    PdfDirectObject pageObject = dataObject.get(0);
+    if(pageObject instanceof PdfReference)
+      return new LocalDestination(baseObject,container,name);
+    else if(pageObject instanceof PdfInteger)
+      return new RemoteDestination(baseObject,container,name);
+    else
+      throw new IllegalArgumentException("'baseObject' parameter doesn't represent a valid destination object.");
+  }
+  // </public>
+  // </interface>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  /**
+    Creates a new destination within the given document context.
+
+    @param context Document context.
+    @param pageObject Page reference. It may be either an actual page reference (PdfReference)
+      or a page index (PdfInteger).
+    @param mode Destination mode.
+    @param viewParams View parameters. Their actual composition depends on the <code>mode</code> value
+      (see ModeEnum for more info).
+  */
+  protected Destination(
+    Document context,
+    PdfDirectObject pageObject,
+    ModeEnum mode,
+    Double[] viewParams
+    )
+  {
+    super(
+      context.getFile(),
+      new PdfArray()
+      );
+
+    PdfArray destinationObject = getBaseDataObject();
+
+    destinationObject.add(pageObject);
+
+    switch(mode)
+    {
+      case Fit:
+        destinationObject.add(PdfName.Fit);
+        break;
+      case FitBoundingBox:
+        destinationObject.add(PdfName.FitB);
+        break;
+      case FitBoundingBoxHorizontal:
+        destinationObject.add(PdfName.FitBH);
+        destinationObject.add(PdfReal.get(viewParams[0]));
+        break;
+      case FitBoundingBoxVertical:
+        destinationObject.add(PdfName.FitBV);
+        destinationObject.add(PdfReal.get(viewParams[0]));
+        break;
+      case FitHorizontal:
+        destinationObject.add(PdfName.FitH);
+        destinationObject.add(PdfReal.get(viewParams[0]));
+        break;
+      case FitRectangle:
+        destinationObject.add(PdfName.FitR);
+        destinationObject.add(PdfReal.get(viewParams[0]));
+        destinationObject.add(PdfReal.get(viewParams[1]));
+        destinationObject.add(PdfReal.get(viewParams[2]));
+        destinationObject.add(PdfReal.get(viewParams[3]));
+        break;
+      case FitVertical:
+        destinationObject.add(PdfName.FitV);
+        destinationObject.add(PdfReal.get(viewParams[0]));
+        break;
+      case XYZ:
+        destinationObject.add(PdfName.XYZ);
+        destinationObject.add(PdfReal.get(viewParams[0]));
+        destinationObject.add(PdfReal.get(viewParams[1]));
+        destinationObject.add(PdfReal.get(viewParams[2]));
+        break;
+    }
+  }
+
+  protected Destination(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container,
+    PdfString name
+    )
+  {
+    super(
+      baseObject,
+      container,
+      name
+      );
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public Destination clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    Gets the destination mode.
+  */
+  public ModeEnum getMode(
+    )
+  {
+    PdfName modeObject = (PdfName)getBaseDataObject().get(1);
+    if(modeObject.equals(PdfName.FitB))
+      return ModeEnum.FitBoundingBox;
+    else if(modeObject.equals(PdfName.FitBH))
+      return ModeEnum.FitBoundingBoxHorizontal;
+    else if(modeObject.equals(PdfName.FitBV))
+      return ModeEnum.FitBoundingBoxVertical;
+    else if(modeObject.equals(PdfName.FitH))
+      return ModeEnum.FitHorizontal;
+    else if(modeObject.equals(PdfName.FitR))
+      return ModeEnum.FitRectangle;
+    else if(modeObject.equals(PdfName.FitV))
+      return ModeEnum.FitVertical;
+    else if(modeObject.equals(PdfName.XYZ))
+      return ModeEnum.XYZ;
+    else
+      return ModeEnum.Fit;
+  }
+
+  /**
+    Gets the target page reference.
+  */
+  public abstract Object getPageRef(
+    );
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/navigation/document/LocalDestination.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/navigation/document/LocalDestination.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/navigation/document/LocalDestination.java	(revision 23703)
@@ -0,0 +1,107 @@
+/*
+  Copyright 2008-2009 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.navigation.document;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.Page;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfString;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+/**
+  Local interaction target [PDF:1.6:8.2.1].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+  @since 0.0.7
+*/
+public class LocalDestination
+  extends Destination
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  public LocalDestination(
+    Page page
+    )
+  {
+    this(
+      page,
+      ModeEnum.Fit,
+      null
+      );
+  }
+
+  public LocalDestination(
+    Page page,
+    ModeEnum mode,
+    Double[] viewParams
+    )
+  {
+    super(
+      page.getDocument(),
+      page.getBaseObject(),
+      mode,
+      viewParams
+      );
+  }
+
+  public LocalDestination(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container,
+    PdfString name
+    )
+  {
+    super(
+      baseObject,
+      container,
+      name
+      );
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public LocalDestination clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  public Page getPage(
+    )
+  {return new Page(getBaseDataObject().get(0));}
+
+  @Override
+  public Object getPageRef(
+    )
+  {return getPage();}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/navigation/document/RemoteDestination.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/navigation/document/RemoteDestination.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/navigation/document/RemoteDestination.java	(revision 23703)
@@ -0,0 +1,110 @@
+/*
+  Copyright 2008-2009 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.navigation.document;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfInteger;
+import it.stefanochizzolini.clown.objects.PdfString;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+/**
+  Remote interaction target [PDF:1.6:8.2.1].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+  @since 0.0.7
+*/
+public class RemoteDestination
+  extends Destination
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  public RemoteDestination(
+    Document context,
+    int pageIndex
+    )
+  {
+    this(
+      context,
+      pageIndex,
+      ModeEnum.Fit,
+      null
+      );
+  }
+
+  public RemoteDestination(
+    Document context,
+    int pageIndex,
+    ModeEnum mode,
+    Double[] viewParams
+    )
+  {
+    super(
+      context,
+      new PdfInteger(pageIndex),
+      mode,
+      viewParams
+      );
+  }
+
+  public RemoteDestination(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container,
+    PdfString name
+    )
+  {
+    super(
+      baseObject,
+      container,
+      name
+      );
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public RemoteDestination clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  public int getPageIndex(
+    )
+  {return ((PdfInteger)getBaseDataObject().get(0)).getRawValue();}
+
+  @Override
+  public Object getPageRef(
+    )
+  {return getPageIndex();}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/navigation/document/package.html
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/navigation/document/package.html	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/navigation/document/package.html	(revision 23703)
@@ -0,0 +1,37 @@
+<html>
+<head>
+<!--
+  Copyright 2006-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+-->
+</head>
+<body>
+<p>Features that allow a PDF viewer application to present the user with an interactive, global overview of a document [PDF:1.6:8.2].</p>
+
+<h2>Related Documentation</h2>
+<p>For overviews, tutorials, examples, guides, and tool documentation, please see:</p>
+<ul>
+  <li><a href="http://clown.stefanochizzolini.it">PDF Clown Home Page</a>
+</ul>
+</body>
+</html>
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/navigation/package.html
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/navigation/package.html	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/navigation/package.html	(revision 23703)
@@ -0,0 +1,37 @@
+<html>
+<head>
+<!--
+  Copyright 2006-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+-->
+</head>
+<body>
+<p>Features that allow a PDF viewer application to present the user with interactive overviews and page-specific views of a document [PDF:1.6:8.2-.3].</p>
+
+<h2>Related Documentation</h2>
+<p>For overviews, tutorials, examples, guides, and tool documentation, please see:</p>
+<ul>
+  <li><a href="http://clown.stefanochizzolini.it">PDF Clown Home Page</a>
+</ul>
+</body>
+</html>
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/navigation/page/Transition.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/navigation/page/Transition.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/navigation/page/Transition.java	(revision 23703)
@@ -0,0 +1,604 @@
+/*
+  Copyright 2008-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.navigation.page;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.objects.IPdfNumber;
+import it.stefanochizzolini.clown.objects.PdfAtomicObject;
+import it.stefanochizzolini.clown.objects.PdfDictionary;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfInteger;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfObjectWrapper;
+import it.stefanochizzolini.clown.objects.PdfReal;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+/**
+  Visual transition to use when moving to a page during a presentation [PDF:1.6:8.3.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.7
+  @version 0.0.8
+*/
+public class Transition
+  extends PdfObjectWrapper<PdfDictionary>
+{
+  // <class>
+  // <classes>
+  /**
+    Transition direction [PDF:1.6:8.3.3].
+  */
+  public enum DirectionEnum
+  {
+    // <class>
+    // <static>
+    // <fields>
+    /**
+      Left to right.
+    */
+    LeftToRight(new PdfInteger(0)),
+    /**
+      Bottom to top.
+    */
+    BottomToTop(new PdfInteger(90)),
+    /**
+      Right to left.
+    */
+    RightToLeft(new PdfInteger(180)),
+    /**
+      Top to bottom.
+    */
+    TopToBottom(new PdfInteger(270)),
+    /**
+      Top-left to bottom-right.
+    */
+    TopLeftToBottomRight(new PdfInteger(315)),
+    /**
+      None.
+    */
+    None(PdfName.None);
+    // </fields>
+
+    // <interface>
+    // <public>
+    /**
+      Gets the direction corresponding to the given value.
+    */
+    public static DirectionEnum get(
+      PdfAtomicObject<?> value
+      )
+    {
+      for(DirectionEnum direction : DirectionEnum.values())
+      {
+        if(direction.getCode().equals(value))
+          return direction;
+      }
+      return null;
+    }
+    // </public>
+    // </interface>
+    // </static>
+
+    // <dynamic>
+    // <fields>
+    private final PdfAtomicObject<?> code;
+    // </fields>
+
+    // <constructors>
+    private DirectionEnum(
+      PdfAtomicObject<?> code
+      )
+    {this.code = code;}
+    // </constructors>
+
+    // <interface>
+    // <public>
+    public PdfAtomicObject<?> getCode(
+      )
+    {return code;}
+    // </public>
+    // </interface>
+    // </dynamic>
+    // </class>
+  }
+
+  /**
+    Transition orientation [PDF:1.6:8.3.3].
+  */
+  public enum OrientationEnum
+  {
+    // <class>
+    // <static>
+    // <fields>
+    /**
+      Horizontal.
+    */
+    Horizontal(PdfName.H),
+    /**
+      Vertical.
+    */
+    Vertical(PdfName.V);
+    // </fields>
+
+    // <interface>
+    // <public>
+    /**
+      Gets the orientation corresponding to the given value.
+    */
+    public static OrientationEnum get(
+      PdfName value
+      )
+    {
+      for(OrientationEnum orientation : OrientationEnum.values())
+      {
+        if(orientation.getCode().equals(value))
+          return orientation;
+      }
+      return null;
+    }
+    // </public>
+    // </interface>
+    // </static>
+
+    // <dynamic>
+    // <fields>
+    private final PdfName code;
+    // </fields>
+
+    // <constructors>
+    private OrientationEnum(
+      PdfName code
+      )
+    {this.code = code;}
+    // </constructors>
+
+    // <interface>
+    // <public>
+    public PdfName getCode(
+      )
+    {return code;}
+    // </public>
+    // </interface>
+    // </dynamic>
+    // </class>
+  }
+
+  /**
+    Transition direction on page [PDF:1.6:8.3.3].
+  */
+  public enum PageDirectionEnum
+  {
+    // <class>
+    // <static>
+    // <fields>
+    /**
+      Inward (from the edges of the page).
+    */
+    Inward(PdfName.I),
+    /**
+      Outward (from the center of the page).
+    */
+    Outward(PdfName.O);
+    // </fields>
+
+    // <interface>
+    // <public>
+    /**
+      Gets the page direction corresponding to the given value.
+    */
+    public static PageDirectionEnum get(
+      PdfName value
+      )
+    {
+      for(PageDirectionEnum direction : PageDirectionEnum.values())
+      {
+        if(direction.getCode().equals(value))
+          return direction;
+      }
+      return null;
+    }
+    // </public>
+    // </interface>
+    // </static>
+
+    // <dynamic>
+    // <fields>
+    private final PdfName code;
+    // </fields>
+
+    // <constructors>
+    private PageDirectionEnum(
+      PdfName code
+      )
+    {this.code = code;}
+    // </constructors>
+
+    // <interface>
+    // <public>
+    public PdfName getCode(
+      )
+    {return code;}
+    // </public>
+    // </interface>
+    // </dynamic>
+    // </class>
+  }
+
+  /**
+    Transition style [PDF:1.6:8.3.3].
+  */
+  public enum StyleEnum
+  {
+    // <class>
+    // <static>
+    // <fields>
+    /**
+      Two lines sweep across the screen, revealing the page.
+    */
+    Split(PdfName.Split),
+    /**
+      Multiple lines sweep across the screen, revealing the page.
+    */
+    Blinds(PdfName.Blinds),
+    /**
+      A rectangular box sweeps between the edges of the page and the center.
+    */
+    Box(PdfName.Box),
+    /**
+      A single line sweeps across the screen from one edge to the other.
+    */
+    Wipe(PdfName.Wipe),
+    /**
+      The old page dissolves gradually.
+    */
+    Dissolve(PdfName.Dissolve),
+    /**
+      The old page dissolves gradually sweeping across the page in a wide band
+      moving from one side of the screen to the other.
+    */
+    Glitter(PdfName.Glitter),
+    /**
+      No transition.
+    */
+    Replace(PdfName.R),
+    /**
+      Changes are flown across the screen.
+    */
+    Fly(PdfName.Fly),
+    /**
+      The page slides in, pushing away the old one.
+    */
+    Push(PdfName.Push),
+    /**
+      The page slides on to the screen, covering the old one.
+    */
+    Cover(PdfName.Cover),
+    /**
+      The old page slides off the screen, uncovering the new one.
+    */
+    Uncover(PdfName.Uncover),
+    /**
+      The new page reveals gradually.
+    */
+    Fade(PdfName.Fade);
+    // </fields>
+
+    // <interface>
+    // <public>
+    /**
+      Gets the style corresponding to the given value.
+    */
+    public static StyleEnum get(
+      PdfName value
+      )
+    {
+      for(StyleEnum style : StyleEnum.values())
+      {
+        if(style.getCode().equals(value))
+          return style;
+      }
+      return null;
+    }
+    // </public>
+    // </interface>
+    // </static>
+
+    // <dynamic>
+    // <fields>
+    private final PdfName code;
+    // </fields>
+
+    // <constructors>
+    private StyleEnum(
+      PdfName code
+      )
+    {this.code = code;}
+    // </constructors>
+
+    // <interface>
+    // <public>
+    public PdfName getCode(
+      )
+    {return code;}
+    // </public>
+    // </interface>
+    // </dynamic>
+    // </class>
+  }
+  // </classes>
+
+  // <dynamic>
+  // <constructors>
+  /**
+    Creates a new action within the given document context.
+  */
+  public Transition(
+    Document context
+    )
+  {
+    super(
+      context.getFile(),
+      new PdfDictionary(
+        new PdfName[]{PdfName.Type},
+        new PdfDirectObject[]{PdfName.Trans}
+        )
+      );
+  }
+
+  public Transition(
+    Document context,
+    StyleEnum style
+    )
+  {
+    this(
+      context,
+      style,
+      null,
+      null,
+      null,
+      null,
+      null
+      );
+  }
+
+  public Transition(
+    Document context,
+    StyleEnum style,
+    Double duration
+    )
+  {
+    this(
+      context,
+      style,
+      duration,
+      null,
+      null,
+      null,
+      null
+      );
+  }
+
+  public Transition(
+    Document context,
+    StyleEnum style,
+    Double duration,
+    OrientationEnum orientation,
+    PageDirectionEnum pageDirection,
+    DirectionEnum direction,
+    Double scale
+    )
+  {
+    this(context);
+
+    setStyle(style);
+    setDuration(duration);
+    setOrientation(orientation);
+    setPageDirection(pageDirection);
+    setDirection(direction);
+    setScale(scale);
+  }
+
+  public Transition(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {
+    super(
+      baseObject,
+      container
+      );
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public Transition clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    Gets the transition direction.
+  */
+  public DirectionEnum getDirection(
+    )
+  {
+    PdfAtomicObject<?> directionObject = (PdfAtomicObject<?>)getBaseDataObject().get(PdfName.Di);
+    if(directionObject == null)
+      return DirectionEnum.LeftToRight;
+
+    return DirectionEnum.get(directionObject);
+  }
+
+  /**
+    Gets the duration of the transition effect, in seconds.
+  */
+  public Double getDuration(
+    )
+  {
+    IPdfNumber durationObject = (IPdfNumber)getBaseDataObject().get(PdfName.D);
+    if(durationObject == null)
+      return new Double(1);
+
+    return durationObject.getNumberValue();
+  }
+
+  /**
+    Gets the transition orientation.
+  */
+  public OrientationEnum getOrientation(
+    )
+  {
+    PdfName orientationObject = (PdfName)getBaseDataObject().get(PdfName.Dm);
+    if(orientationObject == null)
+      return OrientationEnum.Horizontal;
+
+    return OrientationEnum.get(orientationObject);
+  }
+
+  /**
+    Gets the transition direction on page.
+  */
+  public PageDirectionEnum getPageDirection(
+    )
+  {
+    PdfName pageDirectionObject = (PdfName)getBaseDataObject().get(PdfName.M);
+    if(pageDirectionObject == null)
+      return PageDirectionEnum.Inward;
+
+    return PageDirectionEnum.get(pageDirectionObject);
+  }
+
+  /**
+    Gets the scale at which the changes are drawn.
+  */
+  public Double getScale(
+    )
+  {
+    IPdfNumber scaleObject = (IPdfNumber)getBaseDataObject().get(PdfName.SS);
+    if(scaleObject == null)
+      return new Double(1);
+
+    return scaleObject.getNumberValue();
+  }
+
+  /**
+    Gets the transition style.
+  */
+  public StyleEnum getStyle(
+    )
+  {
+    PdfName styleObject = (PdfName)getBaseDataObject().get(PdfName.S);
+    if(styleObject == null)
+      return StyleEnum.Replace;
+
+    return StyleEnum.get(styleObject);
+  }
+
+  /**
+    @see #getDirection()
+  */
+  public void setDirection(
+    DirectionEnum value
+    )
+  {
+    if(value == null)
+    {getBaseDataObject().remove(PdfName.Di);}
+    else
+    {getBaseDataObject().put(PdfName.Di,value.getCode());}
+  }
+
+  /**
+    @see #getDuration()
+  */
+  public void setDuration(
+    Double value
+    )
+  {
+    if(value == null)
+    {getBaseDataObject().remove(PdfName.D);}
+    else
+    {getBaseDataObject().put(PdfName.D,new PdfReal(value));}
+  }
+
+  /**
+    @see #getOrientation()
+  */
+  public void setOrientation(
+    OrientationEnum value
+    )
+  {
+    if(value == null)
+    {getBaseDataObject().remove(PdfName.Dm);}
+    else
+    {getBaseDataObject().put(PdfName.Dm,value.getCode());}
+  }
+
+  /**
+    @see #getPageDirection()
+  */
+  public void setPageDirection(
+    PageDirectionEnum value
+    )
+  {
+    if(value == null)
+    {getBaseDataObject().remove(PdfName.M);}
+    else
+    {getBaseDataObject().put(PdfName.M,value.getCode());}
+  }
+
+  /**
+    @see #getScale()
+  */
+  public void setScale(
+    Double value
+    )
+  {
+    if(value == null)
+    {getBaseDataObject().remove(PdfName.SS);}
+    else
+    {getBaseDataObject().put(PdfName.SS,new PdfReal(value));}
+  }
+
+  /**
+    @see #getStyle()
+  */
+  public void setStyle(
+    StyleEnum value
+    )
+  {
+    if(value == null)
+    {getBaseDataObject().remove(PdfName.S);}
+    else
+    {getBaseDataObject().put(PdfName.S,value.getCode());}
+  }
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/navigation/page/package.html
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/navigation/page/package.html	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/navigation/page/package.html	(revision 23703)
@@ -0,0 +1,37 @@
+<html>
+<head>
+<!--
+  Copyright 2006-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+-->
+</head>
+<body>
+<p>Features that enable the user to navigate from page to page within a document [PDF:1.6:8.3].</p>
+
+<h2>Related Documentation</h2>
+<p>For overviews, tutorials, examples, guides, and tool documentation, please see:</p>
+<ul>
+  <li><a href="http://clown.stefanochizzolini.it">PDF Clown Home Page</a>
+</ul>
+</body>
+</html>
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/package.html
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/package.html	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/package.html	(revision 23703)
@@ -0,0 +1,37 @@
+<html>
+<head>
+<!--
+  Copyright 2006-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+-->
+</head>
+<body>
+<p>Features that allow a user to interact with a document on the screen [PDF:1.6:8].</p>
+
+<h2>Related Documentation</h2>
+<p>For overviews, tutorials, examples, guides, and tool documentation, please see:</p>
+<ul>
+  <li><a href="http://clown.stefanochizzolini.it">PDF Clown Home Page</a>
+</ul>
+</body>
+</html>
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/viewer/ViewerPreferences.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/viewer/ViewerPreferences.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/viewer/ViewerPreferences.java	(revision 23703)
@@ -0,0 +1,260 @@
+/*
+  Copyright 2006-2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interaction.viewer;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.files.File;
+import it.stefanochizzolini.clown.objects.PdfAtomicObject;
+import it.stefanochizzolini.clown.objects.PdfBoolean;
+import it.stefanochizzolini.clown.objects.PdfDictionary;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfObjectWrapper;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+/**
+  Viewer preferences [PDF:1.6:8.1].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.7
+*/
+public class ViewerPreferences
+  extends PdfObjectWrapper<PdfDictionary>
+{
+  // <class>
+  // <classes>
+  /**
+    Predominant reading order for text [PDF:1.6:8.1].
+  */
+  public enum DirectionEnum
+  {
+    // <class>
+    // <static>
+    // <fields>
+    /**
+      Left to right.
+    */
+    LeftToRight(PdfName.L2R),
+    /**
+      Right to left.
+    */
+    RightToLeft(PdfName.R2L);
+    // </fields>
+
+    // <interface>
+    // <public>
+    /**
+      Gets the direction corresponding to the given value.
+    */
+    public static DirectionEnum get(
+      PdfName value
+      )
+    {
+      for(DirectionEnum direction : DirectionEnum.values())
+      {
+        if(direction.getCode().equals(value))
+          return direction;
+      }
+      return null;
+    }
+    // </public>
+    // </interface>
+    // </static>
+
+    // <dynamic>
+    // <fields>
+    private final PdfName code;
+    // </fields>
+
+    // <constructors>
+    private DirectionEnum(
+      PdfName code
+      )
+    {this.code = code;}
+    // </constructors>
+
+    // <interface>
+    // <public>
+    public PdfName getCode(
+      )
+    {return code;}
+    // </public>
+    // </interface>
+    // </dynamic>
+    // </class>
+  }
+  // </classes>
+
+  // <dynamic>
+  // <constructors>
+  public ViewerPreferences(
+    Document context
+    )
+  {
+    super(
+      context.getFile(),
+      new PdfDictionary()
+      );
+  }
+
+  /**
+    For internal use only.
+  */
+  public ViewerPreferences(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {
+    super(
+      baseObject,
+      container
+      );
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public ViewerPreferences clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  public DirectionEnum getDirection(
+    )
+  {
+    /*
+      NOTE: 'Direction' entry may be undefined.
+    */
+    PdfName directionObject = (PdfName)getBaseDataObject().get(PdfName.Direction);
+    if(directionObject == null)
+      return DirectionEnum.LeftToRight;
+
+    return DirectionEnum.get(directionObject);
+  }
+
+  public boolean isCenterWindow(
+    )
+  {return this.<Boolean,PdfBoolean>getEntry(PdfName.CenterWindow);}
+
+  public boolean isDisplayDocTitle(
+    )
+  {return this.<Boolean,PdfBoolean>getEntry(PdfName.DisplayDocTitle);}
+
+  public boolean isFitWindow(
+    )
+  {return this.<Boolean,PdfBoolean>getEntry(PdfName.FitWindow);}
+
+  public boolean isHideMenubar(
+    )
+  {return this.<Boolean,PdfBoolean>getEntry(PdfName.HideMenubar);}
+
+  public boolean isHideToolbar(
+    )
+  {return this.<Boolean,PdfBoolean>getEntry(PdfName.HideToolbar);}
+
+  public boolean isHideWindowUI(
+    )
+  {return this.<Boolean,PdfBoolean>getEntry(PdfName.HideWindowUI);}
+
+  public void setCenterWindow(
+    boolean value
+    )
+  {this.<Boolean,PdfBoolean>setEntry(PdfName.CenterWindow,value,PdfBoolean.class);}
+
+  public void setDirection(
+    DirectionEnum value
+    )
+  {getBaseDataObject().put(PdfName.Direction,value.getCode());}
+
+  public void setDisplayDocTitle(
+    boolean value
+    )
+  {this.<Boolean,PdfBoolean>setEntry(PdfName.DisplayDocTitle,value,PdfBoolean.class);}
+
+  public void setFitWindow(
+    boolean value
+    )
+  {this.<Boolean,PdfBoolean>setEntry(PdfName.FitWindow,value,PdfBoolean.class);}
+
+  public void setHideMenubar(
+    boolean value
+    )
+  {this.<Boolean,PdfBoolean>setEntry(PdfName.HideMenubar,value,PdfBoolean.class);}
+
+  public void setHideToolbar(
+    boolean value
+    )
+  {this.<Boolean,PdfBoolean>setEntry(PdfName.HideToolbar,value,PdfBoolean.class);}
+
+  public void setHideWindowUI(
+    boolean value
+    )
+  {this.<Boolean,PdfBoolean>setEntry(PdfName.HideWindowUI,value,PdfBoolean.class);}
+  // </public>
+
+  // <protected>
+  @SuppressWarnings("unchecked")
+  protected <T,TPdf extends PdfAtomicObject<T>> T getEntry(
+    PdfName key
+    )
+  {
+    TPdf entry = (TPdf)File.resolve(getBaseDataObject().get(key));
+    if(entry == null)
+      return null;
+
+    return (T)entry.getValue();
+  }
+
+  @SuppressWarnings("unchecked")
+  protected <T,TPdf extends PdfAtomicObject<T>> void setEntry(
+    PdfName key,
+    T value,
+    Class<TPdf> entryType // This Class<TPdf> parameter is an ugly workaround to the horrific generics type erasure that precludes full reflection over parameterized types.
+    )
+  {
+    TPdf entry = (TPdf)File.resolve(getBaseDataObject().get(key));
+    if(entry == null)
+    {
+      try
+      {
+        getBaseDataObject().put(
+          key,
+          entry = entryType.newInstance()
+          );
+      }
+      catch(Exception e)
+      {throw new RuntimeException(e);}
+    }
+
+    entry.setValue(value);
+  }
+  // </protected>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/viewer/package.html
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/viewer/package.html	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interaction/viewer/package.html	(revision 23703)
@@ -0,0 +1,37 @@
+<html>
+<head>
+<!--
+  Copyright 2008-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+-->
+</head>
+<body>
+<p>PDF viewer settings [PDF:1.6:8.1].</p>
+
+<h2>Related Documentation</h2>
+<p>For overviews, tutorials, examples, guides, and tool documentation, please see:</p>
+<ul>
+  <li><a href="http://clown.stefanochizzolini.it">PDF Clown Home Page</a>
+</ul>
+</body>
+</html>
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interchange/metadata/Information.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interchange/metadata/Information.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interchange/metadata/Information.java	(revision 23703)
@@ -0,0 +1,211 @@
+/*
+  Copyright 2006-2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.interchange.metadata;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.files.File;
+import it.stefanochizzolini.clown.objects.PdfAtomicObject;
+import it.stefanochizzolini.clown.objects.PdfDate;
+import it.stefanochizzolini.clown.objects.PdfDictionary;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfObjectWrapper;
+import it.stefanochizzolini.clown.objects.PdfTextString;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.util.Date;
+
+/**
+  Document information [PDF:1.6:10.2.1].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.6
+*/
+public class Information
+  extends PdfObjectWrapper<PdfDictionary>
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  public Information(
+    Document context
+    )
+  {
+    super(
+      context.getFile(),
+      new PdfDictionary()
+      );
+
+    try
+    {
+      Package package_ = getClass().getPackage();
+      setProducer(
+        package_.getSpecificationTitle() + " "
+          + package_.getSpecificationVersion()
+        );
+    }
+    catch(Exception e)
+    {/* NOOP (noncritical exception). */}
+  }
+
+  /**
+    For internal use only.
+  */
+  public Information(
+    PdfDirectObject baseObject
+    )
+  {
+    super(
+      baseObject,
+      null // NO container (baseObject MUST be an indirect object [PDF:1.6:3.4.4]).
+      );
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  public String getAuthor(
+    )
+  {return (String)this.<PdfTextString>getEntry(PdfName.Author);}
+
+  @Override
+  public Information clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  public Date getCreationDate(
+    )
+  {return (Date)this.<PdfDate>getEntry(PdfName.CreationDate);}
+
+  public String getCreator(
+    )
+  {return (String)this.<PdfTextString>getEntry(PdfName.Creator);}
+
+  public String getKeywords(
+    )
+  {return (String)this.<PdfTextString>getEntry(PdfName.Keywords);}
+
+  public Date getModificationDate(
+    )
+  {return (Date)this.<PdfDate>getEntry(PdfName.ModDate);}
+
+  public String getProducer(
+    )
+  {return (String)this.<PdfTextString>getEntry(PdfName.Producer);}
+
+  public String getSubject(
+    )
+  {return (String)this.<PdfTextString>getEntry(PdfName.Subject);}
+
+  public String getTitle(
+    )
+  {return (String)this.<PdfTextString>getEntry(PdfName.Title);}
+
+  public void setAuthor(
+    String value
+    )
+  {this.<PdfTextString>setEntry(PdfName.Author,value,PdfTextString.class);}
+
+  public void setCreationDate(
+    Date value
+    )
+  {this.<PdfDate>setEntry(PdfName.CreationDate,value,PdfDate.class);}
+
+  public void setCreator(
+    String value
+    )
+  {this.<PdfTextString>setEntry(PdfName.Creator,value,PdfTextString.class);}
+
+  public void setKeywords(
+    String value
+    )
+  {this.<PdfTextString>setEntry(PdfName.Keywords,value,PdfTextString.class);}
+
+  public void setModificationDate(
+    Date value
+    )
+  {this.<PdfDate>setEntry(PdfName.ModDate,value,PdfDate.class);}
+
+  public void setProducer(
+    String value
+    )
+  {this.<PdfTextString>setEntry(PdfName.Producer,value,PdfTextString.class);}
+
+  public void setSubject(
+    String value
+    )
+  {this.<PdfTextString>setEntry(PdfName.Subject,value,PdfTextString.class);}
+
+  public void setTitle(
+    String value
+    )
+  {this.<PdfTextString>setEntry(PdfName.Title,value,PdfTextString.class);}
+  // </public>
+
+  // <protected>
+  @SuppressWarnings("unchecked")
+  protected <TPdf extends PdfAtomicObject<?>> Object getEntry(
+    PdfName key
+    )
+  {
+    TPdf entry = (TPdf)File.resolve(getBaseDataObject().get(key));
+    if(entry == null)
+      return null;
+
+    return entry.getValue();
+  }
+
+  @SuppressWarnings("unchecked")
+  protected <TPdf extends PdfAtomicObject<?>> void setEntry(
+    PdfName key,
+    Object value,
+    Class<TPdf> entryType // This Class<TPdf> parameter is an ugly workaround to the horrific generics type erasure that precludes full reflection over parameterized types.
+    )
+  {
+    TPdf entry = (TPdf)File.resolve(getBaseDataObject().get(key));
+    if(entry == null)
+    {
+      try
+      {
+        getBaseDataObject().put(
+          key,
+          entry = entryType.newInstance()
+          );
+      }
+      catch(Exception e)
+      {
+        // Propagate the exception!
+        throw new RuntimeException(e);
+      }
+    }
+
+    entry.setValue(value);
+  }
+  // </protected>
+  // </interface>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interchange/metadata/package.html
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interchange/metadata/package.html	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interchange/metadata/package.html	(revision 23703)
@@ -0,0 +1,37 @@
+<html>
+<head>
+<!--
+  Copyright 2006-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+  
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+  
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+-->
+</head>
+<body>
+<p>Features that support global information about the document [PDF:1.6:10.2].</p>
+
+<h2>Related Documentation</h2>
+<p>For overviews, tutorials, examples, guides, and tool documentation, please see:</p>
+<ul>
+  <li><a href="http://clown.stefanochizzolini.it">PDF Clown Home Page</a>
+</ul>
+</body>
+</html>
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interchange/package.html
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interchange/package.html	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/interchange/package.html	(revision 23703)
@@ -0,0 +1,37 @@
+<html>
+<head>
+<!--
+  Copyright 2006-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+  
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+  
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+-->
+</head>
+<body>
+<p>Features that enable a document to include higher-level information that is useful for the interchange of documents among applications [PDF:1.6:10].</p>
+
+<h2>Related Documentation</h2>
+<p>For overviews, tutorials, examples, guides, and tool documentation, please see:</p>
+<ul>
+  <li><a href="http://clown.stefanochizzolini.it">PDF Clown Home Page</a>
+</ul>
+</body>
+</html>
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/multimedia/Movie.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/multimedia/Movie.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/multimedia/Movie.java	(revision 23703)
@@ -0,0 +1,105 @@
+/*
+  Copyright 2008-2009 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.multimedia;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.fileSpecs.FileSpec;
+import it.stefanochizzolini.clown.objects.PdfDictionary;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfObjectWrapper;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+//TODO: this is just a stub.
+/**
+  Movie object [PDF:1.6:9.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.7
+  @since 0.0.7
+*/
+public class Movie
+  extends PdfObjectWrapper<PdfDictionary>
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  /**
+    Creates a new movie within the given document context.
+  */
+  public Movie(
+    Document context,
+    FileSpec fileSpec
+    )
+  {
+    super(
+      context.getFile(),
+      new PdfDictionary()
+      );
+
+    setFileSpec(fileSpec);
+  }
+
+  public Movie(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {super(baseObject,container);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public Movie clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    Gets the file associated with this movie.
+  */
+  public FileSpec getFileSpec(
+    )
+  {
+    /*
+      NOTE: 'F' entry MUST exist.
+    */
+    return new FileSpec(getBaseDataObject().get(PdfName.F),getContainer(),null);
+  }
+
+  /**
+    @see #getFileSpec()
+  */
+  public void setFileSpec(
+    FileSpec value
+    )
+  {getBaseDataObject().put(PdfName.F, value.getBaseObject());}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/multimedia/Sound.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/multimedia/Sound.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/multimedia/Sound.java	(revision 23703)
@@ -0,0 +1,93 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.documents.multimedia;
+
+import it.stefanochizzolini.clown.bytes.IInputStream;
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.objects.PdfDictionary;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfObjectWrapper;
+import it.stefanochizzolini.clown.objects.PdfStream;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+//TODO: this is just a stub.
+/**
+  Sound object [PDF:1.6:9.2].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.7
+  @since 0.0.7
+*/
+public class Sound
+  extends PdfObjectWrapper<PdfStream>
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  /**
+    Creates a new sound within the given document context.
+  */
+  public Sound(
+    Document context,
+    IInputStream stream
+    )
+  {
+    super(
+      context.getFile(),
+      new PdfStream(
+        new PdfDictionary(
+          new PdfName[]{PdfName.Type},
+          new PdfDirectObject[]{PdfName.Sound}
+          )
+        )
+      );
+    throw new NotImplementedException("Process the sound stream!");
+  }
+
+  public Sound(
+    PdfDirectObject baseObject
+    )
+  {
+    super(
+      baseObject,
+      null // NO container (streams are self-contained).
+      );
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public Sound clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/multimedia/package.html
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/multimedia/package.html	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/multimedia/package.html	(revision 23703)
@@ -0,0 +1,37 @@
+<html>
+<head>
+<!--
+  Copyright 2008-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+-->
+</head>
+<body>
+<p>Features that allow a user to embed and play multimedia content within a PDF document [PDF:1.6:9].</p>
+
+<h2>Related Documentation</h2>
+<p>For overviews, tutorials, examples, guides, and tool documentation, please see:</p>
+<ul>
+  <li><a href="http://clown.stefanochizzolini.it">PDF Clown Home Page</a>
+</ul>
+</body>
+</html>
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/package.html
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/package.html	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/documents/package.html	(revision 23703)
@@ -0,0 +1,37 @@
+<html>
+<head>
+<!--
+  Copyright 2006-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+-->
+</head>
+<body>
+<p>Document-level objects [PDF:1.6:3.6].</p>
+
+<h2>Related Documentation</h2>
+<p>For overviews, tutorials, examples, guides, and tool documentation, please see:</p>
+<ul>
+  <li><a href="http://clown.stefanochizzolini.it">PDF Clown Home Page</a>
+</ul>
+</body>
+</html>
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/files/File.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/files/File.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/files/File.java	(revision 23703)
@@ -0,0 +1,409 @@
+/*
+  Copyright 2006-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.files;
+
+import it.stefanochizzolini.clown.bytes.FileInputStream;
+import it.stefanochizzolini.clown.bytes.IInputStream;
+import it.stefanochizzolini.clown.bytes.IOutputStream;
+import it.stefanochizzolini.clown.bytes.OutputStream;
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.objects.IPdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfDataObject;
+import it.stefanochizzolini.clown.objects.PdfDictionary;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfObject;
+import it.stefanochizzolini.clown.objects.PdfReference;
+import it.stefanochizzolini.clown.tokens.FileFormatException;
+import it.stefanochizzolini.clown.tokens.Reader;
+import it.stefanochizzolini.clown.tokens.Writer;
+import it.stefanochizzolini.clown.tokens.XRefEntry;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.io.Closeable;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.Random;
+
+/**
+  PDF file representation.
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.0
+  @version 0.0.8
+*/
+public class File
+  implements Closeable
+{
+  // <class>
+  // <classes>
+  public static final class ResolvedObject<T extends PdfDataObject>
+  {
+    public final T dataObject;
+    public final PdfIndirectObject container;
+
+    private ResolvedObject(
+      T dataObject,
+      PdfIndirectObject container
+      )
+    {
+      this.dataObject = dataObject;
+      this.container = container;
+    }
+  }
+  // </classes>
+
+  // <static>
+  // <fields>
+  private static Random hashCodeGenerator = new Random();
+  // </fields>
+
+  // <interface>
+  // <public>
+  /**
+    Forces a generic object to be expressed as its corresponding data object.
+  */
+  public static PdfDataObject resolve(
+    PdfObject object
+    )
+  {
+    if(object instanceof IPdfIndirectObject)
+      return ((IPdfIndirectObject)object).getDataObject();
+    else
+      return (PdfDataObject)object;
+  }
+
+  /**
+    Resolves a generic object.
+  */
+  @SuppressWarnings("unchecked")
+  public static <T extends PdfDataObject> ResolvedObject<T> resolve(
+    PdfObject object,
+    IPdfIndirectObject container
+    )
+  {
+    if(object == null)
+      return null;
+    else if(object instanceof IPdfIndirectObject)
+    {
+      IPdfIndirectObject indirectObject = (IPdfIndirectObject)object;
+      return new ResolvedObject<T>((T)indirectObject.getDataObject(),indirectObject.getIndirectObject());
+    }
+    else
+      return new ResolvedObject<T>((T)object,container.getIndirectObject());
+  }
+
+  /**
+    Forces a direct object to be updated (whether possible).
+  */
+  public static boolean update(
+    PdfDirectObject object
+    )
+  {
+    /*
+      NOTE: Only PDF references are able to be updated. Other direct types
+      are dependent on their respective containers for update.
+    */
+    if(object instanceof PdfReference)
+    {
+      ((PdfReference)object).getIndirectObject().update();
+      return true;
+    }
+    else
+      return false;
+  }
+  // </public>
+  // </interface>
+  // </static>
+
+  // <dynamic>
+  // <fields>
+  private Document document;
+  private int hashCode = File.hashCodeGenerator.nextInt();
+  private IndirectObjects indirectObjects;
+  private Reader reader;
+  private PdfDictionary trailer;
+  private String version;
+  private XRefEntry[] xrefEntries;
+
+  private String path;
+  // </fields>
+
+  // <constructors>
+  public File(
+    )
+  {
+    this.version = "1.6";
+    this.trailer = new PdfDictionary();
+    this.indirectObjects = new IndirectObjects(this,null);
+    this.document = new Document(this);
+  }
+
+  public File(
+    String path
+    ) throws FileFormatException,
+      java.io.FileNotFoundException
+  {
+    this(
+      new FileInputStream(
+        new java.io.RandomAccessFile(path,"r")
+        )
+      );
+    this.path = path;
+  }
+
+  public File(
+    IInputStream stream
+    ) throws FileFormatException
+  {
+    this.reader = new Reader(stream,this);
+
+    this.version = reader.readVersion();
+    this.trailer = reader.readTrailer();
+
+    // Is this file encrypted?
+    if(trailer.containsKey(PdfName.Encrypt))
+      throw new NotImplementedException("Encrypted files are currently not supported.");
+
+    this.xrefEntries = reader.readXRefTable(trailer);
+    this.indirectObjects = new IndirectObjects(this,xrefEntries);
+    this.document = new Document(trailer.get(PdfName.Root));
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  public Document getDocument(
+    )
+  {return document;}
+
+  public IndirectObjects getIndirectObjects(
+    )
+  {return indirectObjects;}
+
+  public Reader getReader(
+    )
+  {return reader;}
+
+  public PdfDictionary getTrailer(
+    )
+  {return trailer;}
+
+  /**
+    Gets the file header version [PDF:1.6:3.4.1].
+    <h3>Remarks</h3>
+    <p>This property represents just the original file version; to get the actual version,
+    use the {@link it.stefanochizzolini.clown.documents.Document#getVersion() Document.getVersion} method.</p>
+  */
+  public String getVersion(
+    )
+  {return version;}
+
+  //TODO:IMPL avoid direct exposure of array (corruptible!)!!!
+  public XRefEntry[] getXRefEntries(
+    )
+  {return xrefEntries;}
+
+  public int hashCode(
+    )
+  {return hashCode;}
+
+  /**
+    Registers an <b>internal data object</b>.
+    @since 0.0.4
+  */
+  public PdfReference register(
+    PdfDataObject object
+    )
+  {return indirectObjects.add(object).getReference();}
+
+  /**
+    Serializes the file to the current file-system path using the standard serialization mode.
+  */
+  public void save(
+    ) throws IOException
+  {save(SerializationModeEnum.Standard);}
+
+  /**
+    Serializes the file to the current file-system path.
+    @param mode Serialization mode.
+  */
+  public void save(
+    SerializationModeEnum mode
+    ) throws IOException
+  {
+    if(!new java.io.File(path).exists())
+      throw new FileNotFoundException("No valid source path available: use writeTo instead.");
+
+    /*
+      NOTE: The document file cannot be directly overwritten
+      as it's locked for reading by the open stream;
+      its update is therefore delayed to its disposal,
+      when the temporary file will overwrite it (see Dispose method).
+    */
+    writeTo(getTempPath(),mode);
+  }
+
+  /**
+    Unregisters an <b>internal object</b>.
+    @since 0.0.5
+  */
+  public void unregister(
+    PdfReference reference
+    )
+  {indirectObjects.remove(reference.getObjectNumber());}
+
+  /**
+    Serializes the file to the specified file-system path.
+    @param path Target path.
+    @param mode Serialization mode.
+  */
+  public void writeTo(
+    String path,
+    SerializationModeEnum mode
+    ) throws IOException
+  {
+    writeTo(
+      new java.io.File(path),
+      mode
+      );
+  }
+
+  /**
+    Serializes the file to the specified file-system file.
+    @param file Target file.
+    @param mode Serialization mode.
+  */
+  public void writeTo(
+    java.io.File file,
+    SerializationModeEnum mode
+    ) throws IOException
+  {
+    OutputStream outputStream;
+    java.io.BufferedOutputStream baseOutputStream;
+    try
+    {
+      file.createNewFile();
+      baseOutputStream = new java.io.BufferedOutputStream(
+        new java.io.FileOutputStream(file)
+        );
+      outputStream = new OutputStream(baseOutputStream);
+    }
+    catch(Exception e)
+    {throw new IOException(file.getPath() + " file couldn't be created.",e);}
+
+    try
+    {
+      writeTo(
+        outputStream,
+        mode
+        );
+
+      baseOutputStream.flush();
+      baseOutputStream.close();
+    }
+    catch(Exception e)
+    {throw new IOException(file.getPath() + " file writing has failed.",e);}
+  }
+
+  /**
+    Serializes the file to the specified stream.
+    <h3>Remarks</h3>
+    <p>It's caller responsibility to close the stream after this method ends.</p>
+    @param stream Target stream.
+    @param mode Serialization mode.
+  */
+  public void writeTo(
+    IOutputStream stream,
+    SerializationModeEnum mode
+    )
+  {
+    Writer writer = new Writer(stream,this);
+
+    switch(mode)
+    {
+      case Incremental:
+        if(reader != null)
+        {
+          writer.writeIncremental();
+          break;
+        }
+        // If reader IS null, fall through to Standard!
+      case Standard:
+        writer.writeStandard();
+        break;
+      case Linearized:
+        throw new NotImplementedException();
+    }
+  }
+
+  // <Closeable>
+  public void close(
+    ) throws IOException
+  {
+    if(reader != null)
+    {
+      reader.close();
+      reader = null;
+
+      /*
+        NOTE: If the temporary file exists (see Save method),
+        overwrite the document file.
+      */
+      java.io.File sourceFile = new java.io.File(getTempPath());
+      if(sourceFile.exists())
+      {
+        java.io.File targetFile = new java.io.File(path);
+        targetFile.delete();
+        sourceFile.renameTo(targetFile);
+      }
+    }
+  }
+  // </Closeable>
+  // </public>
+
+  // <protected>
+  @Override
+  protected void finalize(
+    ) throws Throwable
+  {
+    try
+    {close();}
+    finally
+    {super.finalize();}
+  }
+  // </protected>
+
+  // <private>
+  private String getTempPath(
+    )
+  {return (path == null ? null : path + ".tmp");}
+  // </private>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/files/IndirectObjects.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/files/IndirectObjects.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/files/IndirectObjects.java	(revision 23703)
@@ -0,0 +1,583 @@
+/*
+  Copyright 2006-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.files;
+
+import it.stefanochizzolini.clown.objects.PdfDataObject;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.tokens.XRefEntry;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.NoSuchElementException;
+import java.util.TreeMap;
+
+/**
+  Collection of the <b>alive indirect objects</b> available inside the file.
+  <h3>Remarks</h3>
+  <p>According to the PDF spec, <i>indirect object entries may be free
+  (no data object associated) or in-use (data object associated)</i>.</p>
+  <p>We can effectively subdivide indirect objects in two possibly-overriding
+  collections: the <b>original indirect objects</b> (coming from the associated
+  preexisting file) and the <b>newly-registered indirect objects</b> (coming
+  from new data objects or original indirect objects manipulated during the
+  current session).</p>
+  <p><i>To ensure that the modifications applied to an original indirect object
+  are committed to being persistent</i> is critical that the modified original
+  indirect object is newly-registered (practically overriding the original
+  indirect object).</p>
+  <p><b>Alive indirect objects</b> encompass all the newly-registered ones plus
+  not-overridden original ones.</p>
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.0
+  @version 0.0.8
+*/
+public class IndirectObjects
+  implements List<PdfIndirectObject>
+{
+  // <class>
+  // <dynamic>
+  // <fields>
+  /**
+    Associated file.
+  */
+  private File file;
+
+  /**
+    Map of matching references of imported indirect objects.
+    <h3>Remarks</h3>
+    <p>This collection is used to prevent duplications among imported indirect
+    objects.</p>
+    <p><code>Key</code> is the external indirect object hashcode, <code>Value</code> is the
+    matching internal indirect object.</p>
+  */
+  private Hashtable<Integer,PdfIndirectObject> importedObjects = new Hashtable<Integer,PdfIndirectObject>();
+  /**
+    Collection of newly-registered indirect objects.
+  */
+  private TreeMap<Integer,PdfIndirectObject> modifiedObjects = new TreeMap<Integer,PdfIndirectObject>();
+  /**
+    Collection of instantiated original indirect objects.
+    <h3>Remarks</h3>
+    <p>This collection is useful as a cache to avoid unconsistent parsing duplications.</p>
+  */
+  private TreeMap<Integer,PdfIndirectObject> wokenObjects = new TreeMap<Integer,PdfIndirectObject>();
+
+  /**
+    Object counter.
+  */
+  private int lastObjectNumber = -1; // Empty.
+  /**
+    Offsets of the original indirect objects inside the associated file (to say:
+    implicit collection of the original indirect objects).
+    <h3>Remarks
+    <p>This information is vital to randomly retrieve the indirect-object persistent
+    representation inside the associated file.</p>
+  */
+  private XRefEntry[] xrefEntries;
+
+  private UpdateModeEnum updateMode = UpdateModeEnum.Manual;
+  // </fields>
+
+  // <constructors>
+  IndirectObjects(
+    File file,
+    XRefEntry[] xrefEntries
+    )
+  {
+    this.file = file;
+    this.xrefEntries = xrefEntries;
+    // Are there original indirect objects?
+    if(this.xrefEntries == null)
+    {
+      /*
+        [PDF:1.6:3.4.3] Mandatory head of the linked list of free objects
+        at object number 0.
+      */
+      // Register the leading free-object!
+      lastObjectNumber++;
+      modifiedObjects.put(
+        lastObjectNumber,
+        new PdfIndirectObject(
+          this.file,
+          null,
+          new XRefEntry(
+            lastObjectNumber,
+            XRefEntry.GenerationUnreusable,
+            0,
+            XRefEntry.UsageEnum.Free
+            )
+          )
+        );
+    }
+    else
+    {
+      // Adjust the object counter!
+      lastObjectNumber = xrefEntries.length - 1;
+    }
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  public File getFile(
+    )
+  {return file;}
+
+  /**
+    Register an <b>internal data object</b>.
+    <h3>Remarks</h3>
+    <p>Alternatives:<ul>
+    <li>To register a modified internal indirect object, use
+    {@link #set(int,PdfIndirectObject) set(int,PdfIndirectObject)}.</li>
+    <li>To register an external indirect object, use
+    {@link #addExternal(PdfIndirectObject) addExternal(PdfIndirectObject)}.</li>
+    </ul></p>
+  */
+  public PdfIndirectObject add(
+    PdfDataObject object
+    )
+  {
+    // Wrap the data object inside a new indirect object!
+    lastObjectNumber++;
+    PdfIndirectObject indirectObject = new PdfIndirectObject(
+      file,
+      object,
+      new XRefEntry(
+        lastObjectNumber,
+        0,
+        0,
+        XRefEntry.UsageEnum.InUse
+        )
+      );
+    // Register the object!
+    modifiedObjects.put(lastObjectNumber,indirectObject);
+
+    return indirectObject;
+  }
+
+  /**
+    Registers and gets an <b>external indirect object</b>.
+    <h3>Remarks</h3>
+    <p>External indirect objects come from alien PDF files. <i>This is a powerful
+    way to import the content of one file into another</i>.</p>
+    <p>Alternatives:<ul>
+    <li>To register a modified internal indirect object, use
+    {@link #set(int,PdfIndirectObject) set(int,PdfIndirectObject)}.</li>
+    <li>To register an internal data object, use
+    {@link #add(PdfDataObject) add(PdfDataObject)}.</li></ul></p>
+  */
+  public PdfIndirectObject addExternal(
+    PdfIndirectObject object
+    )
+  {
+    PdfIndirectObject indirectObject = importedObjects.get(object.hashCode());
+    // Hasn't the external indirect object been imported yet?
+    if(indirectObject == null)
+    {
+      // Register the clone of the data object corresponding to the external indirect object!
+      indirectObject = add((PdfDataObject)object.getDataObject().clone(file));
+      // Keep track of the imported indirect object!
+      importedObjects.put(object.hashCode(),indirectObject);
+    }
+
+    return indirectObject;
+  }
+
+  public Collection<? extends PdfIndirectObject> addAllExternal(
+    Collection<? extends PdfIndirectObject> objects
+    )
+  {
+    ArrayList<PdfIndirectObject> addedObjects = new ArrayList<PdfIndirectObject>(objects.size());
+    for(PdfIndirectObject object : objects)
+    {addedObjects.add((PdfIndirectObject)addExternal(object));}
+
+    return addedObjects;
+  }
+
+  // <List>
+  public void add(
+    int index,
+    PdfIndirectObject object
+    )
+  {throw new UnsupportedOperationException();}
+
+  public boolean addAll(
+    int index,
+    Collection<? extends PdfIndirectObject> objects
+    )
+  {throw new UnsupportedOperationException();}
+
+  /**
+    Gets an indirect object with the specified object number.
+    @param index Object number of the indirect object to get.
+    @return Indirect object corresponding to the specified object number.
+  */
+  public PdfIndirectObject get(
+    int index
+    )
+  {
+    // Try among the new objects!
+    PdfIndirectObject object = modifiedObjects.get(index);
+    // Is it among the original objects?
+    if(object == null)
+    {
+      // Try among the woken original objects!
+      object = wokenObjects.get(index);
+      // Is it among the sleeping original objects?
+      if(object == null)
+      {
+        try
+        {
+          object = new PdfIndirectObject(
+            file,
+            null,
+            xrefEntries[index]
+            );
+        }
+        catch(Exception e)
+        {throw new RuntimeException(e);}
+
+        // Now it's awake!
+        /*
+        NOTE: This operation allows to keep a consistant state across the whole session,
+        avoiding multiple incoherent instantiations of the same original indirect object.
+        */
+        wokenObjects.put(index,object);
+
+        // Early registration?
+        if(updateMode == UpdateModeEnum.Automatic)
+        {update(object); /* Force early registration. */}
+      }
+    }
+
+    return object;
+  }
+
+  public int indexOf(
+    Object object
+    )
+  {
+    // Is this indirect object associated to this file?
+    if(((PdfIndirectObject)object).getFile() != file)
+      return -1;
+
+    return ((PdfIndirectObject)object).getReference().getObjectNumber();
+  }
+
+  public int lastIndexOf(
+    Object object
+    )
+  {
+    /*
+      NOTE: By definition, there's a bijective relation between indirect objects
+      and their indices.
+    */
+    return indexOf(object);
+  }
+
+  public ListIterator<PdfIndirectObject> listIterator(
+    )
+  {throw new NotImplementedException();}
+
+  public ListIterator<PdfIndirectObject> listIterator(
+    int index
+    )
+  {throw new NotImplementedException();}
+
+  public PdfIndirectObject remove(
+    int index
+    )
+  {
+    /*
+      NOTE: Acrobat 6.0 and later (PDF 1.5+) DO NOT use the free list to recycle object numbers;
+      new objects are assigned new numbers [PDF:1.6:H.3:16].
+      According to such an implementation note, we simply mark the removed object as 'not-reusable'
+      newly-freed entry, neglecting both to add it to the linked list of free entries
+      and to increment by 1 its generation number.
+    */
+    return update(
+      new PdfIndirectObject(
+        file,
+        null,
+        new XRefEntry(
+          index,
+          XRefEntry.GenerationUnreusable,
+          0,
+          XRefEntry.UsageEnum.Free
+          )
+        )
+      );
+  }
+
+  /**
+    Sets an indirect object with the specified object number.
+    <h3>Contract</h3>
+    <ul>
+      <li>Preconditions:
+        <ol>
+          <li><code>index</code> value MUST be between 1 and (size() - 1); index 0
+          is reserved to the mandatory head of the linked list of free objects [PDF:1.6:3.4.3].</li>
+        </ol>
+      </li>
+      <li>Postconditions:<ol><li>(none).</li></ol></li>
+      <li>Invariants:<ol><li>(none).</li></ol></li>
+      <li>Side-effects:<ol><li>(none).</li></ol></li>
+    </ul>
+    <h3>Remarks</h3>
+    <p>This method is currently limited to <b>internal indirect
+    objects</b>: <i>use it to register modified internal indirect objects only</i>.
+    If you need to register alternative-type objects, consider the following
+    methods:</p>
+    <ul>
+      <li>to register an <b>external indirect object</b>, use
+      {@link #addExternal(PdfIndirectObject) addExternal(PdfIndirectObject)}.</li>
+      <li>to register an <b>internal data object</b>, use
+      {@link #add(PdfDataObject) add(PdfDataObject)}.</li>
+    </ul>
+    @param index Object number of the indirect object to set.
+    @param object Indirect object to set.
+    @return Replaced indirect object.
+  */
+  public PdfIndirectObject set(
+    int index,
+    PdfIndirectObject object
+    )
+  {throw new UnsupportedOperationException();}
+
+  public List<PdfIndirectObject> subList(
+    int fromIndex,
+    int toIndex
+    )
+  {throw new NotImplementedException();}
+
+  // <Collection>
+  /**
+    Registers an <b>external indirect object</b>.
+    <h3>Remarks</h3>
+    <p>External indirect objects come from alien PDF files. <i>This is a powerful
+    way to import the content of one file into another</i>.</p>
+    <p>Alternatives:<ul>
+    <li>To register and get an external indirect object, use
+    {@link #addExternal(PdfIndirectObject) addExternal(PdfIndirectObject)}.</li>
+    </ul></p>
+  */
+  public boolean add(
+    PdfIndirectObject object
+    )
+  {
+    boolean changed = (addExternal(object) != null);
+
+    return changed;
+  }
+
+  /**
+    Registers <b>external indirect objects</b>.
+    <h3>Remarks</h3>
+    <p>External indirect objects come from alien PDF files. <i>This is a powerful
+    way to import the content of one file into another</i>.</p>
+    <p>Alternatives:<ul>
+    <li>To register and get external indirect object, use
+    {@link #addAllExternal(Collection<? extends PdfIndirectObject>) addAllExternal(Collection<? extends PdfIndirectObject>)}.</li>
+    </ul></p>
+  */
+  public boolean addAll(
+    Collection<? extends PdfIndirectObject> objects
+    )
+  {
+    boolean changed = false;
+    for(PdfIndirectObject object : objects)
+    {
+      changed |= (addExternal(object) != null);
+    }
+
+    return changed;
+  }
+
+  public void clear(
+    )
+  {throw new UnsupportedOperationException();}
+
+  public boolean contains(
+    Object object
+    )
+  {throw new NotImplementedException();}
+
+  public boolean containsAll(
+    Collection<?> objects
+    )
+  {throw new NotImplementedException();}
+
+  public boolean equals(
+    Object object
+    )
+  {throw new NotImplementedException();}
+
+  public int hashCode(
+    )
+  {throw new NotImplementedException();}
+
+  public boolean isEmpty(
+    )
+  {
+    /*
+    NOTE: Semantics of the indirect objects collection imply that the collection is considered
+    empty in any case no in-use object is available.
+    */
+    for(PdfIndirectObject object : this)
+    {
+      if(object.isInUse())
+        return false;
+    }
+
+    return true;
+  }
+
+  /**
+    @since 0.0.0
+  */
+  public boolean remove(
+    Object object
+    )
+  {
+    return (remove(
+      ((PdfIndirectObject)object).getReference().getObjectNumber()
+      ) != null);
+  }
+
+  public boolean removeAll(
+    Collection<?> objects
+    )
+  {throw new NotImplementedException();}
+
+  public boolean retainAll(
+    Collection<?> objects
+    )
+  {throw new UnsupportedOperationException();}
+
+  /**
+    Gets the number of entries available (both in-use and free) in the
+    collection.
+    @return The number of entries available in the collection.
+  */
+  public int size(
+    )
+  {return (lastObjectNumber + 1);}
+
+  public PdfIndirectObject[] toArray(
+    )
+  {throw new NotImplementedException();}
+
+  public <T> T[] toArray(
+    T[] objects
+    )
+  {throw new NotImplementedException();}
+
+  // <Iterable>
+  public Iterator<PdfIndirectObject> iterator(
+    )
+  {
+    return new Iterator<PdfIndirectObject>()
+    {
+      // <class>
+      // <dynamic>
+      // <fields>
+      /** Index of the next item. */
+      private int index = 0;
+      // </fields>
+
+      // <interface>
+      // <public>
+      // <Iterator>
+      public boolean hasNext(
+        )
+      {return (index < size());}
+
+      public PdfIndirectObject next(
+        )
+      {
+        if(!hasNext())
+          throw new NoSuchElementException();
+
+        return get(index++);
+      }
+
+      public void remove(
+        )
+      {throw new UnsupportedOperationException();}
+      // </Iterator>
+      // </public>
+      // </interface>
+      // </dynamic>
+      // </class>
+    };
+  }
+  // </Iterable>
+  // </Collection>
+  // </List>
+  // </public>
+
+  // <internal>
+  /**
+    For internal use only.
+  */
+  public TreeMap<Integer,PdfIndirectObject> getModifiedObjects(
+    )
+  {return modifiedObjects;}
+
+  /**
+    For internal use only.
+  */
+  public PdfIndirectObject update(
+    PdfIndirectObject object
+    )
+  {
+    int index = object.getReference().getObjectNumber();
+
+    // Get the old indirect object to be replaced!
+    PdfIndirectObject old = get(index);
+    if(old != object)
+    {old.dropFile(); /* Disconnect the old indirect object. */}
+
+    // Insert the new indirect object into the modified objects collection!
+    modifiedObjects.put(index,object);
+    // Remove old indirect object from cache!
+    wokenObjects.remove(index);
+    // Mark the new indirect object as modified!
+    object.dropOriginal();
+
+    return old;
+  }
+  // </internal>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/files/SerializationModeEnum.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/files/SerializationModeEnum.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/files/SerializationModeEnum.java	(revision 23703)
@@ -0,0 +1,49 @@
+/*
+  Copyright 2006 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.files;
+
+/**
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+*/
+public enum SerializationModeEnum
+{
+  /**
+    Reduce serialization size, but loose modifications history.
+    <p>Less space, <i>more computation</i>.</p>
+  */
+  Standard,
+  /**
+    Speed up serialization and keep distinctly track of the modifications
+    [PDF:1.6:2.2.7].
+    <p><i>More space</i>, less computation.</p>
+  */
+  Incremental,
+  /**
+    Enable efficient incremental access in a network environment [PDF:1.6:F].
+    <p><i>More computation</i>.</p>
+  */
+  Linearized
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/files/UpdateModeEnum.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/files/UpdateModeEnum.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/files/UpdateModeEnum.java	(revision 23703)
@@ -0,0 +1,43 @@
+/*
+  Copyright 2006 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.files;
+
+/**
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+*/
+public enum UpdateModeEnum
+{
+  /**
+    Delegate the update management of original indirect objects to the client commitment (late registration).
+    <p>Suitable for incremental update.</p>
+  */
+  Manual,
+  /**
+    Automatically update every original indirect object that is requested, indipendently from any actual modification (early registration).
+    <p>Suitable for compact update.</p>
+  */
+  Automatic
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/files/package.html
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/files/package.html	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/files/package.html	(revision 23703)
@@ -0,0 +1,37 @@
+<html>
+<head>
+<!--
+  Copyright 2006-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+-->
+</head>
+<body>
+<p>File-level objects [PDF:1.6:3.4].</p>
+
+<h2>Related Documentation</h2>
+<p>For overviews, tutorials, examples, guides, and tool documentation, please see:</p>
+<ul>
+  <li><a href="http://clown.stefanochizzolini.it">PDF Clown Home Page</a>
+</ul>
+</body>
+</html>
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/IPdfIndirectObject.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/IPdfIndirectObject.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/IPdfIndirectObject.java	(revision 23703)
@@ -0,0 +1,77 @@
+/*
+  Copyright 2006-2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.objects;
+
+import it.stefanochizzolini.clown.files.File;
+
+/**
+  PDF indirect object interface.
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.7
+*/
+public interface IPdfIndirectObject
+{
+  // <interface>
+  Object clone(
+    File context
+    );
+
+  /**
+    Removes the object from its file context.
+    <h3>Remarks</h3>
+    <p>The object is no more usable after this method returns.</p>
+  */
+  void delete(
+    );
+
+  /**
+    Gets the actual data associated to the indirect reference.
+  */
+  PdfDataObject getDataObject(
+    );
+
+  /**
+    Gets the indirect object associated to the indirect reference.
+  */
+  PdfIndirectObject getIndirectObject(
+    );
+
+  /**
+    Gets the indirect reference associated to the indirect object.
+  */
+  PdfReference getReference(
+    );
+
+  /**
+    @see #getDataObject()
+    @since 0.0.7
+  */
+  void setDataObject(
+    PdfDataObject value
+    );
+  // </interface>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/IPdfNumber.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/IPdfNumber.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/IPdfNumber.java	(revision 23703)
@@ -0,0 +1,43 @@
+/*
+  Copyright 2006 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.objects;
+
+/**
+  PDF number interface.
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+*/
+public interface IPdfNumber
+{
+  double getNumberValue(
+    );
+  void setNumberValue(
+    double value
+    );
+  void translateNumberValue(
+    double value
+    );
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/NameTree.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/NameTree.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/NameTree.java	(revision 23703)
@@ -0,0 +1,835 @@
+/*
+  Copyright 2007-2009 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.objects;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.files.File;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+  Name tree [PDF:1.6:3.8.5].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+  @since 0.0.4
+*/
+public abstract class NameTree<T extends PdfObjectWrapper<?>>
+  extends PdfObjectWrapper<PdfDictionary>
+  implements Map<PdfString, T>
+{
+  // <class>
+  // <types>
+  /**
+    Node children.
+  */
+  private static final class Children
+  {
+    /** Children's collection */
+    public final PdfArray items;
+    /** Node's children order (that is maximum number of items allowed). */
+    public final int order;
+    /** Node's children type. */
+    public final PdfName typeName;
+
+    private Children(
+      PdfArray items,
+      PdfName typeName,
+      int order
+      )
+    {
+      this.items = items;
+      this.typeName = typeName;
+      this.order = order;
+    }
+  }
+
+  private final class Entry
+    implements Map.Entry<PdfString, T>,
+      Comparable<Entry>
+  {
+    // <class>
+    // <dynamic>
+    // <fields>
+    private final PdfString key;
+    private final T value;
+    // </fields>
+
+    // <constructors>
+    private Entry(
+      PdfString key,
+      T value
+      )
+    {
+      this.key = key;
+      this.value = value;
+    }
+    // </constructors>
+
+    // <interface>
+    // <public>
+    // <Comparable>
+    public int compareTo(
+      Entry obj
+      )
+    {return key.compareTo(obj.getKey());}
+    // </Comparable>
+
+    // <Map.Entry>
+    public PdfString getKey(
+      )
+    {return key;}
+
+    public T getValue(
+      )
+    {return value;}
+
+    public T setValue(
+      T value
+      )
+    {throw new UnsupportedOperationException();}
+    // </Map.Entry>
+    // </public>
+    // </interface>
+    // </dynamic>
+    // </class>
+  }
+
+  private interface IFiller<TCollection extends Collection<?>>
+  {
+    void add(
+      PdfArray names,
+      int offset,
+      PdfIndirectObject container
+      );
+    TCollection getCollection(
+      );
+  }
+  // </types>
+
+  // <static>
+  // <fields>
+  /**
+    Minimum number of children for each node.
+  */
+  private static final int NodeMinSize = 5;
+  /**
+    Maximum number of children for each node.
+  */
+  private static final int TreeOrder = NodeMinSize * 2;
+
+  /**
+    Minimum number of name/value items for each node.
+  */
+  private static final int NameNodeMinSize = NodeMinSize * 2; // NOTE: Name collections are arrays of name/value pairs.
+  /**
+    Maximum number of name/value items for each node.
+  */
+  private static final int NameOrder = NameNodeMinSize * 2;
+
+  private static final int[] ChildrenOrders = new int[]{NameOrder, TreeOrder};
+  private static final PdfName[] ChildrenTypeNames = new PdfName[]{PdfName.Names, PdfName.Kids};
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  public NameTree(
+    Document context
+    )
+  {
+    super(
+      context.getFile(),
+      new PdfDictionary(
+        new PdfName[]
+        { PdfName.Names },
+        new PdfDirectObject[]
+        { new PdfArray() }
+        )
+      ); // NOTE: Initial root is by-definition a leaf node.
+  }
+
+  public NameTree(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {
+    super(
+      baseObject,
+      container
+      );
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  public NameTree<T> clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  // <Map>
+  public void clear(
+    )
+  {clear(getBaseDataObject());}
+
+  public boolean containsKey(
+    Object key
+    )
+  {
+    /*
+      NOTE: Here we assume that any named entry has a non-null value.
+    */
+    return get(key) != null;
+  }
+
+  public boolean containsValue(
+    Object value
+    )
+  {throw new NotImplementedException();}
+
+  public Set<Map.Entry<PdfString,T>> entrySet(
+    )
+  {
+    IFiller<Set<Map.Entry<PdfString,T>>> filler = new IFiller<Set<Map.Entry<PdfString,T>>>()
+      {
+        private Set<Map.Entry<PdfString,T>> entrySet = new HashSet<Map.Entry<PdfString,T>>();
+        public void add(
+          PdfArray names,
+          int offset,
+          PdfIndirectObject container
+          )
+        {
+          PdfString key = (PdfString)names.get(offset);
+          T value = wrap(
+            names.get(offset + 1),
+            container,
+            key
+            );
+          entrySet.add(
+            new Entry(key,value)
+            );
+        }
+        public Set<Map.Entry<PdfString,T>> getCollection(
+          )
+        {return entrySet;}
+      };
+    fill(
+      filler,
+      (PdfReference)getBaseObject()
+      );
+
+    return filler.getCollection();
+  }
+
+  public boolean equals(
+    Object object
+    )
+  {throw new NotImplementedException();}
+
+  public T get(
+    Object key
+    )
+  {
+    PdfString keyString = (PdfString)key;
+    PdfDirectObject containerObject = getBaseObject();
+    PdfDictionary parent = getBaseDataObject();
+    while(true)
+    {
+      PdfDirectObject namesObject = parent.get(PdfName.Names);
+      if(namesObject == null) // Intermediate node.
+      {
+        PdfArray kids = (PdfArray)parent.resolve(PdfName.Kids);
+        int low = 0, high = kids.size() - 1;
+        while(true)
+        {
+          if(low > high)
+            return null;
+
+          int mid = (low + high) / 2;
+          PdfDirectObject kidObject = kids.get(mid);
+          PdfDictionary kid = (PdfDictionary)File.resolve(kidObject);
+          PdfArray limits = (PdfArray)kid.resolve(PdfName.Limits);
+          // Compare to the lower limit!
+          int comparison = keyString.compareTo(
+            (PdfString)limits.get(0)
+            );
+          if(comparison < 0)
+          {high = mid - 1;}
+          else
+          {
+            // Compare to the upper limit!
+            comparison = keyString.compareTo(
+              (PdfString)limits.get(1)
+              );
+            if(comparison > 0)
+            {low = mid + 1;}
+            else
+            {
+              // Go down one level!
+              containerObject = kidObject; // NOTE: Node children MUST be indirectly referenced.
+              parent = kid;
+              break;
+            }
+          }
+        }
+      }
+      else // Leaf node.
+      {
+        if(namesObject instanceof PdfReference)
+        {containerObject = namesObject;}
+
+        PdfArray names = (PdfArray)File.resolve(namesObject);
+        int low = 0, high = names.size();
+        while(true)
+        {
+          if(low > high)
+            return null;
+
+          int mid = (mid = ((low + high) / 2)) - (mid % 2);
+          int comparison = keyString.compareTo(
+            (PdfString)names.get(mid)
+            );
+          if(comparison < 0)
+          {high = mid - 2;}
+          else if(comparison > 0)
+          {low = mid + 2;}
+          else
+          {
+            // We got it!
+            return wrap(
+              names.get(mid + 1),
+              ((PdfReference)containerObject).getIndirectObject(),
+              (PdfString)names.get(mid)
+              );
+          }
+        }
+      }
+    }
+  }
+
+  public int hashCode(
+    )
+  {throw new NotImplementedException();}
+
+  public boolean isEmpty(
+    )
+  {
+    PdfDictionary rootNode = getBaseDataObject();
+    PdfArray children = (PdfArray)rootNode.resolve(PdfName.Names);
+    if(children == null) // Intermediate node.
+    {children = (PdfArray)rootNode.resolve(PdfName.Kids);}
+
+    return children == null
+      || children.size() == 0;
+  }
+
+  public Set<PdfString> keySet(
+    )
+  {
+    IFiller<Set<PdfString>> filler = new IFiller<Set<PdfString>>()
+      {
+        private Set<PdfString> keySet = new HashSet<PdfString>();
+        public void add(
+          PdfArray names,
+          int offset,
+          PdfIndirectObject container
+          )
+        {
+          keySet.add(
+            (PdfString)names.get(offset)
+            );
+        }
+        public Set<PdfString> getCollection(
+          )
+        {return keySet;}
+      };
+    fill(
+      filler,
+      (PdfReference)getBaseObject()
+      );
+
+    return filler.getCollection();
+  }
+
+  public T put(
+    PdfString key,
+    T value
+    )
+  {
+    // Get the root node!
+    PdfReference rootReference = (PdfReference)getBaseObject(); // NOTE: Nodes MUST be indirect objects.
+    PdfDictionary root = (PdfDictionary)rootReference.getDataObject();
+
+    // Ensuring the root node isn't full...
+    {
+      Children rootChildren = getChildren(root);
+      if(rootChildren.items.size() >= rootChildren.order) // Root node full.
+      {
+        // Insert the old root under the new one!
+        PdfDataObject oldRootDataObject = rootReference.getDataObject();
+        rootReference.setDataObject(
+          root = new PdfDictionary(
+            new PdfName[]
+            { PdfName.Kids },
+            new PdfDirectObject[]
+            {
+              new PdfArray(
+                new PdfDirectObject[]{getFile().register(oldRootDataObject)}
+                )
+            }
+            )
+          );
+        // Split the old root!
+        splitFullNode(
+          (PdfArray)root.get(PdfName.Kids),
+          0, // Old root's position within new root's kids.
+          rootChildren.typeName
+          );
+      }
+    }
+
+    // Set the entry under the root node!
+    return put(
+      key,
+      value,
+      rootReference
+      );
+  }
+
+  public void putAll(
+    Map<? extends PdfString,? extends T> entries
+    )
+  {
+    for(Map.Entry<? extends PdfString,? extends T> entry : entries.entrySet())
+    {put(entry.getKey(),entry.getValue());}
+  }
+
+  public T remove(
+    Object key
+    )
+  {throw new NotImplementedException();}
+
+  public int size(
+    )
+  {return getSize(getBaseDataObject());}
+
+  public Collection<T> values(
+    )
+  {
+    IFiller<Collection<T>> filler = new IFiller<Collection<T>>()
+      {
+        private Collection<T> values = new ArrayList<T>();
+        public void add(
+          PdfArray names,
+          int offset,
+          PdfIndirectObject container
+          )
+        {
+          values.add(
+            wrap(
+              names.get(offset + 1),
+              container,
+              (PdfString)names.get(offset)
+              )
+            );
+        }
+        public Collection<T> getCollection(
+          )
+        {return values;}
+      };
+    fill(
+      filler,
+      (PdfReference)getBaseObject()
+      );
+
+    return filler.getCollection();
+  }
+  // </Map>
+  // </public>
+
+  // <protected>
+  /**
+    Wraps a base object within its corresponding high-level representation.
+  */
+  protected abstract T wrap(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container,
+    PdfString name
+    );
+  // </protected>
+
+  // <private>
+  /**
+    Removes all the given node's children.
+    <h3>Remarks</h3>
+    <p>Removal affects only tree nodes: referenced objects are preserved
+    to avoid inadvertently breaking possible references to them from somewhere else.</p>
+
+    @param node Current node.
+  */
+  private void clear(
+    PdfDictionary node
+    )
+  {
+    Children children = getChildren(node);
+    if(children.typeName.equals(PdfName.Kids))
+    {
+      for(PdfDirectObject child : children.items)
+      {
+        clear((PdfDictionary)File.resolve(child));
+        getFile().unregister((PdfReference)child);
+      }
+      node.put(PdfName.Names, node.get(children.typeName));
+      node.remove(children.typeName);
+    }
+    children.items.clear();
+    node.remove(PdfName.Limits);
+  }
+
+  private <TCollection extends Collection<?>> void fill(
+    IFiller<TCollection> filler,
+    PdfReference nodeReference
+    )
+  {
+    PdfDictionary node = (PdfDictionary)nodeReference.getDataObject();
+    File.ResolvedObject<PdfArray> kidsObject = File.resolve(
+      node.get(PdfName.Kids),
+      nodeReference
+      );
+    if(kidsObject == null) // Leaf node.
+    {
+      File.ResolvedObject<PdfArray> namesObject = File.resolve(
+        node.get(PdfName.Names),
+        nodeReference
+        );
+      for(
+        int index = 0,
+          length = namesObject.dataObject.size();
+        index < length;
+        index += 2
+        )
+      {
+        filler.add(
+          namesObject.dataObject,
+          index,
+          namesObject.container
+          );
+      }
+    }
+    else // Intermediate node.
+    {
+      for(PdfDirectObject kidObject : kidsObject.dataObject)
+      {fill(filler,(PdfReference)kidObject);}
+    }
+  }
+
+  /**
+    Gets the given node's children.
+
+    @param node Parent node.
+  */
+  private Children getChildren(
+    PdfDictionary node
+    )
+  {
+    PdfArray children = null;
+    PdfName childrenTypeName = null;
+    int childrenOrder = 0;
+    for(
+      int index = 0,
+        length = ChildrenTypeNames.length;
+      index < length;
+      index++
+      )
+    {
+      childrenTypeName = ChildrenTypeNames[index];
+      children = (PdfArray)node.resolve(childrenTypeName);
+      if(children == null)
+        continue;
+
+      childrenOrder = ChildrenOrders[index];
+      break;
+    }
+    return new Children(children, childrenTypeName, childrenOrder);
+  }
+
+  /**
+    Gets the given node's entries count.
+
+    @param node Current node.
+  */
+  private int getSize(
+    PdfDictionary node
+    )
+  {
+    PdfArray children = (PdfArray)node.resolve(PdfName.Names);
+    if(children == null) // Intermediate node.
+    {
+      children = (PdfArray)node.resolve(PdfName.Kids);
+
+      int size = 0;
+      for(PdfDirectObject child : children)
+      {size += getSize((PdfDictionary)File.resolve(child));}
+
+      return size;
+    }
+    else // Leaf node.
+    {return (children.size() / 2);}
+  }
+
+  /**
+    Puts an entry under the given tree node.
+
+    @param key New entry's key.
+    @param value New entry's value.
+    @param node Current node.
+  */
+  private T put(
+    PdfString key,
+    T value,
+    PdfReference nodeReference
+    )
+  {
+    PdfDictionary node = (PdfDictionary)nodeReference.getDataObject();
+    T oldValue;
+    PdfArray children = (PdfArray)node.resolve(PdfName.Names);
+    if(children == null) // Intermediate node.
+    {
+      children = (PdfArray)node.resolve(PdfName.Kids);
+      int low = 0, high = children.size() - 1;
+      while(true)
+      {
+        boolean matched = false;
+        int mid = (low + high) / 2;
+        PdfReference kidReference = (PdfReference)children.get(mid);
+        PdfDictionary kid = (PdfDictionary)kidReference.getDataObject();
+        PdfArray limits = (PdfArray)kid.resolve(PdfName.Limits);
+        if(key.compareTo((PdfString)limits.get(0)) < 0) // Before the lower limit.
+        {high = mid - 1;}
+        else if(key.compareTo((PdfString)limits.get(1)) > 0) // After the upper limit.
+        {low = mid + 1;}
+        else // Limit range matched.
+        {matched = true;}
+
+        if(matched // Limit range matched.
+          || low > high) // No limit range match.
+        {
+          Children kidChildren = getChildren(kid);
+          if(kidChildren.items.size() >= kidChildren.order) // Current node is full.
+          {
+            // Split the node!
+            splitFullNode(
+              children,
+              mid,
+              kidChildren.typeName
+              );
+            // Is the key before the splitted node?
+            if(key.compareTo(((PdfArray)kid.resolve(PdfName.Limits)).get(0)) < 0)
+            {
+              kidReference = (PdfReference)children.get(mid);
+              kid = (PdfDictionary)kidReference.getDataObject();
+            }
+          }
+
+          oldValue = put(
+            key,
+            value,
+            kidReference
+            );
+          // Update the key limits!
+          updateNodeLimits(
+            node,
+            children,
+            PdfName.Kids
+            );
+          break;
+        }
+      }
+    }
+    else // Leaf node.
+    {
+      int childrenSize = children.size();
+      int low = 0, high = childrenSize;
+      while(true)
+      {
+        int mid = (mid = ((low + high) / 2)) - (mid % 2);
+        if(mid >= childrenSize)
+        {
+          oldValue = null;
+          // Append the entry!
+          children.add(key);
+          children.add(value.getBaseObject());
+          break;
+        }
+
+        int comparison = key.compareTo(
+          (PdfString)children.get(mid)
+          );
+        if(comparison < 0) // Before.
+        {high = mid - 2;}
+        else if(comparison > 0) // After.
+        {low = mid + 2;}
+        else // Matching entry.
+        {
+          oldValue = wrap(
+            children.get(mid + 1),
+            nodeReference.getIndirectObject(),
+            (PdfString)children.get(mid)
+            );
+          // Overwrite the entry!
+          children.set(mid, key);
+          children.set(++mid, value.getBaseObject());
+          break;
+        }
+        if(low > high)
+        {
+          oldValue = null;
+          // Insert the entry!
+          children.add(low, key);
+          children.add(++low, value.getBaseObject());
+          break;
+        }
+      }
+
+      // Update the key limits!
+      updateNodeLimits(
+        node,
+        children,
+        PdfName.Names
+        );
+    }
+    return oldValue;
+  }
+
+  /**
+    Splits a full node.
+    <h3>Remarks</h3>
+    <p>A new node is inserted at the full node's position, receiving the lower half of its children.</p>
+
+    @param nodes Parent nodes.
+    @param fullNodeIndex Full node's position among the parent nodes.
+    @param childrenTypeName Full node's children type.
+  */
+  private void splitFullNode(
+    PdfArray nodes,
+    int fullNodeIndex,
+    PdfName childrenTypeName
+    )
+  {
+    // Get the full node!
+    PdfDictionary fullNode = (PdfDictionary)nodes.resolve(fullNodeIndex);
+    PdfArray fullNodeChildren = (PdfArray)fullNode.resolve(childrenTypeName);
+
+    // Create a new (sibling) node!
+    PdfDictionary newNode = new PdfDictionary();
+    PdfArray newNodeChildren = new PdfArray();
+    newNode.put(childrenTypeName, newNodeChildren);
+    // Insert the new node just before the full!
+    nodes.add(fullNodeIndex,getFile().register(newNode)); // NOTE: Nodes MUST be indirect objects.
+
+    // Transferring exceeding children to the new node...
+    {
+      int index = 0;
+      int length;
+      if(childrenTypeName.equals(PdfName.Kids))
+      {length = NodeMinSize;}
+      else if(childrenTypeName.equals(PdfName.Names))
+      {length = NameNodeMinSize;}
+      else // NOTE: Should NEVER happen.
+      {throw new UnsupportedOperationException(childrenTypeName + " is NOT a supported child type.");}
+      while(index++ < length)
+      {
+        newNodeChildren.add(fullNodeChildren.get(0));
+        fullNodeChildren.remove(0);
+      }
+    }
+
+    // Update the key limits!
+    updateNodeLimits(
+      newNode,
+      newNodeChildren,
+      childrenTypeName
+      );
+    updateNodeLimits(
+      fullNode,
+      fullNodeChildren,
+      childrenTypeName
+      );
+  }
+
+  /**
+    Sets the key limits of the given node.
+
+    @param node Node to update.
+    @param children Node children.
+    @param childrenTypeName Node's children type.
+  */
+  private void updateNodeLimits(
+    PdfDictionary node,
+    PdfArray children,
+    PdfName childrenTypeName
+    )
+  {
+    if(childrenTypeName.equals(PdfName.Kids))
+    {
+      node.put(
+        PdfName.Limits,
+        new PdfArray(
+          new PdfDirectObject[]
+          {
+            ((PdfArray)((PdfDictionary)children.resolve(0)).resolve(PdfName.Limits)).get(0),
+            ((PdfArray)((PdfDictionary)children.resolve(children.size()-1)).resolve(PdfName.Limits)).get(1)
+          }
+          )
+        );
+    }
+    else if(childrenTypeName.equals(PdfName.Names))
+    {
+      node.put (
+        PdfName.Limits,
+        new PdfArray(
+          new PdfDirectObject[]
+          {
+            children.get(0),
+            children.get(children.size()-2)
+          }
+          )
+        );
+    }
+    else // NOTE: Should NEVER happen.
+    {throw new UnsupportedOperationException(childrenTypeName + " is NOT a supported child type.");}
+  }
+  // </private>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfArray.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfArray.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfArray.java	(revision 23703)
@@ -0,0 +1,277 @@
+/*
+  Copyright 2006-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.objects;
+
+import it.stefanochizzolini.clown.bytes.IOutputStream;
+import it.stefanochizzolini.clown.files.File;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+
+/**
+  PDF array object [PDF:1.6:3.2.5].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.0
+  @version 0.0.8
+*/
+public class PdfArray
+  extends PdfDirectObject
+  implements List<PdfDirectObject>
+{
+  // <class>
+  // <dynamic>
+  // <fields>
+  private ArrayList<PdfDirectObject> items;
+  // </fields>
+
+  // <constructors>
+  public PdfArray(
+    )
+  {items = new ArrayList<PdfDirectObject>();}
+
+  public PdfArray(
+    int capacity
+    )
+  {items = new ArrayList<PdfDirectObject>(capacity);}
+
+  public PdfArray(
+    PdfDirectObject... items
+    )
+  {
+    this(items.length);
+    for(PdfDirectObject item : items)
+    {this.items.add(item);}
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public Object clone(
+    File context
+    )
+  {
+    //TODO:IMPL redefine to support real cloning (current implementation is prone to object slicing hazard)!!!
+    PdfArray clone = new PdfArray(items.size());
+
+    for(PdfDirectObject item : items)
+    {clone.add((PdfDirectObject)item.clone(context));}
+
+    return clone;
+  }
+
+  @Override
+  public int compareTo(
+    PdfDirectObject obj
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    Gets the dereferenced value corresponding to the given index.
+    <h3>Remarks</h3>
+    <p>This method takes care to resolve the value returned by {@link #get(int)}.</p>
+
+    @param index Index of element to return.
+
+    @since 0.0.8
+   */
+  public PdfDataObject resolve(
+    int index
+    )
+  {return File.resolve(get(index));}
+
+  @Override
+  public String toString(
+    )
+  {
+    StringBuilder buffer = new StringBuilder();
+
+    // Begin.
+    buffer.append("[ ");
+
+    // Elements.
+    for(PdfDirectObject item : items)
+    {buffer.append(PdfDirectObject.toString(item)); buffer.append(" ");}
+
+    // End.
+    buffer.append("]");
+
+    return buffer.toString();
+  }
+
+  @Override
+  public void writeTo(
+    IOutputStream stream
+    )
+  {
+    // Begin.
+    stream.write("[ ");
+
+    // Items.
+    for(PdfDirectObject item : items)
+    {PdfDirectObject.writeTo(stream,item); stream.write(" ");}
+
+    // End.
+    stream.write("]");
+  }
+
+  // <List>
+  public void add(
+    int index,
+    PdfDirectObject object
+    )
+  {items.add(index,object);}
+
+  public boolean addAll(
+    int index,
+    Collection<? extends PdfDirectObject> objects
+    )
+  {return items.addAll(index,objects);}
+
+  public PdfDirectObject get(
+    int index
+    )
+  {return items.get(index);}
+
+  public int indexOf(
+    Object object
+    )
+  {return items.indexOf(object);}
+
+  public int lastIndexOf(
+    Object object
+    )
+  {return items.lastIndexOf(object);}
+
+  public ListIterator<PdfDirectObject> listIterator(
+    )
+  {return items.listIterator();}
+
+  public ListIterator<PdfDirectObject> listIterator(
+    int index
+    )
+  {return items.listIterator(index);}
+
+  public PdfDirectObject remove(
+    int index
+    )
+  {return items.remove(index);}
+
+  public PdfDirectObject set(
+    int index,
+    PdfDirectObject object
+    )
+  {return items.set(index,object);}
+
+  public List<PdfDirectObject> subList(
+    int fromIndex,
+    int toIndex
+    )
+  {return items.subList(fromIndex,toIndex);}
+
+  // <Collection>
+  public boolean add(
+    PdfDirectObject object
+    )
+  {return items.add(object);}
+
+  public boolean addAll(
+    Collection<? extends PdfDirectObject> objects
+    )
+  {return items.addAll(objects);}
+
+  public void clear(
+    )
+  {items.clear();}
+
+  public boolean contains(
+    Object object
+    )
+  {return items.contains(object);}
+
+  public boolean containsAll(
+    Collection<?> objects
+    )
+  {return items.containsAll(objects);}
+
+  public boolean equals(
+    PdfDirectObject object
+    )
+  {throw new NotImplementedException();}
+
+  public int hashCode(
+    )
+  {return items.hashCode();}
+
+  public boolean isEmpty(
+    )
+  {return items.isEmpty();}
+
+  public boolean remove(
+    Object object
+    )
+  {return items.remove(object);}
+
+  public boolean removeAll(
+    Collection<?> objects
+    )
+  {return items.removeAll(objects);}
+
+  public boolean retainAll(
+    Collection<?> objects
+    )
+  {return items.retainAll(objects);}
+
+  public int size(
+    )
+  {return items.size();}
+
+  public PdfDirectObject[] toArray(
+    )
+  {return (PdfDirectObject[])items.toArray();}
+
+  public <T> T[] toArray(
+    T[] objects
+    )
+  {return (T[])items.toArray(objects);}
+
+  // <Iterable>
+  public Iterator<PdfDirectObject> iterator(
+    )
+  {return items.iterator();}
+  // </Iterable>
+  // </Collection>
+  // </List>
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfAtomicObject.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfAtomicObject.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfAtomicObject.java	(revision 23703)
@@ -0,0 +1,97 @@
+/*
+  Copyright 2006-2009 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.objects;
+
+/**
+  Abstract PDF atomic object.
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+*/
+public abstract class PdfAtomicObject<TValue>
+  extends PdfDirectObject
+{
+  // <class>
+  // <dynamic>
+  // <fields>
+  private TValue value;
+  // </fields>
+
+  // <constructors>
+  public PdfAtomicObject(
+    )
+  {}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  /**
+    Gets the low-level representation of the value.
+  */
+  public TValue getRawValue(
+    )
+  {return value;}
+
+  /**
+    Gets the high-level representation of the value.
+  */
+  public Object getValue(
+    )
+  {return value;}
+
+  /**
+    Sets the low-level representation of the value.
+  */
+  public void setRawValue(
+    TValue value
+    )
+  {this.value = value;}
+
+  /**
+    Sets the high-level representation of the value.
+  */
+  @SuppressWarnings("unchecked")
+  public void setValue(
+    Object value
+    )
+  {this.value = (TValue)value;}
+
+  @Override
+  public String toString(
+    )
+  {return getValue().toString();}
+  // </public>
+
+  // <protected>
+  @Override
+  protected Object clone(
+    )
+  {return super.clone();}
+  // </protected>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfBoolean.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfBoolean.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfBoolean.java	(revision 23703)
@@ -0,0 +1,99 @@
+/*
+  Copyright 2006-2009 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.objects;
+
+import it.stefanochizzolini.clown.bytes.IOutputStream;
+import it.stefanochizzolini.clown.files.File;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+/**
+  PDF boolean object [PDF:1.6:3.2.1].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+*/
+public class PdfBoolean
+  extends PdfAtomicObject<Boolean>
+{
+  // <class>
+  // <static>
+  // <fields>
+  public static final PdfBoolean False = new PdfBoolean(false);
+  public static final PdfBoolean True = new PdfBoolean(true);
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  public PdfBoolean(
+    )
+  {}
+
+  public PdfBoolean(
+    boolean value
+    )
+  {setRawValue(value);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public Object clone(
+    File context
+    )
+  {
+    // Shallow copy.
+    PdfBoolean clone = (PdfBoolean)super.clone();
+
+    // Deep copy.
+    /* NOTE: No mutable object to be cloned. */
+
+    return clone;
+  }
+
+  @Override
+  public int compareTo(
+    PdfDirectObject obj
+    )
+  {throw new NotImplementedException();}
+
+  @Override
+  public void writeTo(
+    IOutputStream stream
+    )
+  {stream.write(toPdf(getRawValue()));}
+  // </public>
+
+  // <private>
+  private String toPdf(
+    boolean value
+    )
+  {return value ? "true" : "false";}
+  // </private>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfDataObject.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfDataObject.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfDataObject.java	(revision 23703)
@@ -0,0 +1,54 @@
+/*
+  Copyright 2006 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.objects;
+
+/**
+  PDF data object.
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+*/
+public abstract class PdfDataObject
+  extends PdfObject
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  public PdfDataObject(
+    )
+  {}
+  // </constructors>
+
+  // <interface>
+  // <protected>
+  @Override
+  protected Object clone(
+    )
+  {return super.clone();}
+  // </protected>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfDate.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfDate.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfDate.java	(revision 23703)
@@ -0,0 +1,157 @@
+/*
+  Copyright 2006-2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.objects;
+
+import it.stefanochizzolini.clown.files.File;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+  PDF date object [PDF:1.6:3.8.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.6
+*/
+public class PdfDate
+  extends PdfString
+{
+  // <class>
+  // <static>
+  // <fields>
+  protected static final SimpleDateFormat formatter;
+  // </fields>
+
+  // <constructors>
+  static
+  {formatter = new SimpleDateFormat("yyyyMMddHHmmssZ");}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  /**
+    Converts a PDF-formatted date value to a date value.
+  */
+  public static Date toDate(
+    String value
+    )
+  {
+    //TODO:IMPL this code is quite ugly... is there a more elegant solution (regex)?
+    // Normalize datetime value.
+    // Cut leading "D:" tag!
+    value = value.substring(2);
+    int length = value.length();
+    switch(length)
+    {
+      case 8: // Date only.
+        value += "000000+0000";
+        break;
+      case 14: // Datetime without timezone.
+        value += "+0000";
+        break;
+      case 15: // Datetime at UT timezone ("Z" tag).
+        value = value.substring(0,length-1) + "+0000";
+        break;
+      case 17: // Datetime at non-UT timezone without minutes.
+        value += "00";
+        break;
+      case 21: // Datetime at non-UT full timezone ("'mm'" PDF timezone-minutes format).
+        value = value.substring(0,length-1).replace("\'","");
+        break;
+    }
+
+    try
+    {return formatter.parse(value);}
+    catch(Exception e)
+    {throw new RuntimeException(e);}
+  }
+  // </public>
+  // </interface>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  public PdfDate(
+    )
+  {}
+
+  public PdfDate(
+    Date value
+    )
+  {setValue(value);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public Object clone(
+    File context
+    )
+  {
+    // Shallow copy.
+    PdfDate clone = (PdfDate)super.clone();
+
+    // Deep copy.
+    /* NOTE: No mutable object to be cloned. */
+
+    return clone;
+  }
+
+  @Override
+  public Object getValue(
+    )
+  {
+    try
+    {return toDate(new String(getRawValue(),"ISO-8859-1"));}
+    catch(Exception e)
+    {throw new RuntimeException(e); /* (should NEVER happen). */}
+  }
+
+  @Override
+  public void setValue(
+    Object value
+    )
+  {
+    byte[] valueBytes;
+    try
+    {valueBytes = formatter.format(value).getBytes("ISO-8859-1");}
+    catch(Exception e)
+    {throw new RuntimeException(e);}
+
+    byte[] buffer = new byte[23];
+    buffer[0] = 68; buffer[1] = 58;
+    System.arraycopy(valueBytes,0,buffer,2,17);
+    buffer[19] = 39;
+    System.arraycopy(valueBytes,17,buffer,20,2);
+    buffer[22] = 39;
+
+    setRawValue(buffer);
+  }
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfDictionary.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfDictionary.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfDictionary.java	(revision 23703)
@@ -0,0 +1,283 @@
+/*
+  Copyright 2006-2009 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.objects;
+
+import it.stefanochizzolini.clown.bytes.IOutputStream;
+import it.stefanochizzolini.clown.files.File;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+  PDF dictionary object [PDF:1.6:3.2.6].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+  @since 0.0.0
+*/
+public class PdfDictionary
+  extends PdfDirectObject
+  implements Map<PdfName,PdfDirectObject>
+{
+  // <class>
+  // <dynamic>
+  // <fields>
+  private HashMap<PdfName,PdfDirectObject> entries;
+  // </fields>
+
+  // <constructors>
+  public PdfDictionary(
+    )
+  {entries = new HashMap<PdfName,PdfDirectObject>();}
+
+  public PdfDictionary(
+    int capacity
+    )
+  {entries = new HashMap<PdfName,PdfDirectObject>(capacity);}
+
+  public PdfDictionary(
+    PdfName[] keys,
+    PdfDirectObject[] values
+    )
+  {
+    this(values.length);
+
+    for(
+      int index = 0;
+      index < values.length;
+      index++
+      )
+    {
+      put(
+        keys[index],
+        values[index]
+        );
+    }
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public Object clone(
+    File context
+    )
+  {
+    //TODO:IMPL redefine to support real cloning (current implementation is prone to object slicing hazard)!!!
+    PdfDictionary clone = new PdfDictionary(entries.size());
+
+    for(
+      Map.Entry<PdfName,PdfDirectObject> entry : entries.entrySet()
+      )
+    {
+      clone.put(
+        entry.getKey(),
+        (PdfDirectObject)entry.getValue().clone(context)
+        );
+    }
+
+    return clone;
+  }
+
+  @Override
+  public int compareTo(
+    PdfDirectObject obj
+    )
+  {throw new NotImplementedException();}
+
+  /**
+    Gets the key associated to a given value.
+  */
+  public PdfName getKey(
+    PdfDirectObject value
+    )
+  {
+    /*
+      NOTE: Current PdfDictionary implementation doesn't support bidirectional
+      maps, to say that the only currently-available way to retrieve a key from a
+      value is to iterate the whole map (really poor performance!).
+      NOTE: Complex high-level matches are not verified (too expensive!), to say that
+      if the searched high-level object (font, xobject, colorspace etc.) has a
+      PdfReference base object while some high-level objects in the
+      collection have other direct type (PdfName, for example) base objects, they
+      won't match in any case (even if they represent the SAME high-level object --
+      but that should be a rare case...).
+    */
+    for(
+      Map.Entry<PdfName,PdfDirectObject> entry : entries.entrySet()
+      )
+    {
+      if(entry.getValue().equals(value))
+        return entry.getKey(); // Found.
+    }
+
+    return null; // Not found.
+  }
+
+  /**
+    Gets the dereferenced value corresponding to the given key.
+    <h3>Remarks</h3>
+    <p>This method takes care to resolve the value returned by {@link #get(Object)}.</p>
+
+    @param key Key whose associated value is to be returned.
+    @return null, if the map contains no mapping for this key.
+
+    @since 0.0.8
+   */
+  public PdfDataObject resolve(
+    Object key
+    )
+  {return File.resolve(get(key));}
+
+  @Override
+  public String toString(
+    )
+  {
+    StringBuilder buffer = new StringBuilder();
+
+    // Begin.
+    buffer.append("<< ");
+
+    // Entries.
+    for(
+      Map.Entry<PdfName,PdfDirectObject> entry : entries.entrySet()
+      )
+    {
+      // Entry...
+      // ...key.
+      buffer.append(entry.getKey().toString()); buffer.append(" ");
+
+      // ...value.
+      buffer.append(PdfDirectObject.toString(entry.getValue())); buffer.append(" ");
+    }
+
+    // End.
+    buffer.append(">>");
+
+    return buffer.toString();
+  }
+
+  @Override
+  public void writeTo(
+    IOutputStream stream
+    )
+  {
+    // Begin.
+    stream.write("<< ");
+
+    // Entries.
+    for(
+      Map.Entry<PdfName,PdfDirectObject> entry : entries.entrySet()
+      )
+    {
+      // Entry...
+      // ...key.
+      entry.getKey().writeTo(stream); stream.write(" ");
+
+      // ...value.
+      PdfDirectObject.writeTo(stream,entry.getValue()); stream.write(" ");
+    }
+
+    // End.
+    stream.write(">>");
+  }
+
+  // <Map>
+  public void clear(
+    )
+  {entries.clear();}
+
+  public boolean containsKey(
+    Object key
+    )
+  {return entries.containsKey(key);}
+
+  public boolean containsValue(
+    Object value
+    )
+  {return entries.containsValue(value);}
+
+  public Set<Map.Entry<PdfName,PdfDirectObject>> entrySet(
+    )
+  {return entries.entrySet();}
+
+  public boolean equals(
+    Object object
+    )
+  {
+    return (object instanceof PdfDictionary
+      && this.entrySet().equals(((PdfDictionary)object).entrySet()));
+  }
+
+  public PdfDirectObject get(
+    Object key
+    )
+  {return entries.get(key);}
+
+  public int hashCode(
+    )
+  {return entries.hashCode();}
+
+  public boolean isEmpty(
+    )
+  {return entries.isEmpty();}
+
+  public Set<PdfName> keySet(
+    )
+  {return entries.keySet();}
+
+  public PdfDirectObject put(
+    PdfName key,
+    PdfDirectObject value
+    )
+  {return entries.put(key,value);}
+
+  public void putAll(
+    Map<? extends PdfName,? extends PdfDirectObject> entries
+    )
+  {this.entries.putAll(entries);}
+
+  public PdfDirectObject remove(
+    Object key
+    )
+  {return entries.remove(key);}
+
+  public int size(
+    )
+  {return entries.size();}
+
+  public Collection<PdfDirectObject> values(
+    )
+  {return entries.values();}
+  // </Map>
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfDirectObject.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfDirectObject.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfDirectObject.java	(revision 23703)
@@ -0,0 +1,99 @@
+/*
+  Copyright 2006-2009 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.objects;
+
+import it.stefanochizzolini.clown.bytes.IOutputStream;
+
+/**
+  Abstract PDF direct object.
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+*/
+public abstract class PdfDirectObject
+  extends PdfDataObject
+  implements Comparable<PdfDirectObject>
+{
+  // <class>
+  // <static>
+  // <interface>
+  // <internal>
+  /**
+    Ensures that the given direct object is properly represented as string.
+    <p>This method is useful to force null pointers to be expressed as PDF null objects.</p>
+  */
+  static String toString(
+    PdfDirectObject object
+    )
+  {
+    if(object == null)
+      return "null";
+    else
+      return object.toString();
+  }
+
+  /**
+    Ensures that the given direct object is properly serialized.
+    <p>This method is useful to force null pointers to be expressed as PDF null objects.</p>
+  */
+  static void writeTo(
+    IOutputStream stream,
+    PdfDirectObject object
+    )
+  {
+    if(object == null)
+    {stream.write("null");}
+    else
+    {object.writeTo(stream);}
+  }
+  // </internal>
+  // </interface>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  public PdfDirectObject(
+    )
+  {}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  // <Comparable>
+  public abstract int compareTo(PdfDirectObject obj);
+  // </Comparable>
+  // </public>
+
+  // <protected>
+  @Override
+  protected Object clone(
+    )
+  {return super.clone();}
+  // </protected>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfIndirectObject.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfIndirectObject.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfIndirectObject.java	(revision 23703)
@@ -0,0 +1,259 @@
+/*
+  Copyright 2006-2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.objects;
+
+import it.stefanochizzolini.clown.bytes.IOutputStream;
+import it.stefanochizzolini.clown.files.File;
+import it.stefanochizzolini.clown.tokens.Parser;
+import it.stefanochizzolini.clown.tokens.XRefEntry;
+
+/**
+  PDF indirect object [PDF:1.6:3.2.9].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.7
+*/
+public class PdfIndirectObject
+  extends PdfObject
+  implements IPdfIndirectObject
+{
+  // <class>
+  // <static>
+  // <fields>
+  private static final String UsageFree = "f";
+  private static final String UsageInUse = "n";
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <fields>
+  private PdfDataObject dataObject;
+  private File file;
+  private boolean original;
+  private PdfReference reference;
+  private XRefEntry xrefEntry;
+  // </fields>
+
+  // <constructors>
+  /**
+    For internal use only.
+
+    @param file Associated file.
+    @param dataObject Data object associated to the indirect object.
+      It MUST be null if the indirect object is original (i.e. coming from an existing file) or
+      free.
+      It MUST be NOT null if the indirect object is new and in-use.
+    @param xrefEntry Cross-reference entry associated to the indirect object.
+      If the indirect object is new, its offset field MUST be set to 0 (zero).
+  */
+  public PdfIndirectObject(
+    File file,
+    PdfDataObject dataObject,
+    XRefEntry xrefEntry
+    )
+  {
+    this.file = file;
+    this.dataObject = dataObject;
+    this.xrefEntry = xrefEntry;
+
+    this.original = (xrefEntry.getOffset() != 0);
+    this.reference = new PdfReference(
+      this,
+      xrefEntry.getNumber(),
+      xrefEntry.getGeneration()
+      );
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  public File getFile(
+    )
+  {return file;}
+
+  @Override
+  public int hashCode(
+    )
+  {
+    /*
+      NOTE: Uniqueness should be achieved XORring the (local) reference hashcode
+      with the (global) file hashcode.
+      NOTE: DO NOT directly invoke reference.hashCode() method here as
+      it would trigger an infinite loop, as it conversely relies on this method.
+    */
+    return reference.getID().hashCode() ^ file.hashCode();
+  }
+
+  public boolean isInUse(
+    )
+  {return (xrefEntry.getUsage() == XRefEntry.UsageEnum.InUse);}
+
+  public boolean isOriginal(
+    )
+  {return original;}
+
+  public void update(
+    )
+  {
+    if(original)
+    {
+      /*
+        NOTE: It's expected that dropOriginal() is invoked by IndirectObjects set() method;
+        such an action is delegated because clients may invoke directly set() method, skipping
+        this method.
+      */
+      file.getIndirectObjects().update(this);
+    }
+  }
+
+  @Override
+  public void writeTo(
+    IOutputStream stream
+    )
+  {
+    // Header.
+    stream.write(reference.getID() + " obj\n");
+
+    // Body.
+    getDataObject().writeTo(stream);
+
+    // Tail.
+    stream.write("\nendobj\n");
+  }
+
+  // <IPdfIndirectObject>
+  @Override
+  public Object clone(
+    File context
+    )
+  {return context.getIndirectObjects().addExternal(this);}
+
+  public void delete(
+    )
+  {
+    if(file != null)
+    {
+      /*
+        NOTE: It's expected that dropFile() is invoked by IndirectObjects remove() method;
+        such an action is delegated because clients may invoke directly remove() method,
+        skipping this method.
+      */
+      file.getIndirectObjects().remove(xrefEntry.getNumber());
+    }
+  }
+
+  public PdfDataObject getDataObject(
+    )
+  {
+    if(dataObject == null)
+    {
+      /*
+        NOTE: indirect data object is null in 2 cases:
+        1) when the entry is free (no data object at all);
+        2) when the indirect object hasn't been initialized yet
+          because it comes from a parsed reference (late-bound data object).
+        In case 1 data object MUST keep itself null,
+        while in case 2 data object MUST be initialized.
+      */
+
+      // Is the entry free [case 1]?
+      // NOTE: Free entries have NO indirect data object associated with.
+      if(xrefEntry.getUsage() == XRefEntry.UsageEnum.Free)
+        return null;
+
+      // In-use entry (late-bound data object [case 2]).
+      try
+      {
+        Parser parser = file.getReader().getParser();
+        // Retrieve the associated data object among the original objects!
+        parser.seek(xrefEntry.getOffset());
+        // Skip indirect-object header!
+        parser.moveNext(4);
+        // Get the indirect data object!
+        dataObject = parser.parsePdfObject();
+      }
+      catch(Exception e)
+      {throw new RuntimeException(e);}
+    }
+
+    return dataObject;
+  }
+
+  public PdfIndirectObject getIndirectObject(
+    )
+  {return this;}
+
+  public PdfReference getReference(
+    )
+  {return reference;}
+
+  public void setDataObject(
+    PdfDataObject value
+    )
+  {
+    if(xrefEntry.getGeneration() == XRefEntry.GenerationUnreusable)
+      throw new RuntimeException("Unreusable entry.");
+
+    dataObject = value;
+    xrefEntry.setUsage(XRefEntry.UsageEnum.InUse);
+    update();
+  }
+  // </IPdfIndirectObject>
+  // </public>
+
+  // <internal>
+  /**
+    For internal use only.
+  */
+  public void dropFile(
+    )
+  {file = null;}
+
+  /**
+    For internal use only.
+  */
+  public void dropOriginal(
+    )
+  {original = false;}
+
+  String getUsage(
+    )
+  {
+    switch(xrefEntry.getUsage())
+    {
+      case Free:
+        return UsageFree;
+      case InUse:
+        return UsageInUse;
+      default: // Should NEVER happen.
+        throw new RuntimeException("Invalid xref usage value.");
+    }
+  }
+  // </internal>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfInteger.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfInteger.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfInteger.java	(revision 23703)
@@ -0,0 +1,104 @@
+/*
+  Copyright 2006-2009 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.objects;
+
+import it.stefanochizzolini.clown.bytes.IOutputStream;
+import it.stefanochizzolini.clown.files.File;
+
+/**
+  PDF integer number object [PDF:1.6:3.2.2].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+*/
+public class PdfInteger
+  extends PdfAtomicObject<Integer>
+  implements IPdfNumber
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  public PdfInteger(
+    int value
+    )
+  {setRawValue(value);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public Object clone(
+    File context
+    )
+  {
+    // Shallow copy.
+    PdfInteger clone = (PdfInteger)super.clone();
+
+    // Deep copy.
+    /* NOTE: No mutable object to be cloned. */
+
+    return clone;
+  }
+
+  @Override
+  public int compareTo(
+    PdfDirectObject obj
+    )
+  {return PdfNumber.compare(this,obj);}
+
+  @Override
+  public void writeTo(
+    IOutputStream stream
+    )
+  {stream.write(toPdf(getRawValue()));}
+
+  // <IPdfNumber>
+  public double getNumberValue(
+    )
+  {return getRawValue();}
+
+  public void setNumberValue(
+    double value
+    )
+  {setRawValue((int)value);}
+
+  public void translateNumberValue(
+    double value
+    )
+  {setRawValue(getRawValue() + (int)value);}
+  // </IPdfNumber>
+  // </public>
+
+  // <private>
+  private String toPdf(
+    int value
+    )
+  {return Integer.toString(value);}
+  // </private>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfName.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfName.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfName.java	(revision 23703)
@@ -0,0 +1,554 @@
+/*
+  Copyright 2006-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.objects;
+
+import it.stefanochizzolini.clown.bytes.IOutputStream;
+import it.stefanochizzolini.clown.files.File;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+  PDF name object [PDF:1.6:3.2.4].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+*/
+public final class PdfName
+  extends PdfAtomicObject<String>
+{
+  /*
+    NOTE: As name objects are atomic symbols uniquely defined by sequences of characters,
+    the bytes making up the name are never treated as text, always keeping them escaped.
+  */
+  // <class>
+  // <static>
+  // <fields>
+  /*
+    NOTE: Name lexical conventions prescribe that the following reserved characters
+    are to be escaped when placed inside names' character sequences:
+      - delimiters;
+      - whitespaces;
+      - '#' (number sign character).
+  */
+  private static final Pattern EscapedPattern = Pattern.compile("#([\\da-fA-F]{2})");
+  private static final Pattern UnescapedPattern = Pattern.compile("[\\s\\(\\)<>\\[\\]{}/%#]");
+
+  public static final PdfName A = new PdfName("A");
+  public static final PdfName A85 = new PdfName("A85");
+  public static final PdfName AA = new PdfName("AA");
+  public static final PdfName AC = new PdfName("AC");
+  public static final PdfName Action = new PdfName("Action");
+  public static final PdfName AcroForm = new PdfName("AcroForm");
+  public static final PdfName AHx = new PdfName("AHx");
+  public static final PdfName Annot = new PdfName("Annot");
+  public static final PdfName Annotation = new PdfName("Annotation");
+  public static final PdfName Annots = new PdfName("Annots");
+  public static final PdfName AP = new PdfName("AP");
+  public static final PdfName Approved = new PdfName("Approved");
+  public static final PdfName AS = new PdfName("AS");
+  public static final PdfName Ascent = new PdfName("Ascent");
+  public static final PdfName ASCII85Decode = new PdfName("ASCII85Decode");
+  public static final PdfName ASCIIHexDecode = new PdfName("ASCIIHexDecode");
+  public static final PdfName AsIs = new PdfName("AsIs");
+  public static final PdfName Author = new PdfName("Author");
+  public static final PdfName B = new PdfName("B");
+  public static final PdfName BaseEncoding = new PdfName("BaseEncoding");
+  public static final PdfName BaseFont = new PdfName("BaseFont");
+  public static final PdfName BBox = new PdfName("BBox");
+  public static final PdfName BC = new PdfName("BC");
+  public static final PdfName BG = new PdfName("BG");
+  public static final PdfName BitsPerComponent = new PdfName("BitsPerComponent");
+  public static final PdfName Bl = new PdfName("Bl");
+  public static final PdfName Blinds = new PdfName("Blinds");
+  public static final PdfName Border = new PdfName("Border");
+  public static final PdfName Box = new PdfName("Box");
+  public static final PdfName BPC = new PdfName("BPC");
+  public static final PdfName BS = new PdfName("BS");
+  public static final PdfName Btn = new PdfName("Btn");
+  public static final PdfName Butt = new PdfName("Butt");
+  public static final PdfName C = new PdfName("C");
+  public static final PdfName CA = new PdfName("CA");
+  public static final PdfName CalGray = new PdfName("CalGray");
+  public static final PdfName CalRGB = new PdfName("CalRGB");
+  public static final PdfName Cap = new PdfName("Cap");
+  public static final PdfName CapHeight = new PdfName("CapHeight");
+  public static final PdfName Caret = new PdfName("Caret");
+  public static final PdfName Catalog = new PdfName("Catalog");
+  public static final PdfName CCF = new PdfName("CCF");
+  public static final PdfName CCITTFaxDecode = new PdfName("CCITTFaxDecode");
+  public static final PdfName CenterWindow = new PdfName("CenterWindow");
+  public static final PdfName Ch = new PdfName("Ch");
+  public static final PdfName CIDFontType0 = new PdfName("CIDFontType0");
+  public static final PdfName CIDFontType2 = new PdfName("CIDFontType2");
+  public static final PdfName CIDSystemInfo = new PdfName("CIDSystemInfo");
+  public static final PdfName CIDToGIDMap = new PdfName("CIDToGIDMap");
+  public static final PdfName Circle = new PdfName("Circle");
+  public static final PdfName CL = new PdfName("CL");
+  public static final PdfName ClosedArrow = new PdfName("ClosedArrow");
+  public static final PdfName CMap = new PdfName("CMap");
+  public static final PdfName CMapName = new PdfName("CMapName");
+  public static final PdfName ColorSpace = new PdfName("ColorSpace");
+  public static final PdfName Comment = new PdfName("Comment");
+  public static final PdfName Confidential = new PdfName("Confidential");
+  public static final PdfName Contents = new PdfName("Contents");
+  public static final PdfName Count = new PdfName("Count");
+  public static final PdfName Cover = new PdfName("Cover");
+  public static final PdfName CreationDate = new PdfName("CreationDate");
+  public static final PdfName Creator = new PdfName("Creator");
+  public static final PdfName Crypt = new PdfName("Crypt");
+  public static final PdfName CS = new PdfName("CS");
+  public static final PdfName D = new PdfName("D");
+  public static final PdfName DA = new PdfName("DA");
+  public static final PdfName DC = new PdfName("DC");
+  public static final PdfName DCT = new PdfName("DCT");
+  public static final PdfName DCTDecode = new PdfName("DCTDecode");
+  public static final PdfName Departmental = new PdfName("Departmental");
+  public static final PdfName Desc = new PdfName("Desc");
+  public static final PdfName DescendantFonts = new PdfName("DescendantFonts");
+  public static final PdfName Descent = new PdfName("Descent");
+  public static final PdfName Dest = new PdfName("Dest");
+  public static final PdfName Dests = new PdfName("Dests");
+  public static final PdfName DeviceCMYK = new PdfName("DeviceCMYK");
+  public static final PdfName DeviceGray = new PdfName("DeviceGray");
+  public static final PdfName DeviceRGB = new PdfName("DeviceRGB");
+  public static final PdfName Di = new PdfName("Di");
+  public static final PdfName Diamond = new PdfName("Diamond");
+  public static final PdfName Differences = new PdfName("Differences");
+  public static final PdfName Direction = new PdfName("Direction");
+  public static final PdfName DisplayDocTitle = new PdfName("DisplayDocTitle");
+  public static final PdfName Dissolve = new PdfName("Dissolve");
+  public static final PdfName Dm = new PdfName("Dm");
+  public static final PdfName DOS = new PdfName("DOS");
+  public static final PdfName DP = new PdfName("DP");
+  public static final PdfName DR = new PdfName("DR");
+  public static final PdfName Draft = new PdfName("Draft");
+  public static final PdfName DS = new PdfName("DS");
+  public static final PdfName Dur = new PdfName("Dur");
+  public static final PdfName DV = new PdfName("DV");
+  public static final PdfName E = new PdfName("E");
+  public static final PdfName EF = new PdfName("EF");
+  public static final PdfName EmbeddedFile = new PdfName("EmbeddedFile");
+  public static final PdfName EmbeddedFiles = new PdfName("EmbeddedFiles");
+  public static final PdfName Encoding = new PdfName("Encoding");
+  public static final PdfName Encrypt = new PdfName("Encrypt");
+  public static final PdfName Experimental = new PdfName("Experimental");
+  public static final PdfName Expired = new PdfName("Expired");
+  public static final PdfName ExtGState = new PdfName("ExtGState");
+  public static final PdfName F = new PdfName("F");
+  public static final PdfName Fade = new PdfName("Fade");
+  public static final PdfName FB = new PdfName("FB");
+  public static final PdfName Ff = new PdfName("Ff");
+  public static final PdfName Fields = new PdfName("Fields");
+  public static final PdfName FileAttachment = new PdfName("FileAttachment");
+  public static final PdfName Filespec = new PdfName("Filespec");
+  public static final PdfName Filter = new PdfName("Filter");
+  public static final PdfName Final = new PdfName("Final");
+  public static final PdfName First = new PdfName("First");
+  public static final PdfName FirstChar = new PdfName("FirstChar");
+  public static final PdfName FirstPage = new PdfName("FirstPage");
+  public static final PdfName Fit = new PdfName("Fit");
+  public static final PdfName FitB = new PdfName("FitB");
+  public static final PdfName FitBH = new PdfName("FitBH");
+  public static final PdfName FitBV = new PdfName("FitBV");
+  public static final PdfName FitH = new PdfName("FitH");
+  public static final PdfName FitR = new PdfName("FitR");
+  public static final PdfName FitV = new PdfName("FitV");
+  public static final PdfName FitWindow = new PdfName("FitWindow");
+  public static final PdfName Fl = new PdfName("Fl");
+  public static final PdfName Flags = new PdfName("Flags");
+  public static final PdfName FlateDecode = new PdfName("FlateDecode");
+  public static final PdfName Fly = new PdfName("Fly");
+  public static final PdfName Fo = new PdfName("Fo");
+  public static final PdfName Font = new PdfName("Font");
+  public static final PdfName FontBBox = new PdfName("FontBBox");
+  public static final PdfName FontDescriptor = new PdfName("FontDescriptor");
+  public static final PdfName FontFile = new PdfName("FontFile");
+  public static final PdfName FontFile2 = new PdfName("FontFile2");
+  public static final PdfName FontFile3 = new PdfName("FontFile3");
+  public static final PdfName FontName = new PdfName("FontName");
+  public static final PdfName ForComment = new PdfName("ForComment");
+  public static final PdfName Form = new PdfName("Form");
+  public static final PdfName ForPublicRelease = new PdfName("ForPublicRelease");
+  public static final PdfName FreeText = new PdfName("FreeText");
+  public static final PdfName FS = new PdfName("FS");
+  public static final PdfName FT = new PdfName("FT");
+  public static final PdfName FullScreen = new PdfName("FullScreen");
+  public static final PdfName Glitter = new PdfName("Glitter");
+  public static final PdfName GoTo = new PdfName("GoTo");
+  public static final PdfName GoTo3DView = new PdfName("GoTo3DView");
+  public static final PdfName GoToAction = new PdfName("GoToAction");
+  public static final PdfName GoToE = new PdfName("GoToE");
+  public static final PdfName GoToR = new PdfName("GoToR");
+  public static final PdfName Graph = new PdfName("Graph");
+  public static final PdfName H = new PdfName("H");
+  public static final PdfName Height = new PdfName("Height");
+  public static final PdfName Help = new PdfName("Help");
+  public static final PdfName Hide = new PdfName("Hide");
+  public static final PdfName HideMenubar = new PdfName("HideMenubar");
+  public static final PdfName HideToolbar = new PdfName("HideToolbar");
+  public static final PdfName HideWindowUI = new PdfName("HideWindowUI");
+  public static final PdfName Highlight = new PdfName("Highlight");
+  public static final PdfName I = new PdfName("I");
+  public static final PdfName IC = new PdfName("IC");
+  public static final PdfName ICCBased = new PdfName("ICCBased");
+  public static final PdfName Identity = new PdfName("Identity");
+  public static final PdfName IdentityH = new PdfName("Identity-H");
+  public static final PdfName IdentityV = new PdfName("Identity-V");
+  public static final PdfName IF = new PdfName("IF");
+  public static final PdfName Image = new PdfName("Image");
+  public static final PdfName ImportData = new PdfName("ImportData");
+  public static final PdfName Info = new PdfName("Info");
+  public static final PdfName Ink = new PdfName("Ink");
+  public static final PdfName InkList = new PdfName("InkList");
+  public static final PdfName Insert = new PdfName("Insert");
+  public static final PdfName ItalicAngle = new PdfName("ItalicAngle");
+  public static final PdfName IX = new PdfName("IX");
+  public static final PdfName JavaScript = new PdfName("JavaScript");
+  public static final PdfName JBIG2Decode = new PdfName("JBIG2Decode");
+  public static final PdfName JPXDecode = new PdfName("JPXDecode");
+  public static final PdfName JS = new PdfName("JS");
+  public static final PdfName K = new PdfName("K");
+  public static final PdfName Key = new PdfName("Key");
+  public static final PdfName Keywords = new PdfName("Keywords");
+  public static final PdfName Kids = new PdfName("Kids");
+  public static final PdfName L = new PdfName("L");
+  public static final PdfName L2R = new PdfName("L2R");
+  public static final PdfName Lab = new PdfName("Lab");
+  public static final PdfName Last = new PdfName("Last");
+  public static final PdfName LastChar = new PdfName("LastChar");
+  public static final PdfName LastPage = new PdfName("LastPage");
+  public static final PdfName Launch = new PdfName("Launch");
+  public static final PdfName LC = new PdfName("LC");
+  public static final PdfName LE = new PdfName("LE");
+  public static final PdfName Leading = new PdfName("Leading");
+  public static final PdfName Length = new PdfName("Length");
+  public static final PdfName Limits = new PdfName("Limits");
+  public static final PdfName Line = new PdfName("Line");
+  public static final PdfName Link = new PdfName("Link");
+  public static final PdfName LJ = new PdfName("LJ");
+  public static final PdfName LL = new PdfName("LL");
+  public static final PdfName LLE = new PdfName("LLE");
+  public static final PdfName LW = new PdfName("LW");
+  public static final PdfName LZW = new PdfName("LZW");
+  public static final PdfName LZWDecode = new PdfName("LZWDecode");
+  public static final PdfName M = new PdfName("M");
+  public static final PdfName Mac = new PdfName("Mac");
+  public static final PdfName MacRomanEncoding = new PdfName("MacRomanEncoding");
+  public static final PdfName Matrix = new PdfName("Matrix");
+  public static final PdfName MaxLen = new PdfName("MaxLen");
+  public static final PdfName MediaBox = new PdfName("MediaBox");
+  public static final PdfName Mic = new PdfName("Mic");
+  public static final PdfName MissingWidth = new PdfName("MissingWidth");
+  public static final PdfName MK = new PdfName("MK");
+  public static final PdfName ML = new PdfName("ML");
+  public static final PdfName MMType1 = new PdfName("MMType1");
+  public static final PdfName ModDate = new PdfName("ModDate");
+  public static final PdfName Movie = new PdfName("Movie");
+  public static final PdfName N = new PdfName("N");
+  public static final PdfName Name = new PdfName("Name");
+  public static final PdfName Named = new PdfName("Named");
+  public static final PdfName Names = new PdfName("Names");
+  public static final PdfName NewParagraph = new PdfName("NewParagraph");
+  public static final PdfName NewWindow = new PdfName("NewWindow");
+  public static final PdfName Next = new PdfName("Next");
+  public static final PdfName NextPage = new PdfName("NextPage");
+  public static final PdfName NM = new PdfName("NM");
+  public static final PdfName None = new PdfName("None");
+  public static final PdfName NotApproved = new PdfName("NotApproved");
+  public static final PdfName Note = new PdfName("Note");
+  public static final PdfName NotForPublicRelease = new PdfName("NotForPublicRelease");
+  public static final PdfName O = new PdfName("O");
+  public static final PdfName OC = new PdfName("OC");
+  public static final PdfName Off = new PdfName("Off");
+  public static final PdfName OneColumn = new PdfName("OneColumn");
+  public static final PdfName Open = new PdfName("Open");
+  public static final PdfName OpenAction = new PdfName("OpenAction");
+  public static final PdfName OpenArrow = new PdfName("OpenArrow");
+  public static final PdfName OpenType = new PdfName("OpenType");
+  public static final PdfName Opt = new PdfName("Opt");
+  public static final PdfName Ordering = new PdfName("Ordering");
+  public static final PdfName Outlines = new PdfName("Outlines");
+  public static final PdfName P = new PdfName("P");
+  public static final PdfName Page = new PdfName("Page");
+  public static final PdfName PageLayout = new PdfName("PageLayout");
+  public static final PdfName PageMode = new PdfName("PageMode");
+  public static final PdfName Pages = new PdfName("Pages");
+  public static final PdfName Paperclip = new PdfName("Paperclip");
+  public static final PdfName Paragraph = new PdfName("Paragraph");
+  public static final PdfName Parent = new PdfName("Parent");
+  public static final PdfName PC = new PdfName("PC");
+  public static final PdfName PI = new PdfName("PI");
+  public static final PdfName PO = new PdfName("PO");
+  public static final PdfName Polygon = new PdfName("Polygon");
+  public static final PdfName PolyLine = new PdfName("PolyLine");
+  public static final PdfName Popup = new PdfName("Popup");
+  public static final PdfName Prev = new PdfName("Prev");
+  public static final PdfName PrevPage = new PdfName("PrevPage");
+  public static final PdfName Producer = new PdfName("Producer");
+  public static final PdfName Push = new PdfName("Push");
+  public static final PdfName PushPin = new PdfName("PushPin");
+  public static final PdfName PV = new PdfName("PV");
+  public static final PdfName Q = new PdfName("Q");
+  public static final PdfName QuadPoints = new PdfName("QuadPoints");
+  public static final PdfName R = new PdfName("R");
+  public static final PdfName R2L = new PdfName("R2L");
+  public static final PdfName RC = new PdfName("RC");
+  public static final PdfName RClosedArrow = new PdfName("RClosedArrow");
+  public static final PdfName Rect = new PdfName("Rect");
+  public static final PdfName Registry = new PdfName("Registry");
+  public static final PdfName Rendition = new PdfName("Rendition");
+  public static final PdfName ResetForm = new PdfName("ResetForm");
+  public static final PdfName Resources = new PdfName("Resources");
+  public static final PdfName RF = new PdfName("RF");
+  public static final PdfName RGB = new PdfName("RGB");
+  public static final PdfName RI = new PdfName("RI");
+  public static final PdfName RL = new PdfName("RL");
+  public static final PdfName Root = new PdfName("Root");
+  public static final PdfName ROpenArrow = new PdfName("ROpenArrow");
+  public static final PdfName RunLengthDecode = new PdfName("RunLengthDecode");
+  public static final PdfName S = new PdfName("S");
+  public static final PdfName SetOCGState = new PdfName("SetOCGState");
+  public static final PdfName Sig = new PdfName("Sig");
+  public static final PdfName SinglePage = new PdfName("SinglePage");
+  public static final PdfName Size = new PdfName("Size");
+  public static final PdfName Slash = new PdfName("Slash");
+  public static final PdfName Sold = new PdfName("Sold");
+  public static final PdfName Sound = new PdfName("Sound");
+  public static final PdfName Speaker = new PdfName("Speaker");
+  public static final PdfName Split = new PdfName("Split");
+  public static final PdfName Square = new PdfName("Square");
+  public static final PdfName Squiggly = new PdfName("Squiggly");
+  public static final PdfName SS = new PdfName("SS");
+  public static final PdfName Stamp = new PdfName("Stamp");
+  public static final PdfName StandardEncoding = new PdfName("StandardEncoding");
+  public static final PdfName StemV = new PdfName("StemV");
+  public static final PdfName StrikeOut = new PdfName("StrikeOut");
+  public static final PdfName StructParent = new PdfName("StructParent");
+  public static final PdfName Subject = new PdfName("Subject");
+  public static final PdfName SubmitForm = new PdfName("SubmitForm");
+  public static final PdfName Subtype = new PdfName("Subtype");
+  public static final PdfName Supplement = new PdfName("Supplement");
+  public static final PdfName SW = new PdfName("SW");
+  public static final PdfName Sy = new PdfName("Sy");
+  public static final PdfName T = new PdfName("T");
+  public static final PdfName Tabs = new PdfName("Tabs");
+  public static final PdfName Tag = new PdfName("Tag");
+  public static final PdfName Text = new PdfName("Text");
+  public static final PdfName Thread = new PdfName("Thread");
+  public static final PdfName Title = new PdfName("Title");
+  public static final PdfName TopSecret = new PdfName("TopSecret");
+  public static final PdfName ToUnicode = new PdfName("ToUnicode");
+  public static final PdfName TP = new PdfName("TP");
+  public static final PdfName Trans = new PdfName("Trans");
+  public static final PdfName TrueType = new PdfName("TrueType");
+  public static final PdfName TwoColumnLeft = new PdfName("TwoColumnLeft");
+  public static final PdfName Tx = new PdfName("Tx");
+  public static final PdfName Type = new PdfName("Type");
+  public static final PdfName Type0 = new PdfName("Type0");
+  public static final PdfName Type1 = new PdfName("Type1");
+  public static final PdfName Type1C = new PdfName("Type1C");
+  public static final PdfName Type3 = new PdfName("Type3");
+  public static final PdfName U = new PdfName("U");
+  public static final PdfName Uncover = new PdfName("Uncover");
+  public static final PdfName Underline = new PdfName("Underline");
+  public static final PdfName Unix = new PdfName("Unix");
+  public static final PdfName URI = new PdfName("URI");
+  public static final PdfName UseNone = new PdfName("UseNone");
+  public static final PdfName UseOutlines = new PdfName("UseOutlines");
+  public static final PdfName UseThumbs = new PdfName("UseThumbs");
+  public static final PdfName V = new PdfName("V");
+  public static final PdfName Version = new PdfName("Version");
+  public static final PdfName Vertices = new PdfName("Vertices");
+  public static final PdfName ViewerPreferences = new PdfName("ViewerPreferences");
+  public static final PdfName W = new PdfName("W");
+  public static final PdfName Widget = new PdfName("Widget");
+  public static final PdfName Width = new PdfName("Width");
+  public static final PdfName Widths = new PdfName("Widths");
+  public static final PdfName Win = new PdfName("Win");
+  public static final PdfName WinAnsiEncoding = new PdfName("WinAnsiEncoding");
+  public static final PdfName Wipe = new PdfName("Wipe");
+  public static final PdfName WP = new PdfName("WP");
+  public static final PdfName WS = new PdfName("WS");
+  public static final PdfName X = new PdfName("X");
+  public static final PdfName XObject = new PdfName("XObject");
+  public static final PdfName XYZ = new PdfName("XYZ");
+  public static final PdfName Yes = new PdfName("Yes");
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  public PdfName(
+    String value
+    )
+  {setValue(value);}
+
+  /**
+    For internal use only.
+  */
+  public PdfName(
+    String value,
+    boolean escaped
+    )
+  {
+    /*
+      NOTE: To avoid ambiguities due to the presence of '#' characters,
+      it's necessary to explicitly state when a name value has already been escaped.
+      This is tipically the case of names parsed from a previously-serialized PDF file.
+    */
+    if(escaped)
+    {setRawValue(value);}
+    else
+    {setValue(value);}
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public Object clone(
+    File context
+    )
+  {
+    // Shallow copy.
+    PdfName clone = (PdfName)super.clone();
+
+    // Deep copy.
+    /* NOTE: No mutable object to be cloned. */
+
+    return clone;
+  }
+
+  @Override
+  public int compareTo(
+    PdfDirectObject obj
+    )
+  {
+    if(!(obj instanceof PdfName))
+      throw new IllegalArgumentException("Object MUST be a PdfName");
+
+    return getRawValue().compareTo(((PdfName)obj).getRawValue());
+  }
+
+  @Override
+  public boolean equals(
+    Object object
+    )
+  {
+    if(!(object instanceof PdfName))
+      return false;
+
+    return getRawValue().equals(((PdfName)object).getRawValue());
+  }
+
+  @Override
+  public int hashCode(
+    )
+  {return getRawValue().hashCode();}
+
+  @Override
+  public void setValue(
+    Object value
+    )
+  {
+    String stringValue = (String)value;
+    /*
+      NOTE: Before being accepted, any character sequence identifying a name MUST be normalized
+      escaping reserved characters.
+    */
+    StringBuilder buffer = new StringBuilder();
+    int index = 0;
+    Matcher unescapedMatcher = UnescapedPattern.matcher(stringValue);
+    while(unescapedMatcher.find())
+    {
+      int start = unescapedMatcher.start();
+      if(start > index)
+      {buffer.append(stringValue.substring(index,start));}
+
+      buffer.append(
+        '#' + Integer.toHexString(
+          (int)unescapedMatcher.group(0).charAt(0)
+          )
+        );
+
+      index = unescapedMatcher.end();
+    }
+    if(index < stringValue.length())
+    {buffer.append(stringValue.substring(index));}
+
+    setRawValue(buffer.toString());
+  }
+
+  @Override
+  public String toString(
+    )
+  {
+    /*
+      NOTE: The textual representation of a name concerns unescaping reserved characters.
+    */
+    String value = getRawValue();
+    StringBuilder buffer = new StringBuilder();
+    int index = 0;
+    Matcher escapedMatcher = EscapedPattern.matcher(value);
+    while(escapedMatcher.find())
+    {
+      int start = escapedMatcher.start();
+      if(start > index)
+      {buffer.append(value.substring(index,start));}
+
+      buffer.append(
+        (char)Integer.parseInt(
+          escapedMatcher.group(1),
+          16
+          )
+        );
+
+      index = escapedMatcher.end();
+    }
+    if(index < value.length())
+    {buffer.append(value.substring(index));}
+
+    return buffer.toString();
+  }
+
+  @Override
+  public void writeTo(
+    IOutputStream stream
+    )
+  {stream.write(toPdf(getRawValue()));}
+  // </public>
+
+  // <private>
+  private String toPdf(
+    String value
+    )
+  {return "/" + value;}
+  // </private>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfNamedObjectWrapper.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfNamedObjectWrapper.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfNamedObjectWrapper.java	(revision 23703)
@@ -0,0 +1,122 @@
+/*
+  Copyright 2009 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.objects;
+
+import it.stefanochizzolini.clown.files.File;
+
+/**
+  High-level representation of a strongly-typed PDF object
+  that can be referenced also through a name. When such a name exists, the object
+  is called 'named object', otherwise 'unnamed object'.
+  <h3>Remarks</h3>
+  <p>Some categories of objects in a PDF file can be also referred to by name
+  rather than by object reference. The correspondence between names and objects
+  is established by the document's name dictionary [PDF:1.6:3.6.3].</p>
+  <p>The name's purpose is to provide a further level of referential abstraction
+  especially for references across diverse PDF documents.</p>
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+  @since 0.0.8
+*/
+public abstract class PdfNamedObjectWrapper<TDataObject extends PdfDataObject>
+  extends PdfObjectWrapper<TDataObject>
+{
+  // <class>
+  // <dynamic>
+  // <fields>
+  private PdfString name;
+  // </fields>
+
+  // <constructors>
+  protected PdfNamedObjectWrapper(
+    File context,
+    TDataObject baseDataObject
+    )
+  {
+    this(
+      context.register(baseDataObject),
+      null,
+      null
+      );
+  }
+
+  /**
+    @param baseObject Base PDF object. MUST be a {@link PdfReference}
+    everytime available.
+    @param container Indirect object containing the base object.
+    @param name Object name.
+  */
+  protected PdfNamedObjectWrapper(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container,
+    PdfString name
+    )
+  {
+    super(
+      baseObject,
+      container
+      );
+    this.name = name;
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  /**
+    Gets the object name.
+  */
+  public PdfString getName(
+    )
+  {return name;}
+
+  /**
+    Gets the object name, if available;
+    otherwise, behaves like {@link PdfObjectWrapper#getBaseObject() getBaseObject()}.
+  */
+  public PdfDirectObject getNamedBaseObject(
+    )
+  {
+    if(name != null)
+      return name;
+    else
+      return getBaseObject();
+  }
+  // </public>
+
+  // <internal>
+  /**
+    @see #getName()
+  */
+  void setName(
+    PdfString value
+    )
+  {name = value;}
+  // </internal>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfNumber.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfNumber.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfNumber.java	(revision 23703)
@@ -0,0 +1,42 @@
+/*
+  Copyright 2009 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.objects;
+
+class PdfNumber
+{
+  public static int compare(
+    Object obj1,
+    Object obj2
+    )
+  {
+    if(!(obj1 instanceof IPdfNumber))
+      throw new IllegalArgumentException("obj1 MUST implement IPdfNumber");
+    if(!(obj2 instanceof IPdfNumber))
+      throw new IllegalArgumentException("obj2 MUST implement IPdfNumber");
+
+    return Double.compare(((IPdfNumber)obj1).getNumberValue(),((IPdfNumber)obj2).getNumberValue());
+  }
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfObject.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfObject.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfObject.java	(revision 23703)
@@ -0,0 +1,79 @@
+/*
+  Copyright 2006-2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.objects;
+
+import it.stefanochizzolini.clown.bytes.IOutputStream;
+import it.stefanochizzolini.clown.files.File;
+
+/**
+  Abstract PDF object.
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.6
+*/
+public abstract class PdfObject
+  implements Cloneable
+{
+  // <class>
+  // <dynamic>
+  // <constructors>
+  public PdfObject(
+    )
+  {}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  /**
+    Gets the clone of the object, registered inside the given file context.
+  */
+  public abstract Object clone(
+    File context
+    );
+
+  /**
+    Serializes the object to the given stream.
+  */
+  public abstract void writeTo(
+    IOutputStream stream
+    );
+  // </public>
+
+  // <protected>
+  @Override
+  protected Object clone(
+    )
+  {
+    try
+    {return super.clone();}
+    catch(CloneNotSupportedException e)
+    {throw new RuntimeException("Unable to clone.",e);}
+  }
+  // </protected>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfObjectWrapper.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfObjectWrapper.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfObjectWrapper.java	(revision 23703)
@@ -0,0 +1,195 @@
+/*
+  Copyright 2006-2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.objects;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.files.File;
+
+/**
+  Base high-level representation of a PDF object.
+  All specialized objects (e.g. Document, Page, Pages, ContentStream...) inherit from it.
+  <h3>Remarks</h3>
+  <p>Somebody may wonder why I didn't directly make specialized objects inherit from
+  their low-level counterparts (e.g. Page extends PdfDictionary, ContentStream
+  extends PdfStream and so on): that could have been much smoother anyway, you argue.
+  Yeah, I could agree if there was a plain one-to-one mapping between primitive PDF
+  types and specialized instances, but (you know!) reality is not so polished as
+  theory: the 'Content' entry of Page dictionaries may be a simple reference to a
+  PdfStream or a PdfArray of references to PdfStream-s, Pages collections may be
+  spread across a B-tree instead of a flat PdfArray etc. So: <i>in order to hide all
+  these annoying inner workings, I chose to adopt a composition pattern instead of
+  the apparently-reasonable (but actually awkward!) inheritance pattern</i>.
+  Nonetheless, users are always enabled to navigate through the low-level structure
+  accessing the {@link #getBaseDataObject()} method.</p>
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.7
+*/
+public abstract class PdfObjectWrapper<TDataObject extends PdfDataObject>
+{
+  // <class>
+  // <dynamic>
+  // <fields>
+  private TDataObject baseDataObject;
+  private PdfDirectObject baseObject;
+  private PdfIndirectObject container;
+  // </fields>
+
+  // <constructors>
+  protected PdfObjectWrapper(
+    File context,
+    TDataObject baseDataObject
+    )
+  {
+    this(
+      context.register(baseDataObject),
+      null
+      );
+  }
+
+  /**
+    @param baseObject Base PDF object. MUST be a {@link PdfReference PdfReference}
+    everytime available.
+    @param container Indirect object containing the base object.
+  */
+  protected PdfObjectWrapper(
+    PdfDirectObject baseObject,
+    PdfIndirectObject container
+    )
+  {
+    setBaseObject(baseObject);
+    setContainer(container);
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  /**
+    Gets a clone of the object, registered inside the given document context.
+
+    @param context Which document the clone has to be registered in.
+  */
+  public abstract Object clone(
+    Document context
+    );
+
+  /**
+    Removes the object from its document context.
+    <h3>Remarks</h3>
+    <p>The object is no more usable after this method returns.</p>
+
+    @return Whether the object was actually decontextualized (only indirect objects can be
+    decontextualized).
+  */
+  public boolean delete(
+    )
+  {
+    // Is the object indirect?
+    if(baseObject instanceof PdfReference) // Indirect object.
+    {
+      ((PdfReference)baseObject).delete();
+      return true;
+    }
+    else // Direct object.
+    {return false;}
+  }
+
+  /**
+    Gets the underlying data object.
+  */
+  public TDataObject getBaseDataObject(
+    )
+  {return baseDataObject;}
+
+  /**
+    Gets the underlying reference object, if available;
+    otherwise, behaves like {@link #getBaseDataObject() getBaseDataObject()}.
+  */
+  public PdfDirectObject getBaseObject(
+    )
+  {return baseObject;}
+
+  /**
+    Gets the indirect object containing the base object.
+    <h3>Remarks</h3>
+    <p>It's used for update purposes.</p>
+  */
+  public PdfIndirectObject getContainer(
+    )
+  {return container;}
+
+  /**
+    Gets the document context.
+  */
+  public Document getDocument(
+    )
+  {return container.getFile().getDocument();}
+
+  /**
+    Gets the file context.
+  */
+  public File getFile(
+    )
+  {return container.getFile();}
+
+  /**
+    Manually update the underlying indirect object.
+  */
+  public void update(
+    )
+  {container.update();}
+  // </public>
+
+  // <protected>
+  @SuppressWarnings("unchecked")
+  protected void setBaseObject(
+    PdfDirectObject value
+    )
+  {
+    baseObject = value;
+    baseDataObject = (TDataObject)File.resolve(baseObject);
+  }
+  // </protected>
+
+  // <internal>
+  /**
+    For internal use only.
+  */
+  public void setContainer(
+    PdfIndirectObject value
+    )
+  {
+    // Is base object indirect (self-contained)?
+    if(baseObject instanceof PdfReference) // Base object is indirect (self-contained).
+    {container = ((PdfReference)baseObject).getIndirectObject();}
+    else // Base object is direct (contained).
+    {container = value;}
+  }
+  // </internal>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfReal.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfReal.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfReal.java	(revision 23703)
@@ -0,0 +1,133 @@
+/*
+  Copyright 2006-2009 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.objects;
+
+import it.stefanochizzolini.clown.bytes.IOutputStream;
+import it.stefanochizzolini.clown.files.File;
+
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+
+/**
+  PDF real number object [PDF:1.6:3.2.2].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+*/
+public class PdfReal
+  extends PdfAtomicObject<Double>
+  implements IPdfNumber
+{
+  // <class>
+  // <static>
+  // <fields>
+  protected static final DecimalFormat formatter;
+  // </fields>
+
+  // <constructors>
+  static
+  {
+    DecimalFormatSymbols symbols = new DecimalFormatSymbols();
+    symbols.setDecimalSeparator('.');
+    formatter = new DecimalFormat("0.#####",symbols);
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  /**
+    Gets the object equivalent to the given value.
+  */
+  public static PdfReal get(
+    Double value
+    )
+  {return value == null ? null : new PdfReal(value);}
+  // </public>
+  // </interface>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  public PdfReal(
+    double value
+    )
+  {setRawValue(value);}
+  // </constructors>
+
+  // <iterface>
+  // <public>
+  @Override
+  public Object clone(
+    File context
+    )
+  {
+    // Shallow copy.
+    PdfReal clone = (PdfReal)super.clone();
+
+    // Deep copy.
+    /* NOTE: No mutable object to be cloned. */
+
+    return clone;
+  }
+
+  @Override
+  public int compareTo(
+    PdfDirectObject obj
+    )
+  {return PdfNumber.compare(this,obj);}
+
+  @Override
+  public void writeTo(
+    IOutputStream stream
+    )
+  {stream.write(toPdf(getRawValue()));}
+
+  // <IPdfNumber>
+  public double getNumberValue(
+    )
+  {return getRawValue();}
+
+  public void setNumberValue(
+    double value
+    )
+  {setRawValue(value);}
+
+  public void translateNumberValue(
+    double value
+    )
+  {setRawValue(getRawValue() + value);}
+  // </IPdfNumber>
+  // </public>
+
+  // <private>
+  private String toPdf(
+    double value
+    )
+  {return formatter.format(value);}
+  // </private>
+  // </interface>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfReference.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfReference.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfReference.java	(revision 23703)
@@ -0,0 +1,200 @@
+/*
+  Copyright 2006-2009 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.objects;
+
+import it.stefanochizzolini.clown.bytes.IOutputStream;
+import it.stefanochizzolini.clown.files.File;
+import it.stefanochizzolini.clown.tokens.Parser;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.text.DecimalFormat;
+
+/**
+  PDF indirect reference object [PDF:1.6:3.2.9].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+*/
+public class PdfReference
+  extends PdfDirectObject
+  implements IPdfIndirectObject
+{
+  // <class>
+  // <static>
+  // <fields>
+  private static final DecimalFormat xRefGenerationFormatter;
+  private static final DecimalFormat xRefOffsetFormatter;
+  // </fields>
+
+  // <constructors>
+  static
+  {
+    xRefGenerationFormatter = new DecimalFormat("00000");
+    xRefOffsetFormatter = new DecimalFormat("0000000000");
+  }
+  // </constructors>
+  // </static>
+
+  // <dynamic>
+  // <fields>
+  private PdfIndirectObject indirectObject;
+
+  private int generationNumber;
+  private int objectNumber;
+
+  private File file;
+  // </fields>
+
+  // <constructors>
+  PdfReference(
+    PdfIndirectObject indirectObject,
+    int objectNumber,
+    int generationNumber
+    )
+  {
+    this.indirectObject = indirectObject;
+
+    this.objectNumber = objectNumber;
+    this.generationNumber = generationNumber;
+  }
+
+  /**
+    For internal use only.
+
+    <p>This is a necessary hack because indirect objects are unreachable on parsing bootstrap
+    (see File(IInputStream) constructor).</p>
+  */
+  public PdfReference(
+    Parser.Reference reference,
+    File file
+    )
+  {
+    this.objectNumber = reference.getObjectNumber();
+    this.generationNumber = reference.getGenerationNumber();
+
+    this.file = file;
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public int compareTo(
+    PdfDirectObject object
+    )
+  {throw new NotImplementedException();}
+
+  @Override
+  public boolean equals(
+    Object object
+    )
+  {
+    if(!(object instanceof PdfReference))
+      return false;
+
+    return (getID().equals(((PdfReference)object).getID()));
+  }
+
+  public String getCrossReference(
+    long offset
+    )
+  {
+    return (xRefOffsetFormatter.format(offset) + " "
+        + xRefGenerationFormatter.format(generationNumber) + " "
+        + getIndirectObject().getUsage()
+        + "\r\n");
+  }
+
+  public int getGenerationNumber(
+    )
+  {return generationNumber;}
+
+  public String getID(
+    )
+  {return (objectNumber + " " + generationNumber);}
+
+  public String getIndirectReference(
+    )
+  {return (getID() + " R");}
+
+  public int getObjectNumber(
+    )
+  {return objectNumber;}
+
+  @Override
+  public int hashCode(
+    )
+  {return getIndirectObject().hashCode();}
+
+  @Override
+  public String toString(
+    )
+  {return getIndirectReference();}
+
+  @Override
+  public void writeTo(
+    IOutputStream stream
+    )
+  {stream.write(getIndirectReference());}
+
+  // <IPdfIndirectObject>
+  @Override
+  public Object clone(
+    File context
+    )
+  {return ((PdfIndirectObject)getIndirectObject().clone(context)).getReference();}
+
+  public void delete(
+    )
+  {getIndirectObject().delete();}
+
+  public PdfDataObject getDataObject(
+    )
+  {return getIndirectObject().getDataObject();}
+
+  public PdfIndirectObject getIndirectObject(
+    )
+  {
+    if(indirectObject == null)
+    {indirectObject = file.getIndirectObjects().get(objectNumber);}
+
+    return indirectObject;
+  }
+
+  public PdfReference getReference(
+    )
+  {return this;}
+
+  public void setDataObject(
+    PdfDataObject value
+    )
+  {getIndirectObject().setDataObject(value);}
+  // </IPdfIndirectObject>
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfStream.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfStream.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfStream.java	(revision 23703)
@@ -0,0 +1,235 @@
+/*
+  Copyright 2006-2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.objects;
+
+import it.stefanochizzolini.clown.bytes.Buffer;
+import it.stefanochizzolini.clown.bytes.IBuffer;
+import it.stefanochizzolini.clown.bytes.IOutputStream;
+import it.stefanochizzolini.clown.bytes.filters.Filter;
+import it.stefanochizzolini.clown.files.File;
+import java.util.Iterator;
+
+/**
+  PDF stream object [PDF:1.6:3.2.7].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.6
+*/
+public class PdfStream
+  extends PdfDataObject
+{
+  // <class>
+  // <dynamic>
+  // <fields>
+  private IBuffer body;
+  private PdfDictionary header;
+  // </fields>
+
+  // <constructors>
+  public PdfStream(
+    )
+  {
+    this(
+      new PdfDictionary(),
+      new Buffer()
+      );
+  }
+
+  public PdfStream(
+    PdfDictionary header
+    )
+  {
+    this(
+      header,
+      new Buffer()
+      );
+  }
+
+  public PdfStream(
+    IBuffer body
+    )
+  {
+    this(
+      new PdfDictionary(),
+      body
+      );
+  }
+
+  public PdfStream(
+    PdfDictionary header,
+    IBuffer body
+    )
+  {
+    this.header = header;
+    this.body = body;
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public Object clone(
+    File context
+    )
+  {
+    PdfStream clone = new PdfStream(
+      (PdfDictionary)header.clone(context),
+      body.clone()
+      );
+
+    return clone;
+  }
+
+  /**
+    Gets the decoded stream body.
+  */
+  public IBuffer getBody(
+    )
+  {
+    /*
+      NOTE: Encoding filters are removed by default because they belong to a lower layer
+      (token layer), so that it's appropriate and consistent to transparently keep the object layer
+      unaware of such a facility.
+    */
+    return getBody(true);
+  }
+
+  /**
+    Gets the stream body.
+    @param decode Defines whether the body has to be decoded.
+  */
+  public IBuffer getBody(
+    boolean decode
+    )
+  {
+    if(decode)
+    {
+      // Get 'Filter' entry!
+      /*
+        NOTE: Such an entry defines possible encodings applied to the stream.
+      */
+      PdfDirectObject filterObj = header.get(PdfName.Filter);
+      // Is the stream encoded?
+      if(filterObj != null)
+      {
+        /*
+          NOTE: If the stream is encoded, we must decode it before continuing.
+        */
+        // TODO:IMPL 'DecodeParms' entry management!!!
+        PdfDataObject filterDataObj = File.resolve(filterObj);
+        if(filterDataObj instanceof PdfName) // PdfName.
+        {body.decode(Filter.get((PdfName)filterDataObj));}
+        else // MUST be PdfArray.
+        {
+          // [FIX:0.0.5:1:SC] It failed to deal with filter chains.
+          Iterator<PdfDirectObject> filterObjIterator = ((PdfArray)filterDataObj).iterator();
+          while(filterObjIterator.hasNext())
+          {body.decode(Filter.get((PdfName)File.resolve(filterObjIterator.next())));}
+        }
+
+        // Update 'Filter' entry!
+        header.put(PdfName.Filter,null); // The stream is free from encodings.
+      }
+    }
+
+    return body;
+  }
+
+  public PdfDictionary getHeader(
+    )
+  {return header;}
+
+  @Override
+  public void writeTo(
+    IOutputStream stream
+    )
+  {
+    boolean unencodedBody;
+    byte[] bodyData;
+    int bodyLength;
+
+    // 1. Header.
+    // Encoding.
+    /*
+      NOTE: As the contract establishes that a stream instance should be kept
+      free from encodings in order to be editable, encoding is NOT applied to
+      the actual online stream, but to its serialized representation only.
+      That is, as encoding is just a serialization practise, it is excluded from
+      alive, instanced streams.
+    */
+    PdfDirectObject filterObj = header.get(PdfName.Filter);
+    // Is the body free from encodings?
+    if(filterObj == null) // Unencoded body.
+    {
+      /*
+        NOTE: As online representation is unencoded,
+        header entries related to the encoded stream body are temporary
+        (instrumental to the current serialization process).
+      */
+      unencodedBody = true;
+    
+      // Set the filter to apply!
+      filterObj = PdfName.FlateDecode; // zlib/deflate filter.
+      // Get encoded body data applying the filter to the stream!
+      bodyData = body.encode(Filter.get((PdfName)filterObj));
+      // Set encoded length!
+      bodyLength = bodyData.length;
+      // Update 'Filter' entry!
+      header.put(PdfName.Filter,filterObj);
+    }
+    else // Encoded body.
+    {
+      unencodedBody = false;
+
+      // Get encoded body data!
+      bodyData = body.toByteArray();
+      // Set encoded length!
+      bodyLength = (int)body.getLength();
+    }
+    // Set encoded length!
+    header.put(PdfName.Length,new PdfInteger(bodyLength));
+
+    header.writeTo(stream);
+
+    // Is the body free from encodings?
+    if(unencodedBody)
+    {
+      // Restore actual header entries!
+      ((PdfInteger)header.get(PdfName.Length)).setValue((int)body.getLength());
+      header.put(PdfName.Filter,null);
+    }
+
+    // 2. Body.
+    // [FIX:1909707:AH] Invalid end-of-line marker for stream objects.
+    stream.write("\nstream\n");
+    stream.write(bodyData);
+    stream.write("\nendstream");
+  }
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfString.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfString.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfString.java	(revision 23703)
@@ -0,0 +1,295 @@
+/*
+  Copyright 2008-2009 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.objects;
+
+import it.stefanochizzolini.clown.bytes.IOutputStream;
+import it.stefanochizzolini.clown.files.File;
+import it.stefanochizzolini.clown.util.ConvertUtils;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.io.ByteArrayOutputStream;
+
+/**
+  PDF string object [PDF:1.6:3.2.3].
+
+  <p>A string object consists of a series of bytes.</p>
+  <p>String objects can be serialized in two ways:</p>
+  <ul>
+    <li>as a sequence of literal characters (plain form)</li>
+    <li>as a sequence of hexadecimal digits (hexadecimal form)</li>
+  </ul>
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+  @since 0.0.6
+*/
+public class PdfString
+  extends PdfAtomicObject<byte[]>
+{
+  /*
+    NOTE: String objects are internally represented as unescaped sequences of bytes.
+    Escaping is applied on serialization only.
+  */
+  // <class>
+  // <classes>
+  /**
+    String serialization mode.
+  */
+  public enum SerializationModeEnum
+  {
+    /**
+      Plain form.
+    */
+    Literal,
+    /**
+      Hexadecimal form.
+    */
+    Hex
+  };
+  // </classes>
+
+  // <static>
+  // <fields>
+  private static final byte BackspaceCode = 8;
+  private static final byte CarriageReturnCode = 13;
+  private static final byte FormFeedCode = 12;
+  private static final byte HorizontalTabCode = 9;
+  private static final byte LineFeedCode = 10;
+
+  private static final byte HexLeftDelimiterCode = 60;
+  private static final byte HexRightDelimiterCode = 62;
+  private static final byte LiteralEscapeCode = 92;
+  private static final byte LiteralLeftDelimiterCode = 40;
+  private static final byte LiteralRightDelimiterCode = 41;
+
+  private static final String Encoding = "ISO-8859-1";
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <fields>
+  private SerializationModeEnum serializationMode = SerializationModeEnum.Literal;
+  // </fields>
+
+  // <constructors>
+  public PdfString(
+    )
+  {}
+
+  public PdfString(
+    byte[] value
+    )
+  {setRawValue(value);}
+
+  public PdfString(
+    String value
+    )
+  {setValue(value);}
+
+  public PdfString(
+    byte[] value,
+    SerializationModeEnum serializationMode
+    )
+  {
+    setSerializationMode(serializationMode);
+    setRawValue(value);
+  }
+
+  public PdfString(
+    String value,
+    SerializationModeEnum serializationMode
+    )
+  {
+    setSerializationMode(serializationMode);
+    setValue(value);
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public Object clone(
+    File context
+    )
+  {
+    // Shallow copy.
+    PdfString clone = (PdfString)super.clone();
+
+    // Deep copy.
+    /* NOTE: No mutable object to be cloned. */
+
+    return clone;
+  }
+
+  @Override
+  public int compareTo(
+    PdfDirectObject object
+    )
+  {
+    if(!(object instanceof PdfString))
+      throw new IllegalArgumentException("Object MUST be a PdfString");
+
+    return ((String)getValue()).compareTo((String)((PdfString)object).getValue());
+  }
+
+  /**
+    Gets the serialization mode.
+  */
+  public SerializationModeEnum getSerializationMode(
+    )
+  {return serializationMode;}
+
+  @Override
+  public Object getValue(
+    )
+  {
+    switch(serializationMode)
+    {
+      case Literal:
+        try
+        {
+          return new String(
+            getRawValue(),
+            Encoding
+            );
+        }
+        catch(Exception e)
+        {throw new RuntimeException(e);}
+      case Hex:
+        return ConvertUtils.byteArrayToHex(getRawValue());
+      default:
+        throw new NotImplementedException(serializationMode + " serialization mode is not implemented.");
+    }
+  }
+
+  /**
+    @see #getSerializationMode()
+  */
+  public void setSerializationMode(
+    SerializationModeEnum value
+    )
+  {serializationMode = value;}
+
+  @Override
+  public void setValue(
+    Object value
+    )
+  {
+    switch(serializationMode)
+    {
+      case Literal:
+        try
+        {setRawValue(((String)value).getBytes(Encoding));}
+        catch(Exception e)
+        {throw new RuntimeException(e);}
+        break;
+      case Hex:
+        setRawValue(ConvertUtils.hexToByteArray((String)value));
+        break;
+      default:
+        throw new NotImplementedException(serializationMode + " serialization mode is not implemented.");
+    }
+  }
+
+  @Override
+  public void writeTo(
+    IOutputStream stream
+    )
+  {stream.write(toPdf());}
+  // </public>
+
+  // <private>
+  private byte[] toPdf(
+    )
+  {
+    byte[] rawValue = getRawValue();
+    ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+    switch(serializationMode)
+    {
+      case Literal:
+        buffer.write(LiteralLeftDelimiterCode);
+        /*
+          NOTE: Literal lexical conventions prescribe that the following reserved characters
+          are to be escaped when placed inside string character sequences:
+            - \n Line feed (LF)
+            - \r Carriage return (CR)
+            - \t Horizontal tab (HT)
+            - \b Backspace (BS)
+            - \f Form feed (FF)
+            - \( Left parenthesis
+            - \) Right parenthesis
+            - \\ Backslash
+        */
+        for(
+          int index = 0;
+          index < rawValue.length;
+          index++
+          )
+        {
+          byte valueByte = rawValue[index];
+          switch(valueByte)
+          {
+            case LineFeedCode:
+              buffer.write(LiteralEscapeCode); valueByte = 110; break;
+            case CarriageReturnCode:
+              buffer.write(LiteralEscapeCode); valueByte = 114; break;
+            case HorizontalTabCode:
+              buffer.write(LiteralEscapeCode); valueByte = 116; break;
+            case BackspaceCode:
+              buffer.write(LiteralEscapeCode); valueByte = 98; break;
+            case FormFeedCode:
+              buffer.write(LiteralEscapeCode); valueByte = 102; break;
+            case LiteralLeftDelimiterCode:
+            case LiteralRightDelimiterCode:
+            case LiteralEscapeCode:
+              buffer.write(LiteralEscapeCode); break;
+          }
+          buffer.write(valueByte);
+        }
+        buffer.write(LiteralRightDelimiterCode);
+        break;
+      case Hex:
+        buffer.write(HexLeftDelimiterCode);
+        try
+        {
+          byte[] value = ConvertUtils.byteArrayToHex(rawValue).getBytes(Encoding);
+          buffer.write(value,0,value.length);
+        }
+        catch(Exception e)
+        {throw new RuntimeException(e);}
+        buffer.write(HexRightDelimiterCode);
+        break;
+      default:
+        throw new NotImplementedException();
+    }
+
+    return buffer.toByteArray();
+  }
+  // </private>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfTextString.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfTextString.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/PdfTextString.java	(revision 23703)
@@ -0,0 +1,163 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.objects;
+
+import it.stefanochizzolini.clown.files.File;
+
+/**
+  PDF text string object [PDF:1.6:3.8.1].
+  <h3>Remarks</h3>
+  <p>Text strings are meaningful only as part of the document hierarchy;
+  they cannot appear within content streams.
+  They represent information that is intended to be human-readable.</p>
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.7
+  @since 0.0.6
+*/
+public class PdfTextString
+  extends PdfString
+{
+  /*
+    NOTE: Text strings are string objects encoded in either PDFDocEncoding
+    or Unicode character encoding.
+    PDFDocEncoding is a superset of the ISO Latin 1 encoding [PDF:1.6:D].
+    Unicode is described in the Unicode Standard by the Unicode Consortium [UCS:4].
+  */
+  // <static>
+  // <fields>
+  private static final String ISO88591Encoding = "ISO-8859-1";
+  private static final String UTF16BEEncoding = "UTF-16BE";
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <fields>
+  private String encoding;
+  // </fields>
+
+  // <constructors>
+  public PdfTextString(
+    )
+  {}
+
+  public PdfTextString(
+    byte[] rawValue
+    )
+  {setRawValue(rawValue);}
+
+  public PdfTextString(
+    String value
+    )
+  {setValue(value);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public Object clone(
+    File context
+    )
+  {
+    // Shallow copy.
+    PdfTextString clone = (PdfTextString)super.clone();
+
+    // Deep copy.
+    /* NOTE: No mutable object to be cloned. */
+
+    return clone;
+  }
+
+  public String getEncoding(
+    )
+  {return encoding;}
+
+  @Override
+  public Object getValue(
+    )
+  {
+    try
+    {
+      byte[] valueBytes = getRawValue();
+      byte[] buffer;
+      if(encoding == UTF16BEEncoding)
+      {
+        // Excluding UTF marker...
+        buffer = new byte[valueBytes.length - 2];
+        System.arraycopy(valueBytes,2,buffer,0,buffer.length);
+      }
+      else
+      {buffer = valueBytes;}
+
+      return new String(buffer,encoding);
+    }
+    catch(Exception e)
+    {throw new RuntimeException(e); /* (should NEVER happen). */}
+  }
+
+  @Override
+  public void setValue(
+    Object value
+    )
+  {
+    try
+    {
+      // Prepending UTF marker...
+      byte[] valueBytes = ((String)value).getBytes(UTF16BEEncoding);
+      byte[] buffer = new byte[valueBytes.length + 2];
+      buffer[0] = (byte)254; buffer[1] = (byte)255;
+      System.arraycopy(valueBytes,0,buffer,2,valueBytes.length);
+
+      setRawValue(buffer);
+    }
+    catch(Exception e)
+    {throw new RuntimeException(e);}
+  }
+
+  @Override
+  public void setRawValue(
+    byte[] value
+    )
+  {
+    if(value.length > 2
+      && value[0] == (byte)254
+      && value[1] == (byte)255) // Multi-byte (Unicode).
+    {encoding = UTF16BEEncoding;}
+    else // Single byte (PDFDocEncoding).
+    {encoding = ISO88591Encoding;}
+
+    super.setRawValue(value);
+  }
+
+  @Override
+  public String toString(
+    )
+  {return (String)getValue();}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/Rectangle.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/Rectangle.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/Rectangle.java	(revision 23703)
@@ -0,0 +1,213 @@
+/*
+  Copyright 2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.objects;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.files.File;
+import it.stefanochizzolini.clown.util.NotImplementedException;
+
+import java.awt.geom.Point2D;
+import java.awt.geom.RectangularShape;
+
+/**
+  PDF rectangle object [PDF:1.6:3.8.4].
+  <h3>Remarks</h3>
+  <p>Rectangles are described by two diagonally-opposite corners.</p>
+  <p>Corner pairs which don't respect the canonical form (lower-left and upper-right)
+  are automatically normalized to provide a consistent representation.</p>
+  <p>Coordinates are expressed within the PDF coordinate space (lower-left origin
+  and positively-oriented axes).</p>
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.8
+  @version 0.0.8
+*/
+public class Rectangle
+  extends PdfObjectWrapper<PdfArray>
+{
+  // <class>
+  // <static>
+  // <interface>
+  // <private>
+  private static PdfArray normalize(
+    PdfArray rectangle
+    )
+  {
+    if(((IPdfNumber)rectangle.get(0)).getNumberValue() > ((IPdfNumber)rectangle.get(2)).getNumberValue())
+    {
+      PdfDirectObject leftCoordinate = rectangle.get(2);
+      rectangle.set(2, rectangle.get(0));
+      rectangle.set(0, leftCoordinate);
+    }
+    if(((IPdfNumber)rectangle.get(1)).getNumberValue() > ((IPdfNumber)rectangle.get(3)).getNumberValue())
+    {
+      PdfDirectObject bottomCoordinate = rectangle.get(3);
+      rectangle.set(3, rectangle.get(1));
+      rectangle.set(1, bottomCoordinate);
+    }
+    return rectangle;
+  }
+  // </private>
+  // </interface>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  public Rectangle(
+    RectangularShape rectangle
+    )
+  {
+    this(
+      rectangle.getMinX(),
+      rectangle.getMaxY(),
+      rectangle.getWidth(),
+      rectangle.getHeight()
+      );
+  }
+
+  public Rectangle(
+    Point2D lowerLeft,
+    Point2D upperRight
+    )
+  {
+    this(
+      lowerLeft.getX(),
+      upperRight.getY(),
+      upperRight.getX()-lowerLeft.getX(),
+      upperRight.getY()-lowerLeft.getY()
+      );
+  }
+
+  public Rectangle(
+    double left,
+    double top,
+    double width,
+    double height
+    )
+  {
+    this(
+      new PdfArray(
+        new PdfDirectObject[]
+        {
+          new PdfReal(left),
+          new PdfReal(top-height),
+          new PdfReal(left+width),
+          new PdfReal(top)
+        }
+        )
+      );
+  }
+  //TODO:integrate with the container update infrastructure (see other PdfObjectWrapper subclass implementations)!!
+  public Rectangle(
+    PdfDirectObject baseObject
+    )
+  {super(normalize((PdfArray)File.resolve(baseObject)), null);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public Rectangle clone(
+    Document context
+    )
+  {throw new NotImplementedException();}
+
+  public double getBottom(
+    )
+  {return ((IPdfNumber)getBaseDataObject().get(1)).getNumberValue();}
+
+  public double getHeight(
+    )
+  {return getTop() - getBottom();}
+
+  public double getLeft(
+    )
+  {return getX();}
+
+  public double getRight(
+    )
+  {return ((IPdfNumber)getBaseDataObject().get(2)).getNumberValue();}
+
+  public double getTop(
+    )
+  {return getY();}
+
+  public double getWidth(
+    )
+  {return getRight() - getLeft();}
+
+  public double getX(
+    )
+  {return ((IPdfNumber)getBaseDataObject().get(0)).getNumberValue();}
+
+  public double getY(
+    )
+  {return ((IPdfNumber)getBaseDataObject().get(3)).getNumberValue();}
+
+  public void setBottom(
+    double value
+    )
+  {((IPdfNumber)getBaseDataObject().get(1)).setNumberValue(value);}
+
+  public void setHeight(
+    double value
+    )
+  {setBottom(getTop() - value);}
+
+  public void setLeft(
+    double value
+    )
+  {setX(value);}
+
+  public void setRight(
+    double value
+    )
+  {((IPdfNumber)getBaseDataObject().get(2)).setNumberValue(value);}
+
+  public void setTop(
+    double value
+    )
+  {setY(value);}
+
+  public void setWidth(
+    double value
+    )
+  {setRight(getLeft() + value);}
+
+  public void setX(
+    double value
+    )
+  {((IPdfNumber)getBaseDataObject().get(0)).setNumberValue(value);}
+
+  public void setY(
+    double value
+    )
+  {((IPdfNumber)getBaseDataObject().get(3)).setNumberValue(value);}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/package.html
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/package.html	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/objects/package.html	(revision 23703)
@@ -0,0 +1,37 @@
+<html>
+<head>
+<!--
+  Copyright 2006-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+-->
+</head>
+<body>
+<p>Primitive PDF object types [PDF:1.6:3.2], along with related extensions [PDF:1.6:3.8].</p>
+
+<h2>Related Documentation</h2>
+<p>For overviews, tutorials, examples, guides, and tool documentation, please see:</p>
+<ul>
+  <li><a href="http://clown.stefanochizzolini.it">PDF Clown Home Page</a>
+</ul>
+</body>
+</html>
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/package.html
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/package.html	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/package.html	(revision 23703)
@@ -0,0 +1,37 @@
+<html>
+<head>
+<!--
+  Copyright 2006-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+-->
+</head>
+<body>
+<p>Root namespace of PDF Clown library.</p>
+
+<h2>Related Documentation</h2>
+<p>For overviews, tutorials, examples, guides, and tool documentation, please see:</p>
+<ul>
+  <li><a href="http://clown.stefanochizzolini.it">PDF Clown Home Page</a>
+</ul>
+</body>
+</html>
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/tokens/FileFormatException.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/tokens/FileFormatException.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/tokens/FileFormatException.java	(revision 23703)
@@ -0,0 +1,83 @@
+/*
+  Copyright 2006 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.tokens;
+
+/**
+  Exception thrown in case of bad file format detection.
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+*/
+public class FileFormatException
+  extends Exception
+{
+  // <class>
+  // <static>
+  // <fields>
+  private static final long serialVersionUID = 1L;
+  // </fields>
+  // </static>
+  
+  // <dynamic>
+  // <fields>
+  private long position;
+  // </fields>
+
+  // <constructors>
+  public FileFormatException(
+    String message,
+    long position
+    )
+  {
+    super(message);
+
+    this.position = position;
+  }
+
+  public FileFormatException(
+    String message,
+    Throwable cause,
+    long position
+    )
+  {
+    super(message,cause);
+
+    this.position = position;
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  /**
+    Gets the file pointer position before which the exception has occurred.
+  */
+  public long getPosition(
+    )
+  {return position;}
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/tokens/Parser.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/tokens/Parser.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/tokens/Parser.java	(revision 23703)
@@ -0,0 +1,974 @@
+/*
+  Copyright 2006-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+    * Haakan Aakerberg (bugfix contributor):
+      - [FIX:0.0.4:1]
+      - [FIX:0.0.4:4]
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.tokens;
+
+import it.stefanochizzolini.clown.bytes.Buffer;
+import it.stefanochizzolini.clown.bytes.IInputStream;
+import it.stefanochizzolini.clown.files.File;
+import it.stefanochizzolini.clown.objects.PdfArray;
+import it.stefanochizzolini.clown.objects.PdfBoolean;
+import it.stefanochizzolini.clown.objects.PdfDataObject;
+import it.stefanochizzolini.clown.objects.PdfDate;
+import it.stefanochizzolini.clown.objects.PdfDictionary;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfInteger;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfReal;
+import it.stefanochizzolini.clown.objects.PdfReference;
+import it.stefanochizzolini.clown.objects.PdfStream;
+import it.stefanochizzolini.clown.objects.PdfString;
+import it.stefanochizzolini.clown.objects.PdfTextString;
+
+import java.io.Closeable;
+import java.io.EOFException;
+import java.io.IOException;
+import java.util.Date;
+
+/**
+  Token parser.
+  <h3>Contract</h3>
+  <ul>
+    <li>Preconditions:
+    <ol>
+      <li>(none).</li>
+    </ol>
+    </li>
+    <li>Postconditions:
+    <ol>
+      <li>(none).</li>
+    </ol>
+    </li>
+    <li>Invariants:
+    <ol>
+      <li>Stream data IS kept untouched.</li>
+    </ol>
+    </li>
+    <li>Side-effects:
+    <ol>
+      <li>(none).</li>
+    </ol>
+    </li>
+  </ul>
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8.2
+*/
+public class Parser
+  implements Closeable
+{
+  // <class>
+  // <classes>
+  public class Reference
+  {
+    // <class>
+    // <fields>
+    private final int generationNumber;
+    private final int objectNumber;
+    // </fields>
+
+    // <constructors>
+    private Reference(
+      int objectNumber,
+      int generationNumber
+      )
+    {
+      this.objectNumber = objectNumber;
+      this.generationNumber = generationNumber;
+    }
+    // </constructors>
+
+    // <interface>
+    // <public>
+    public int getGenerationNumber(
+      )
+    {return generationNumber;}
+
+    public int getObjectNumber(
+      )
+    {return objectNumber;}
+    // </public>
+    // </interface>
+    // </class>
+  }
+  // </classes>
+
+  // <static>
+  // <fields>
+  private static final String PdfHeader = "%PDF-";
+  // </fields>
+
+  // <interface>
+  // <protected>
+  /**
+    Evaluates whether a character is a delimiter [PDF:1.6:3.1.1].
+  */
+  protected static boolean isDelimiter(
+    int c
+    )
+  {return (c == '(' || c == ')' || c == '<' || c == '>' || c == '[' || c == ']' || c == '/' || c == '%');}
+
+  /**
+    Evaluates whether a character is an EOL marker [PDF:1.6:3.1.1].
+  */
+  protected static boolean isEOL(
+    int c
+    )
+  {return c == 10 || c == 13;}
+
+  /**
+    Evaluates whether a character is a white-space [PDF:1.6:3.1.1].
+  */
+  protected static boolean isWhitespace(
+    int c
+    )
+  {return c == 32 || isEOL(c) || c == 0 || c == 9 || c == 12;}
+  // </protected>
+  // </interface>
+  // </static>
+
+  // <dynamic>
+  // <fields>
+  private File file;
+  private IInputStream stream;
+  private Object token;
+  private TokenTypeEnum tokenType;
+
+  private boolean multipleTokenParsing;
+  // </fields>
+
+  // <constructors>
+  Parser(
+    IInputStream stream,
+    File file
+    )
+  {
+    this.stream = stream;
+    this.file = file;
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  public long getLength(
+    )
+  {return stream.getLength();}
+
+  public long getPosition(
+    )
+  {return stream.getPosition();}
+
+  public IInputStream getStream(
+    )
+  {return stream;}
+
+  /**
+    Gets the currently-parsed token.
+    @return The current token.
+  */
+  public Object getToken(
+    )
+  {return token;}
+
+  /**
+    Gets the currently-parsed token type.
+    @return The current token type.
+  */
+  public TokenTypeEnum getTokenType(
+    )
+  {return tokenType;}
+
+  public int hashCode(
+    )
+  {return stream.hashCode();}
+
+  /**
+    @param offset Number of tokens to be skipped before reaching the intended one.
+  */
+  public boolean moveNext(
+    int offset
+    ) throws FileFormatException
+  {
+    for(
+      int index = 0;
+      index < offset;
+      index++
+      )
+    {
+      if(!moveNext())
+        return false;
+    }
+
+    return true;
+  }
+
+  /**
+    Parse the next token [PDF:1.6:3.1].
+    <h3>Contract</h3>
+    <ul>
+     <li>Preconditions:
+      <ol>
+       <li>To properly parse the current token, the pointer MUST be just before its starting (leading whitespaces are ignored).</li>
+      </ol>
+     </li>
+     <li>Postconditions:
+      <ol>
+       <li id="moveNext_contract_post[0]">When this method terminates, the pointer IS at the last byte of the current token.</li>
+      </ol>
+     </li>
+     <li>Invariants:
+      <ol>
+       <li>The byte-level position of the pointer IS anytime (during token parsing) at the end of the current token (whereas the 'current token' represents the token-level position of the pointer).</li>
+      </ol>
+     </li>
+     <li>Side-effects:
+      <ol>
+       <li>See <a href="#moveNext_contract_post[0]">Postconditions</a>.</li>
+      </ol>
+     </li>
+    </ul>
+    @return Whether a new token was found.
+  */
+  public boolean moveNext(
+    ) throws FileFormatException
+  {
+    /*
+      NOTE: It'd be interesting to evaluate an alternative regular-expression-based
+      implementation...
+    */
+    StringBuilder buffer = null;
+    token = null;
+    int c = 0;
+
+    // Skip leading white-space characters [PDF:1.6:3.1.1].
+    try
+    {
+      do
+      {
+        c = stream.readUnsignedByte();
+      } while(isWhitespace(c)); // Keep goin' till there's a white-space character...
+    }
+    catch(EOFException e)
+    {return false;}
+
+    // Which character is it?
+    switch(c)
+    {
+      case '/': // Name [PDF:1.6:3.2.4].
+        tokenType = TokenTypeEnum.Name;
+
+        /*
+          NOTE: As name objects are atomic symbols uniquely defined by sequences of characters,
+          the bytes making up the name are never treated as text, so here they are just
+          passed through without unescaping.
+        */
+        buffer = new StringBuilder();
+        try
+        {
+          while(true)
+          {
+            c = stream.readUnsignedByte();
+            if(isDelimiter(c) || isWhitespace(c))
+              break;
+
+            buffer.append((char)c);
+          }
+        }
+        catch(EOFException e)
+        {throw new FileFormatException("Unexpected EOF (malformed name object).",e,stream.getPosition());}
+
+        stream.skip(-1); // Recover the first byte after the current token.
+        break;
+      case '0':
+      case '1':
+      case '2':
+      case '3':
+      case '4':
+      case '5':
+      case '6':
+      case '7':
+      case '8':
+      case '9':
+      case '.':
+      case '-':
+      case '+': // Number [PDF:1.6:3.2.2] | Indirect reference.
+        switch(c)
+        {
+          case '.': // Decimal point.
+            tokenType = TokenTypeEnum.Real;
+            break;
+          case '-':
+          case '+': // Signum.
+            tokenType = TokenTypeEnum.Integer; // By default (it may be real).
+            break;
+          default: // Digit.
+            if(multipleTokenParsing) // Plain number (multiple token parsing -- see indirect reference search).
+            {
+              tokenType = TokenTypeEnum.Integer; // By default (it may be real).
+            }
+            else // Maybe an indirect reference (postfix notation [PDF:1.6:3.2.9]).
+            {
+              /*
+                NOTE: We need to identify this pattern:
+                ref :=  { int int 'R' }
+              */
+              // Enable multiple token parsing!
+              // NOTE: This state MUST be disabled before returning.
+              multipleTokenParsing = true;
+
+              // 1. Object number.
+              // Try the possible object number!
+              stream.skip(-1); moveNext();
+              // Isn't it a valid object number?
+              if(tokenType != TokenTypeEnum.Integer)
+              {
+                // Disable multiple token parsing!
+                multipleTokenParsing = false;
+                return true;
+              }
+              // Assign object number!
+              int objectNumber = (Integer)token;
+              // Backup the recovery position!
+              long oldOffset = stream.getPosition();
+
+              // 2. Generation number.
+              // Try the possible generation number!
+              moveNext();
+              // Isn't it a valid generation number?
+              if(tokenType != TokenTypeEnum.Integer)
+              {
+                // Rollback!
+                stream.seek(oldOffset);
+                token = objectNumber; tokenType = TokenTypeEnum.Integer;
+                // Disable multiple token parsing!
+                multipleTokenParsing = false;
+                return true;
+              }
+              // Assign generation number!
+              int generationNumber = (Integer)token;
+
+              // 3. Reference keyword.
+              // Try the possible reference keyword!
+              moveNext();
+              // Isn't it a valid reference keyword?
+              if(tokenType != TokenTypeEnum.Reference)
+              {
+                // Rollback!
+                stream.seek(oldOffset);
+                token = objectNumber; tokenType = TokenTypeEnum.Integer;
+                // Disable multiple token parsing!
+                multipleTokenParsing = false;
+                return true;
+              }
+              token = new Reference(objectNumber,generationNumber);
+              // Disable multiple token parsing!
+              multipleTokenParsing = false;
+              return true;
+            }
+            break;
+        }
+
+        // Building the number...
+        buffer = new StringBuilder();
+        try
+        {
+          do
+          {
+            buffer.append((char)c);
+            c = stream.readUnsignedByte();
+            if(c == '.')
+              tokenType = TokenTypeEnum.Real;
+            else if(c < '0' || c > '9')
+              break;
+          } while(true);
+        }
+        catch(EOFException e)
+        {throw new FileFormatException("Unexpected EOF (malformed number object).",e,stream.getPosition());}
+
+        stream.skip(-1); // Recover the first byte after the current token.
+        break;
+      case '[': // Array (begin).
+        tokenType = TokenTypeEnum.ArrayBegin;
+        break;
+      case ']': // Array (end).
+        tokenType = TokenTypeEnum.ArrayEnd;
+        break;
+      case '<': // Dictionary (begin) | Hexadecimal string.
+        try
+        {c = stream.readUnsignedByte();}
+        catch(EOFException e)
+        {throw new FileFormatException("Unexpected EOF (isolated opening angle-bracket character).",e,stream.getPosition());}
+        // Is it a dictionary (2nd angle bracket [PDF:1.6:3.2.6])?
+        if(c == '<')
+        {
+          tokenType = TokenTypeEnum.DictionaryBegin;
+          break;
+        }
+
+        // Hexadecimal string (single angle bracket [PDF:1.6:3.2.3]).
+        tokenType = TokenTypeEnum.Hex;
+
+        // [FIX:0.0.4:4] It skipped after the first hexadecimal character, missing it.
+        buffer = new StringBuilder();
+        try
+        {
+          while(c != '>') // NOT string end.
+          {
+            buffer.append((char)c);
+
+            c = stream.readUnsignedByte();
+          }
+        }
+        catch(EOFException e)
+        {throw new FileFormatException("Unexpected EOF (malformed hex string).",e,stream.getPosition());}
+
+        break;
+      case '>': // Dictionary (end).
+        try
+        {c = stream.readUnsignedByte();}
+        catch(EOFException e)
+        {throw new FileFormatException("Unexpected EOF (malformed dictionary).",e,stream.getPosition());}
+        if(c != '>')
+          throw new FileFormatException("Malformed dictionary.",stream.getPosition());
+
+        tokenType = TokenTypeEnum.DictionaryEnd;
+
+        break;
+      case '(': // Literal string [PDF:1.6:3.2.3].
+        tokenType = TokenTypeEnum.Literal;
+
+        /*
+          NOTE: As literal objects are textual, their characters are unescaped when deserialized.
+        */
+        buffer = new StringBuilder();
+        int level = 0;
+        try
+        {
+          while(true)
+          {
+            c = stream.readUnsignedByte();
+            if(c == '(')
+              level++;
+            else if(c == ')')
+              level--;
+            else if(c == '\\')
+            {
+              boolean lineBreak = false;
+              c = stream.readUnsignedByte();
+              switch(c)
+              {
+                case 'n':
+                  c = '\n';
+                  break;
+                case 'r':
+                  c = '\r';
+                  break;
+                case 't':
+                  c = '\t';
+                  break;
+                case 'b':
+                  c = '\b';
+                  break;
+                case 'f':
+                  c = '\f';
+                  break;
+                case '(':
+                case ')':
+                case '\\':
+                  break;
+                case '\r':
+                  lineBreak = true;
+                  c = stream.readUnsignedByte();
+                  if(c != '\n')
+                    stream.skip(-1);
+                  break;
+                case '\n':
+                  lineBreak = true;
+                  break;
+                default:
+                {
+                  // Is it outside the octal encoding?
+                  if(c < '0' || c > '7')
+                    break;
+
+                  // Octal.
+                  int octal = c - '0';
+                  c = stream.readUnsignedByte();
+                  // Octal end?
+                  if(c < '0' || c > '7')
+                  {c = octal; stream.skip(-1); break;}
+                  octal = (octal << 3) + c - '0';
+                  c = stream.readUnsignedByte();
+                  // Octal end?
+                  if(c < '0' || c > '7')
+                  {c = octal; stream.skip(-1); break;}
+                  octal = (octal << 3) + c - '0';
+                  c = octal & 0xff;
+                  break;
+                }
+              }
+              if(lineBreak)
+                continue;
+            }
+            else if(c == '\r')
+            {
+              c = stream.readUnsignedByte();
+              if(c != '\n')
+              {c = '\n'; stream.skip(-1);}
+            }
+            if(level == -1)
+              break;
+
+            buffer.append((char)c);
+          }
+        }
+        catch(EOFException e)
+        {throw new FileFormatException("Unexpected EOF (malformed literal string).",e,stream.getPosition());}
+
+        break;
+      case 'R': // Indirect reference.
+        tokenType = TokenTypeEnum.Reference;
+
+        break;
+      case '%': // Comment [PDF:1.6:3.1.2].
+        tokenType = TokenTypeEnum.Comment;
+        
+        buffer = new StringBuilder();
+        try
+        {
+          while(true)
+          {
+          	c = stream.readUnsignedByte();
+          	if(isEOL(c))
+          		break;
+          	
+          	buffer.append((char)c);
+          }
+        }
+        catch(EOFException e)
+        {/* NOOP */}
+
+        break;
+      default: // Keyword object.
+        tokenType = TokenTypeEnum.Keyword;
+
+        buffer = new StringBuilder();
+        try
+        {
+          do
+          {
+            buffer.append((char)c);
+            c = stream.readUnsignedByte();
+          } while(!isDelimiter(c) && !isWhitespace(c));
+        }
+        catch(EOFException e)
+        {/* NOOP */}
+        stream.skip(-1); // Recover the first byte after the current token.
+
+        break;
+    }
+
+    if(buffer != null)
+    {
+      /*
+        Here we prepare the current token state.
+      */
+      // Which token type?
+      switch(tokenType)
+      {
+        case Keyword:
+          token = buffer.toString();
+          // Late recognition.
+          if(((String)token).equals("false")
+            || ((String)token).equals("true")) // Boolean.
+          {
+            tokenType = TokenTypeEnum.Boolean;
+            token = Boolean.parseBoolean((String)token);
+          }
+          else if(((String)token).equals("null")) // Null.
+          {
+            tokenType = TokenTypeEnum.Null;
+            token = null;
+          }
+          break;
+        case Comment:
+        case Hex:
+        case Name:
+          token = buffer.toString();
+          break;
+        case Literal:
+          token = buffer.toString();
+          // Late recognition.
+          if(((String)token).startsWith("D:")) // Date.
+          {
+            tokenType = TokenTypeEnum.Date;
+            token = PdfDate.toDate((String)token);
+          }
+          break;
+        case Integer:
+          token = Integer.parseInt(buffer.toString());
+          break;
+        case Real:
+          token = Float.parseFloat(buffer.toString());
+          break;
+      }
+    }
+
+    return true;
+  }
+
+  /**
+    Parse the current PDF object [PDF:1.6:3.2].
+    <h3>Contract</h3>
+    <ul>
+     <li>Preconditions:
+      <ol>
+       <li>When this method is invoked, the pointer MUST be at the first
+       token of the requested object.</li>
+      </ol>
+     </li>
+     <li>Postconditions:
+      <ol>
+       <li id="parsePdfObject_contract_post[0]">When this method terminates,
+       the pointer IS at the last token of the requested object.</li>
+      </ol>
+     </li>
+     <li>Invariants:
+      <ol>
+       <li>(none).</li>
+      </ol>
+     </li>
+     <li>Side-effects:
+      <ol>
+       <li>See <a href="#parsePdfObject_contract_post[0]">Postconditions</a>.</li>
+      </ol>
+     </li>
+    </ul>
+  */
+  public PdfDataObject parsePdfObject(
+    ) throws FileFormatException
+  {
+    /*
+      NOTE: Object parsing is intrinsically a sequential operation tied to the stream pointer.
+      Calls bound towards other classes are potentially disruptive for the predictability of
+      the position of the stream pointer, so we are forced to carefully keep track of our
+      current position in order to recover its proper state after any outbound call.
+    */
+  	do
+  	{
+	    // Which token type?
+	    switch(tokenType)
+	    {
+	      case Integer:
+	        return new PdfInteger((Integer)token);
+	      case Name:
+	        return new PdfName((String)token,true);
+	      case Reference:
+	        /*
+	          NOTE: Curiously, PDF references are the only primitive objects that require
+	          a file reference. That's because they deal with indirect objects, which are strongly
+	          coupled with the current state of the file: so, PDF references are the fundamental
+	          bridge between the token layer and the file layer.
+	        */
+	        return new PdfReference(
+	          (Reference)token,
+	          file
+	          );
+	      case Literal:
+	        try
+	        {
+	          return new PdfTextString(
+	            ((String)token).getBytes("ISO-8859-1")
+	            );
+	        }
+	        catch(Exception e)
+	        {throw new RuntimeException(e);}
+	      case DictionaryBegin:
+	        PdfDictionary dictionary = new PdfDictionary();
+	        // Populate the dictionary.
+	        while(true)
+	        {
+	          // Key.
+	          moveNext();
+	          if(tokenType == TokenTypeEnum.DictionaryEnd)
+	            break;
+	          PdfName key = (PdfName)parsePdfObject();
+	
+	          // Value.
+	          moveNext();
+	          PdfDirectObject value = (PdfDirectObject)parsePdfObject();
+	
+	          // Add the current entry to the dictionary!
+	          dictionary.put(key,value);
+	        }
+	
+	        int oldOffset = (int)stream.getPosition();
+	        moveNext();
+	        // Is this dictionary the header of a stream object [PDF:1.6:3.2.7]?
+	        if((tokenType == TokenTypeEnum.Keyword)
+	          && token.equals("stream")) // Stream.
+	        {
+	          // Keep track of current position!
+	          long position = stream.getPosition();
+	
+	          // Get the stream length!
+	          /*
+	            NOTE: Indirect reference resolution is an outbound call (stream pointer hazard!),
+	            so we need to recover our current position after it returns.
+	          */
+	          int length = ((PdfInteger)File.resolve(dictionary.get(PdfName.Length))).getRawValue();
+	
+	          // Come back to current position!
+	          stream.seek(position);
+	
+	          skipWhitespace();
+	
+	          // Copy the stream data to the instance!
+	          byte[] data = new byte[length];
+	          try
+	          {stream.read(data);}
+	          catch(EOFException e)
+	          {throw new FileFormatException("Unexpected EOF (malformed stream object).",e,stream.getPosition());}
+	
+	          moveNext(); // Postcondition (last token should be 'endstream' keyword).
+	
+	          return new PdfStream(
+	            dictionary,
+	            new Buffer(data)
+	            );
+	        }
+	        else // Simple dictionary.
+	        {
+	          stream.seek(oldOffset); // Restore postcondition (last token should be the dictionary end).
+	
+	          return dictionary;
+	        }
+	      case ArrayBegin:
+	        PdfArray array = new PdfArray();
+	        // Populate the array.
+	        while(true)
+	        {
+	          // Value.
+	          moveNext();
+	          if(tokenType == TokenTypeEnum.ArrayEnd)
+	            break;
+	
+	          // Add the current item to the array!
+	          array.add((PdfDirectObject)parsePdfObject());
+	        }
+	        return array;
+	      case Real:
+	        return new PdfReal((Float)token);
+	      case Boolean:
+	        return new PdfBoolean((Boolean)token);
+	      case Date:
+	        return new PdfDate((Date)token);
+	      case Hex:
+	        try
+	        {
+	          return new PdfString(
+	            (String)token,
+	            PdfString.SerializationModeEnum.Hex
+	            );
+	        }
+	        catch(Exception e)
+	        {throw new RuntimeException(e);}
+	      case Null:
+	        return null;
+	      case Comment:
+	      	// NOOP: Comments are simply ignored and skipped.
+	      	break;
+	      default:
+	        throw new RuntimeException("Unhandled type: " + tokenType);
+	    }
+  	} while(moveNext());
+
+  	return null;
+  }
+
+  /**
+    Retrieves the PDF version of the file [PDF:1.6:3.4.1].
+    <h3>Contract</h3>
+    <ul>
+     <li>Preconditions:
+      <ol>
+       <li>(none).</li>
+      </ol>
+     </li>
+     <li>Postconditions:
+      <ol>
+       <li>(none).</li>
+      </ol>
+     </li>
+     <li>Invariants:
+      <ol>
+       <li>(none).</li>
+      </ol>
+     </li>
+     <li>Side-effects:
+      <ol>
+       <li>The pointer is released at an undefined location.</li>
+      </ol>
+     </li>
+    </ul>
+  */
+  public String retrieveVersion(
+    ) throws FileFormatException
+  {
+    stream.seek(0);
+    String header;
+    try{header = stream.readString(10);}
+    catch(EOFException e){throw new FileFormatException("Unexpected EOF (malformed version data).",e,stream.getPosition());}
+    if(!header.startsWith(PdfHeader))
+      throw new FileFormatException("PDF header not found.",stream.getPosition());
+
+    return header.substring(PdfHeader.length(),PdfHeader.length() + 3);
+  }
+
+  /**
+    Retrieves the starting position of the last xref-table section.
+    @see #retrieveXRefOffset(long)
+  */
+  public long retrieveXRefOffset(
+    ) throws FileFormatException
+  {return retrieveXRefOffset(stream.getLength());}
+
+  /**
+    Retrieves the starting position of an xref-table section [PDF:1.6:3.4.4].
+    <h3>Contract</h3>
+    <ul>
+     <li>Preconditions:
+      <ol>
+       <li>(none).</li>
+      </ol>
+     </li>
+     <li>Postconditions:
+      <ol>
+       <li>(none).</li>
+      </ol>
+     </li>
+     <li>Invariants:
+      <ol>
+       <li>(none).</li>
+      </ol>
+     </li>
+     <li>Side-effects:
+      <ol>
+       <li>The pointer is released at an undefined location.</li>
+      </ol>
+     </li>
+    </ul>
+    @param offset Position of the EOF marker related to the section intended to be parsed.
+  */
+  public long retrieveXRefOffset(
+    long offset
+    ) throws FileFormatException
+  {
+    final int chunkSize = 1024; // [PDF:1.6:H.3.18].
+
+    // Move back before 'startxref' keyword!
+    long position = offset - chunkSize;
+    if (position < 0)
+    {position = 0;} // [FIX:0.0.4:1] It failed to deal with less-than-1024-byte-long PDF files.
+    stream.seek(position);
+
+    // Get 'startxref' keyword position!
+    int index;
+    try{index = stream.readString(chunkSize).lastIndexOf("startxref");}
+    catch(EOFException e){throw new FileFormatException("Unexpected EOF (malformed 'startxref' tag).",e,stream.getPosition());}
+    if(index < 0)
+      throw new FileFormatException("PDF startxref not found.",stream.getPosition());
+    // Go past the 'startxref' keyword!
+    stream.seek(position + index); moveNext();
+
+    // Get the xref offset!
+    moveNext();
+    if(tokenType != TokenTypeEnum.Integer)
+      throw new FileFormatException("PDF startxref malformed.",stream.getPosition());
+
+    return (Integer)token;
+  }
+
+  public void seek(
+    long position
+    )
+  {stream.seek(position);}
+
+  public void skip(
+    long offset
+    )
+  {stream.skip(offset);}
+
+  /**
+    Moves to the last whitespace after the current position in order to let read
+    the first non-whitespace.
+  */
+  public boolean skipWhitespace(
+    )
+  {
+    int b;
+    try
+    {
+      do
+      {b = stream.readUnsignedByte();} while(isWhitespace(b)); // Keep goin' till there's a white-space character...
+    }
+    catch(EOFException e)
+    {return false;}
+    stream.skip(-1); // Recover the last whitespace position.
+
+    return true;
+  }
+
+  // <Closeable>
+  public void close(
+    ) throws IOException
+  {
+    if(stream != null)
+    {
+      stream.close();
+      stream = null;
+    }
+  }
+  // </Closeable>
+  // </public>
+
+  // <protected>
+  @Override
+  protected void finalize(
+    ) throws Throwable
+  {
+    try
+    {close();}
+    finally
+    {super.finalize();}
+  }
+  // </protected>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/tokens/Reader.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/tokens/Reader.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/tokens/Reader.java	(revision 23703)
@@ -0,0 +1,260 @@
+/*
+  Copyright 2006-2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.tokens;
+
+import it.stefanochizzolini.clown.bytes.IInputStream;
+import it.stefanochizzolini.clown.files.File;
+import it.stefanochizzolini.clown.objects.PdfDictionary;
+import it.stefanochizzolini.clown.objects.PdfInteger;
+import it.stefanochizzolini.clown.objects.PdfName;
+
+import java.io.Closeable;
+import java.io.IOException;
+
+/**
+  PDF file reader.
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.7
+*/
+public class Reader
+  implements Closeable
+{
+  // <class>
+  // <dynamic>
+  // <fields>
+  private Parser parser;
+  // </fields>
+
+  // <constructors>
+  /**
+    For internal use only.
+  */
+  public Reader(
+    IInputStream stream,
+    File file
+    )
+  {
+    this.parser = new Parser(stream,file);
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  public int hashCode(
+    )
+  {return parser.hashCode();}
+
+  public Parser getParser(
+    )
+  {return parser;}
+
+  public PdfDictionary readTrailer(
+    ) throws FileFormatException
+  {
+    // Get the offset of the last xref-table section!
+    long xrefOffset = parser.retrieveXRefOffset();
+    // Go to the start of the last xref-table section!
+    parser.seek(xrefOffset); parser.moveNext();
+    if(!parser.getToken().equals("xref"))
+      throw new FileFormatException("'xref' keyword not found.",parser.getPosition());
+
+    // Searching the start of the last trailer...
+    while(true)
+    {
+      parser.moveNext();
+      if(parser.getTokenType() == TokenTypeEnum.Keyword)
+        break;
+      parser.moveNext();
+      int count = (Integer)parser.getToken();
+      parser.skip(count * 20);
+    }
+    if(!parser.getToken().equals("trailer"))
+      throw new FileFormatException("'trailer' keyword not found.",parser.getPosition());
+
+    // Get the last trailer!
+    parser.moveNext();
+    return (PdfDictionary)parser.parsePdfObject();
+  }
+
+  /**
+    Retrieves the xref-table.
+    @return The xref-table entries array.
+  */
+  public XRefEntry[] readXRefTable(
+    PdfDictionary trailer
+    ) throws FileFormatException
+  {
+    // 1. XRef-table.
+    // Get the xref-table size!
+    PdfInteger xrefTableSize = (PdfInteger)trailer.get(PdfName.Size);
+    // Allocate the xref-table array!
+    XRefEntry[] xrefEntries = new XRefEntry[xrefTableSize.getRawValue()];
+
+    // 2. Last xref-table section.
+    // Move to the start of the last xref-table section!
+    parser.seek(parser.retrieveXRefOffset());
+    // Parse the last xref-table section!
+    readXRefSection(xrefEntries);
+
+    // 3. Previous xref-table sections.
+    while(true)
+    {
+      // 1. Previous xref-table section.
+      // Get the previous xref-table section offset!
+      PdfInteger prevXRefOffset = (PdfInteger)trailer.get(PdfName.Prev);
+      if(prevXRefOffset == null)
+        break;
+      // Move to the start of the previous xref-table section!
+      parser.seek(prevXRefOffset.getRawValue());
+      // Parse the previous xref-table section!
+      readXRefSection(xrefEntries);
+
+      // 2. Previous trailer.
+      // Skip 'trailer' keyword!
+      parser.moveNext();
+      // Get the previous trailer!
+      trailer = (PdfDictionary)parser.parsePdfObject();
+    }
+
+    return xrefEntries;
+  }
+
+  public String readVersion(
+    ) throws FileFormatException
+  {
+    return parser.retrieveVersion();
+  }
+
+  // <Closeable>
+  public void close(
+    ) throws IOException
+  {
+    if(parser != null)
+    {
+      parser.close();
+      parser = null;
+    }
+  }
+  // </Closeable>
+  // </public>
+
+  // <protected>
+  @Override
+  protected void finalize(
+    ) throws Throwable
+  {
+    try
+    {close();}
+    finally
+    {super.finalize();}
+  }
+
+  protected void readXRefSection(
+    XRefEntry[] xrefEntries
+    ) throws FileFormatException
+  {
+    // Reach the start of the xref-table section!
+    parser.moveNext();
+    if(!((String)parser.getToken()).equals("xref"))
+      throw new FileFormatException("'xref' keyword not found.",parser.getPosition());
+
+    // Loop sequentially across the subsections inside the current xref-table section.
+    while(true)
+    {
+      /*
+        NOTE: Each iteration of this loop block represents the scanning
+        of one subsection.
+        We get its bounds (first and last object numbers within its range)
+        and then collect its entries.
+      */
+      // 1. First object number.
+      parser.moveNext();
+      // Have we reached the end of the xref-table section?
+      if((parser.getTokenType() == TokenTypeEnum.Keyword)
+          && ((String)parser.getToken()).equals("trailer"))
+        break;
+      // Is the current token type different from the expected one?
+      if(parser.getTokenType() != TokenTypeEnum.Integer)
+        throw new FileFormatException("Neither object number of the first object in this xref subsection nor end of xref section found.",parser.getPosition());
+      // Get the object number of the first object in this xref-table subsection!
+      int startObjectNumber = (Integer)parser.getToken();
+
+      // 2. Last object number.
+      parser.moveNext();
+      if(parser.getTokenType() != TokenTypeEnum.Integer)
+        throw new FileFormatException("Number of entries in this xref subsection not found.",parser.getPosition());
+      // Get the object number of the last object in this xref-table subsection!
+      int endObjectNumber = (Integer)parser.getToken() + startObjectNumber;
+
+      // 3. xref-table subsection entries.
+      for(
+        int index = startObjectNumber;
+        index < endObjectNumber;
+        index++
+        )
+      {
+        // Is the entry undefined?
+        if(xrefEntries[index] == null) // Undefined entry.
+        {
+          // 1. Get the indirect object offset!
+          parser.moveNext();
+          int offset = (Integer)parser.getToken();
+          // 2. Get the object generation number!
+          parser.moveNext();
+          int generation = (Integer)parser.getToken();
+          // 3. Get the usage tag!
+          parser.moveNext();
+          String usageToken = (String)parser.getToken();
+          XRefEntry.UsageEnum usage;
+          if(usageToken.equals("n"))
+            usage = XRefEntry.UsageEnum.InUse;
+          else if(usageToken.equals("f"))
+            usage = XRefEntry.UsageEnum.Free;
+          else
+            throw new FileFormatException("Invalid xref entry.",parser.getPosition());
+
+          // 4. Entry initialization.
+          xrefEntries[index] = new XRefEntry(
+            index,
+            generation,
+            offset,
+            usage
+            );
+        }
+        else // Already-defined entry.
+        {
+          // Skip to the next entry!
+          parser.moveNext(3);
+        }
+      }
+    }
+  }
+  // </protected>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/tokens/TokenTypeEnum.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/tokens/TokenTypeEnum.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/tokens/TokenTypeEnum.java	(revision 23703)
@@ -0,0 +1,48 @@
+/*
+  Copyright 2006 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.tokens;
+
+/**
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+*/
+public enum TokenTypeEnum // [PDF:1.6:3.1].
+{
+  Keyword,
+  Boolean,
+  Integer,
+  Real,
+  Date,
+  Literal,
+  Hex,
+  Name,
+  Comment,
+  ArrayBegin,
+  ArrayEnd,
+  DictionaryBegin,
+  DictionaryEnd,
+  Reference,
+  Null
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/tokens/Writer.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/tokens/Writer.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/tokens/Writer.java	(revision 23703)
@@ -0,0 +1,302 @@
+/*
+  Copyright 2006-2009 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+    * Haakan Aakerberg (bugfix contributor):
+      - [FIX:0.0.4:5]
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.tokens;
+
+import it.stefanochizzolini.clown.bytes.IOutputStream;
+import it.stefanochizzolini.clown.files.File;
+import it.stefanochizzolini.clown.files.IndirectObjects;
+import it.stefanochizzolini.clown.objects.PdfDictionary;
+import it.stefanochizzolini.clown.objects.PdfIndirectObject;
+import it.stefanochizzolini.clown.objects.PdfInteger;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfReference;
+
+import java.util.Map;
+
+/**
+  PDF file writer.
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+*/
+public class Writer
+{
+  // <class>
+  // <static>
+  // <fields>
+  private static final byte[] HeaderBinaryHint = new byte[]{(byte)'%',(byte)0x80,(byte)0x80,(byte)0x80,(byte)0x80,(byte)'\r'}; // NOTE: Arbitrary binary characters (code >= 128) for ensuring proper behavior of file transfer applications [PDF:1.6:3.4.1].
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <fields>
+  private File file;
+  private IOutputStream stream;
+  // </fields>
+
+  // <constructors>
+  /**
+    For internal use only.
+  */
+  public Writer(
+    IOutputStream stream,
+    File file
+    )
+  {
+    this.stream = stream;
+    this.file = file;
+  }
+  // </constructors>
+
+  // <interface>
+  public IOutputStream getStream(
+    )
+  {return stream;}
+
+  /**
+    Serializes the PDF file compactly [PDF:1.6:3.4].
+  */
+  public void writeStandard(
+    )
+  {
+    StringBuilder xrefBuilder = new StringBuilder();
+    int xrefSize = file.getIndirectObjects().size();
+
+    // Header [PDF:1.6:3.4.1].
+    {
+      stream.write("%PDF-" + file.getDocument().getVersion() + "\r"); // NOTE: Document version represents the actual (possibly-overridden) file version.
+      stream.write(HeaderBinaryHint);
+    }
+
+    // Body [PDF:1.6:3.4.2].
+    {
+      /*
+        NOTE: A compact xref table comprises just one section composed by just one subsection.
+        NOTE: As xref-table free entries MUST be arrayed as a linked list,
+        it's needed to cache intermingled in-use entries in order to properly render
+        the object number of the next free entry inside the previous one.
+      */
+      StringBuilder xrefInUseBlockBuilder = new StringBuilder();
+      IndirectObjects indirectObjects = file.getIndirectObjects();
+      PdfReference freeReference = indirectObjects.get(0).getReference(); // Initialized to the first free entry.
+      for(
+        int index = 1;
+        index < xrefSize;
+        index++
+        )
+      {
+        PdfIndirectObject indirectObject = indirectObjects.get(index);
+        // Is the object entry in use?
+        if(indirectObject.isInUse()) // In-use entry.
+        {
+          // Indirect object.
+          // Append to the xref table its xref!
+          xrefInUseBlockBuilder.append(
+            indirectObject.getReference().getCrossReference(
+              stream.getLength()
+              )
+            );
+          // Serialize its content!
+          indirectObject.writeTo(stream);
+        }
+        else // Free entry.
+        {
+          // Flush current xref-table cache!
+          xrefBuilder.append(
+            freeReference.getCrossReference(index)
+              + xrefInUseBlockBuilder.toString()
+            );
+          // Initialize next xref-table subsection!
+          xrefInUseBlockBuilder.setLength(0);
+          freeReference = indirectObject.getReference();
+        }
+      }
+      // Flush current xref-table cache!
+      xrefBuilder.append(
+        freeReference.getCrossReference(0)
+          + xrefInUseBlockBuilder.toString()
+        );
+    }
+
+    // XRef table (unique section) [PDF:1.6:3.4.3]...
+    long startxref = stream.getLength();
+    {
+      // ...header.
+      stream.write(
+        "xref\r"
+          + "0 " + xrefSize + "\r"
+        );
+      // ...body.
+      stream.write(xrefBuilder.toString());
+    }
+
+    // Trailer [PDF:1.6:3.4.4]...
+    {
+      // ...header.
+      stream.write("trailer\r");
+      // ...body.
+      // Update the counter!
+      PdfDictionary trailer = file.getTrailer();
+      trailer.put(PdfName.Size,new PdfInteger(xrefSize));
+      trailer.remove(PdfName.Prev); // [FIX:0.0.4:5] It (wrongly) kept the 'Prev' entry of multiple-section xref tables.
+      // Serialize the contents!
+      trailer.writeTo(stream);
+      // ...tail.
+      stream.write(
+        "\r"
+          + "startxref\r"
+          + startxref + "\r"
+          + "%%EOF"
+        );
+    }
+  }
+
+  /**
+    Serializes the PDF file as incremental update [PDF:1.6:3.4.5].
+  */
+  public void writeIncremental(
+    )
+  {
+    StringBuilder xrefBuilder = new StringBuilder();
+    int xrefSize = file.getIndirectObjects().size();
+    Parser parser = file.getReader().getParser();
+
+    // Original content.
+    stream.write(parser.getStream());
+
+    // Body update.
+    {
+      /*
+        NOTE: incremental xref table comprises multiple sections each one composed by multiple
+        subsections.
+      */
+      // Insert modified indirect objects.
+      StringBuilder xrefSubBuilder = new StringBuilder(); // xref-table subsection builder.
+      int xrefSubCount = 0; // xref-table subsection counter.
+      int prevKey = 0; // Previous-entry object number.
+      for(
+        Map.Entry<Integer,PdfIndirectObject> indirectObjectEntry
+          : file.getIndirectObjects().getModifiedObjects().entrySet()
+        )
+      {
+        // Is the object in the current subsection?
+        /*
+          NOTE: to belong to the current subsection, the object entry MUST be contiguous with the
+          previous (condition 1) or the iteration has to have been just started (condition 2).
+       */
+        if(indirectObjectEntry.getKey() - prevKey == 1
+          || prevKey == 0) // Current subsection continues.
+        {
+          xrefSubCount++;
+        }
+        else // Current subsection terminates.
+        {
+          // Flush current xref-table subsection!
+          xrefBuilder.append(
+            (prevKey - xrefSubCount + 1) + " " + xrefSubCount + "\r"
+              + xrefSubBuilder.toString()
+            );
+          // Initialize next xref-table subsection!
+          xrefSubBuilder.setLength(0);
+          xrefSubCount = 1;
+        }
+
+        prevKey = indirectObjectEntry.getKey();
+
+        // Modified indirect object.
+        if(indirectObjectEntry.getValue().isInUse()) // In-use entry.
+        {
+          // Append to the current xref-table subsection its xref!
+          xrefSubBuilder.append(
+            indirectObjectEntry.getValue().getReference().getCrossReference(
+              stream.getLength()
+              )
+            );
+          // Serialize its content!
+          indirectObjectEntry.getValue().writeTo(stream);
+        }
+        else // Free entry.
+        {
+          // Append to the current xref-table subsection its xref!
+          /*
+            NOTE: We purposely neglect the linked list of free entries
+            (see IndirectObjects.remove(int)),
+            so that this entry links directly back to object number 0,
+            having a generation number of 65535 (not reusable) [PDF:1.6:3.4.3].
+          */
+          xrefSubBuilder.append(
+            indirectObjectEntry.getValue().getReference().getCrossReference(0)
+            );
+        }
+      }
+      // Flush current xref-table subsection!
+      xrefBuilder.append(
+        (prevKey - xrefSubCount + 1) + " " + xrefSubCount + "\r"
+          + xrefSubBuilder.toString()
+        );
+    }
+
+    // XRef-table last section...
+    long startxref = stream.getLength();
+    {
+      // ...header.
+      stream.write("xref\r");
+      // ...body.
+      stream.write(xrefBuilder.toString());
+    }
+
+    // Updated trailer...
+    try
+    {
+      // ...header.
+      stream.write("trailer\r");
+      // ...body.
+      // Update the entries!
+      PdfDictionary trailer = file.getTrailer();
+      trailer.put(PdfName.Size,new PdfInteger(xrefSize));
+      trailer.put(PdfName.Prev,new PdfInteger((int)parser.retrieveXRefOffset()));
+      // Serialize the contents!
+      trailer.writeTo(stream);
+      // ...tail.
+      stream.write(
+        "\r"
+          + "startxref\r"
+          + startxref + "\r"
+          + "%%EOF"
+        );
+    }
+    catch(Exception e)
+    {
+      // Propagate the exception!
+      throw new RuntimeException(e);
+    }
+  }
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/tokens/XRefEntry.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/tokens/XRefEntry.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/tokens/XRefEntry.java	(revision 23703)
@@ -0,0 +1,139 @@
+/*
+  Copyright 2006-2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.tokens;
+
+/**
+  Cross-reference table entry [PDF:1.6:3.4.3].
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.7
+*/
+public class XRefEntry
+{
+  // <class>
+  // <classes>
+  /**
+    Cross-reference table entry usage [PDF:1.6:3.4.3].
+  */
+  public enum UsageEnum
+  {
+    Undefined,
+    Free,
+    InUse
+  }
+  // </classes>
+
+  // <static>
+  // <fields>
+  /**
+    Unreusable generation [PDF:1.6:3.4.3].
+  */
+  public static final int GenerationUnreusable = 65535;
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <fields>
+  private int number; // Object number.
+  private int generation; // Object generation.
+  private int offset; // Indirect-object offset (in-use entry) | Next free-object object number (free entry).
+  private UsageEnum usage; // Entry usage.
+  // </fields>
+
+  // <constructors>
+  public XRefEntry(
+    int number,
+    int generation,
+    int offset,
+    UsageEnum usage
+    )
+  {
+    this.number = number;
+    this.generation = generation;
+    this.offset = offset;
+    this.usage = usage;
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  /**
+    Gets the generation number.
+  */
+  public int getGeneration(
+    )
+  {return generation;}
+
+  /**
+    Gets the object number.
+  */
+  public int getNumber(
+    )
+  {return number;}
+
+  /**
+    Gets the byte offset of the object data within the serialized file.
+  */
+  public int getOffset(
+    )
+  {return offset;}
+
+  /**
+    Gets the usage state.
+  */
+  public UsageEnum getUsage(
+    )
+  {return usage;}
+
+  /**
+    @see #getUsage()
+  */
+  public void setUsage(
+    UsageEnum value
+    )
+  {usage = value;}
+  // </public>
+
+  // <internal>
+  void setGeneration(
+    int value
+    )
+  {generation = value;}
+
+  void setNumber(
+    int value
+    )
+  {number = value;}
+
+  void setOffset(
+    int value
+    )
+  {offset = value;}
+  // </internal>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/tokens/package.html
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/tokens/package.html	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/tokens/package.html	(revision 23703)
@@ -0,0 +1,37 @@
+<html>
+<head>
+<!--
+  Copyright 2006-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+-->
+</head>
+<body>
+<p>PDF file serialization [PDF:1.6:3].</p>
+
+<h2>Related Documentation</h2>
+<p>For overviews, tutorials, examples, guides, and tool documentation, please see:</p>
+<ul>
+  <li><a href="http://clown.stefanochizzolini.it">PDF Clown Home Page</a>
+</ul>
+</body>
+</html>
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/tools/PageManager.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/tools/PageManager.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/tools/PageManager.java	(revision 23703)
@@ -0,0 +1,267 @@
+/*
+  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.tools;
+
+import it.stefanochizzolini.clown.documents.Document;
+import it.stefanochizzolini.clown.documents.Page;
+import it.stefanochizzolini.clown.documents.Pages;
+import it.stefanochizzolini.clown.files.File;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+/**
+  Tool for page management.
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.6
+  @since 0.0.6
+*/
+public class PageManager
+{
+  // <class>
+  // <dynamic>
+  // <fields>
+  private Document document;
+  private Pages pages;
+  // </fields>
+
+  // <constructors>
+  public PageManager(
+    )
+  {this(null);}
+
+  public PageManager(
+    Document document
+    )
+  {setDocument(document);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  /**
+    Appends a document to the end of the document.
+
+    @param document The document to add.
+  */
+  public void add(
+    Document document
+    )
+  {add((Collection<Page>)document.getPages());}
+
+  /**
+    Appends a collection of pages to the end of the document.
+
+    @param pages The pages to add.
+  */
+  @SuppressWarnings("unchecked")
+  public void add(
+    Collection<Page> pages
+    )
+  {
+    /*
+      NOTE: To be added to an alien document,
+      pages MUST be firstly contextualized into it,
+      then added to the target pages collection.
+    */
+    this.pages.addAll(
+      (Collection<Page>)this.document.contextualize(pages)
+      );
+    this.pages.update(); // NOTE: Update is fundamental to override original page collection.
+  }
+
+  /**
+    Inserts a document at the specified position in the document.
+
+    @param index Position at which the document is to be inserted.
+    @param document The document to be inserted.
+  */
+  public void add(
+    int index,
+    Document document
+    )
+  {add(index,(Collection<Page>)document.getPages());}
+
+  /**
+    Inserts a collection of pages at the specified position in the document.
+
+    @param index Position at which the pages are to be inserted.
+    @param pages The pages to be inserted.
+  */
+  @SuppressWarnings("unchecked")
+  public void add(
+    int index,
+    Collection<Page> pages
+    )
+  {
+    /*
+      NOTE: To be added to an alien document,
+      pages MUST be firstly contextualized into it,
+      then added to the target pages collection.
+    */
+    // Add the source pages to the document (contextualize)!
+    /* NOTE: Deep addition. */
+    Collection<Page> addingPages = (Collection<Page>)document.contextualize(pages);
+    // Add the source pages to the pages collection!
+    /* NOTE: Shallow addition. */
+    if(index >= this.pages.size())
+    {this.pages.addAll(addingPages);}
+    else
+    {this.pages.addAll(index,addingPages);}
+    this.pages.update(); // NOTE: Update is fundamental to override original page collection.
+  }
+
+  /**
+    Extracts a page range from the document.
+
+    @param beginIndex The beginning index, inclusive.
+    @param endIndex The ending index, exclusive.
+    @return Extracted page range.
+  */
+  @SuppressWarnings("unchecked")
+  public Document extract(
+    int beginIndex,
+    int endIndex
+    )
+  {
+    Document extractedDocument = new File().getDocument();
+
+    // Add the pages to the target file!
+    /*
+      NOTE: To be added to an alien document,
+      pages MUST be contextualized within it first,
+      then added to the target pages collection.
+    */
+    extractedDocument.getPages().addAll(
+      (Collection<Page>)extractedDocument.contextualize(
+        pages.subList(beginIndex,endIndex)
+        )
+      );
+
+    return extractedDocument;
+  }
+
+  /**
+    Moves a page range to a target position within the document.
+
+    @param beginIndex The beginning index, inclusive.
+    @param endIndex The ending index, exclusive.
+    @param targetIndex The target index.
+  */
+  public void move(
+    int beginIndex,
+    int endIndex,
+    int targetIndex
+    )
+  {
+    int pageCount = pages.size();
+
+    List<Page> movingPages = pages.subList(beginIndex,endIndex);
+
+    // Temporarily remove the pages from the pages collection!
+    /* NOTE: Shallow removal. */
+    pages.removeAll(movingPages);
+
+    // Adjust indexes!
+    pageCount -= movingPages.size();
+    if(targetIndex > beginIndex)
+    {targetIndex -= movingPages.size(); /* Adjusts the target position due to shifting for temporary page removal. */}
+
+    // Reinsert the pages at the target position!
+    /* NOTE: Shallow addition. */
+    if(targetIndex >= pageCount)
+    {pages.addAll(movingPages);}
+    else
+    {pages.addAll(targetIndex,movingPages);}
+    pages.update(); // NOTE: Update is fundamental to override original page collection.
+  }
+
+  /**
+    Gets the document being manipulated.
+  */
+  public Document getDocument(
+    )
+  {return document;}
+
+  /**
+    Removes a page range from the document.
+
+    @param beginIndex The beginning index, inclusive.
+    @param endIndex The ending index, exclusive.
+  */
+  public void remove(
+    int beginIndex,
+    int endIndex
+    )
+  {
+    List<Page> removingPages = pages.subList(beginIndex,endIndex);
+
+    // Remove the pages from the pages collection!
+    /* NOTE: Shallow removal. */
+    pages.removeAll(removingPages); pages.update();
+
+    // Remove the pages from the document (decontextualize)!
+    /* NOTE: Deep removal. */
+    document.decontextualize(removingPages);
+  }
+
+  /**
+    Sets the document to manipulate.
+  */
+  public void setDocument(
+    Document value
+    )
+  {
+    document = value;
+    pages = document.getPages();
+  }
+
+  /**
+    Splits the document into multiple single-paged documents.
+
+    @return A list of single-paged documents.
+  */
+  public List<Document> split(
+    )
+  {
+    List<Document> documents = new ArrayList<Document>();
+    for(Page page : pages)
+    {
+      Document pageDocument = new File().getDocument();
+      pageDocument.getPages().add(
+        (Page)page.clone(pageDocument)
+        );
+      documents.add(pageDocument);
+    }
+
+    return documents;
+  }
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/tools/PageStamper.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/tools/PageStamper.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/tools/PageStamper.java	(revision 23703)
@@ -0,0 +1,188 @@
+/*
+  Copyright 2007-2009 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.tools;
+
+import it.stefanochizzolini.clown.documents.Page;
+import it.stefanochizzolini.clown.documents.contents.Contents;
+import it.stefanochizzolini.clown.documents.contents.ContentScanner;
+import it.stefanochizzolini.clown.documents.contents.composition.PrimitiveFilter;
+import it.stefanochizzolini.clown.documents.contents.objects.RestoreGraphicsState;
+import it.stefanochizzolini.clown.documents.contents.objects.SaveGraphicsState;
+import it.stefanochizzolini.clown.files.File;
+import it.stefanochizzolini.clown.objects.PdfArray;
+import it.stefanochizzolini.clown.objects.PdfDataObject;
+import it.stefanochizzolini.clown.objects.PdfDirectObject;
+import it.stefanochizzolini.clown.objects.PdfName;
+import it.stefanochizzolini.clown.objects.PdfReference;
+import it.stefanochizzolini.clown.objects.PdfStream;
+
+/**
+  Tool for content insertion into existing pages.
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+*/
+public class PageStamper
+{
+  // <class>
+  // <dynamic>
+  // <fields>
+  private Page page;
+
+  private PrimitiveFilter background;
+  private PrimitiveFilter foreground;
+  // </fields>
+
+  // <constructors>
+  public PageStamper(
+    )
+  {this(null);}
+
+  public PageStamper(
+    Page page
+    )
+  {setPage(page);}
+  // </constructors>
+
+  // <interface>
+  // <public>
+  public void flush(
+    )
+  {
+    // Ensuring that there's room for the new content chunks inside the page's content stream...
+    /*
+      NOTE: This specialized stamper is optimized for content insertion without modifying
+      existing content representations, leveraging the peculiar feature of page structures
+      to express their content streams as arrays of data streams.
+    */
+    PdfArray streams;
+    {
+      PdfDirectObject contentsObject = page.getBaseDataObject().get(PdfName.Contents);
+      PdfDataObject contentsDataObject = File.resolve(contentsObject);
+      // Single data stream?
+      if(contentsDataObject instanceof PdfStream)
+      {
+        /*
+          NOTE: Content stream MUST be expressed as an array of data streams in order to host
+          background- and foreground-stamped contents.
+        */
+        streams = new PdfArray();
+        streams.add(contentsObject);
+        page.getBaseDataObject().put(PdfName.Contents,streams);
+
+        page.update(); // Fundamental to override original page contents collection.
+      }
+      else
+      {
+        streams = (PdfArray)contentsDataObject;
+
+        if(!File.update(contentsObject))
+        {page.update();} // Fundamental to override original page contents collection.
+      }
+    }
+
+    // Background.
+    // Serialize the content!
+    background.flush();
+    // Insert the serialized content into the page's content stream!
+    streams.add(
+      0,
+      (PdfReference)background.getScanner().getContents().getBaseObject()
+      );
+
+    // Foreground.
+    // Serialize the content!
+    foreground.flush();
+    // Append the serialized content into the page's content stream!
+    streams.add(
+      (PdfReference)foreground.getScanner().getContents().getBaseObject()
+      );
+  }
+
+  public PrimitiveFilter getBackground(
+    )
+  {return background;}
+
+  public PrimitiveFilter getForeground(
+    )
+  {return foreground;}
+
+  public Page getPage(
+    )
+  {return page;}
+
+  public void setPage(
+    Page value
+    )
+  {
+    page = value;
+    if(page == null)
+    {
+      background = null;
+      foreground = null;
+    }
+    else
+    {
+      // Background.
+      background = createFilter();
+      // Open the background local state!
+      background.add(SaveGraphicsState.Value);
+      // Close the background local state!
+      background.add(RestoreGraphicsState.Value);
+      // Open the middleground local state!
+      background.add(SaveGraphicsState.Value);
+      // Move into the background!
+      background.getScanner().move(1);
+
+      // Foregrond.
+      foreground = createFilter();
+      // Close the middleground local state!
+      foreground.add(RestoreGraphicsState.Value);
+    }
+  }
+  // </public>
+
+  // <private>
+  private PrimitiveFilter createFilter(
+    )
+  {
+    PdfReference reference = page.getFile().register(new PdfStream());
+
+    return new PrimitiveFilter(
+      new ContentScanner(
+        new Contents(
+          reference,
+          reference.getIndirectObject(),
+          page
+          )
+        )
+      );
+  }
+  // </private>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/tools/TextExtractor.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/tools/TextExtractor.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/tools/TextExtractor.java	(revision 23703)
@@ -0,0 +1,557 @@
+/*
+  Copyright 2009-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.tools;
+
+import it.stefanochizzolini.clown.documents.contents.Contents;
+import it.stefanochizzolini.clown.documents.contents.ContentScanner;
+import it.stefanochizzolini.clown.documents.contents.IContentContext;
+import it.stefanochizzolini.clown.documents.contents.ITextString;
+import it.stefanochizzolini.clown.documents.contents.TextChar;
+import it.stefanochizzolini.clown.documents.contents.TextStyle;
+import it.stefanochizzolini.clown.documents.contents.objects.ContainerObject;
+import it.stefanochizzolini.clown.documents.contents.objects.ContentObject;
+import it.stefanochizzolini.clown.documents.contents.objects.Text;
+
+import java.awt.geom.Rectangle2D;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+  Tool for extracting text from {@link IContentContext content contexts}.
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+  @since 0.0.8
+*/
+public class TextExtractor
+{
+  // <class>
+  // <classes>
+  /**
+    Text-to-area matching mode.
+  */
+  public enum AreaModeEnum
+  {
+    /**
+      Text string must be contained by the area.
+    */
+    Containment,
+    /**
+      Text string must intersect the area.
+    */
+    Intersection
+  }
+
+  /**
+    Text string.
+    <h3>Remarks</h3>
+    <p>This is typically used to assemble multiple raw text strings
+    laying on the same line.</p>
+  */
+  private static class TextString
+    implements ITextString
+  {
+    // <class>
+    // <dynamic>
+    // <fields>
+    private List<TextChar> textChars = new ArrayList<TextChar>();
+    // </fields>
+
+    // <interface>
+    // <public>
+    public Rectangle2D getBox(
+      )
+    {
+      Rectangle2D box = null;
+      for(TextChar textChar : textChars)
+      {
+        if(box == null)
+        {box = (Rectangle2D)textChar.box.clone();}
+        else
+        {box.add(textChar.box);}
+      }
+      return box;
+    }
+
+    public String getText(
+      )
+    {
+      StringBuilder textBuilder = new StringBuilder();
+      for(TextChar textChar : textChars)
+      {textBuilder.append(textChar);}
+      return textBuilder.toString();
+    }
+
+    public List<TextChar> getTextChars(
+      )
+    {return textChars;}
+    // </public>
+    // </interface>
+    // </dynamic>
+    // </class>
+  }
+
+  /**
+    Text string position comparator.
+   */
+  private static class TextStringPositionComparator
+    implements Comparator<ITextString>
+  {
+    // <class>
+    // <static>
+    /**
+      Gets whether the given boxes lay on the same text line.
+    */
+    public static boolean isOnTheSameLine(
+      Rectangle2D box1,
+      Rectangle2D box2
+      )
+    {
+      /*
+        NOTE: In order to consider the two boxes being on the same line,
+        we apply a simple rule of thumb: at least 25% of a box's height MUST
+        lay on the horizontal projection of the other one.
+      */
+      double minHeight = Math.min(box1.getHeight(), box2.getHeight());
+      double yThreshold = minHeight * .75;
+      return ((box1.getY() > box2.getY() - yThreshold
+          && box1.getY() < box2.getMaxY() + yThreshold - minHeight)
+        || (box2.getY() > box1.getY() - yThreshold
+          && box2.getY() < box1.getMaxY() + yThreshold - minHeight));
+    }
+    // </static>
+
+    // <dynamic>
+    // <Comparator>
+    public int compare(
+      ITextString textString1,
+      ITextString textString2
+      )
+    {
+      Rectangle2D box1 = textString1.getBox();
+      Rectangle2D box2 = textString2.getBox();
+      if(isOnTheSameLine(box1,box2))
+      {
+        if(box1.getX() < box2.getX())
+          return -1;
+        else if(box1.getX() > box2.getX())
+          return 1;
+        else
+          return 0;
+      }
+      else if(box1.getY() < box2.getY())
+        return -1;
+      else
+        return 1;
+    }
+    // </Comparator>
+    // </dynamic>
+    // </class>
+  }
+  // </classes>
+
+  // <dynamic>
+  // <fields>
+  private AreaModeEnum areaMode = AreaModeEnum.Containment;
+  private List<Rectangle2D> areas;
+  private double areaTolerance = 0;
+  private boolean sorted;
+  // </fields>
+
+  // <constructors>
+  public TextExtractor(
+    )
+  {this(true);}
+
+  public TextExtractor(
+    boolean sorted
+    )
+  {this(null,sorted);}
+
+  public TextExtractor(
+    List<Rectangle2D> areas,
+    boolean sorted
+    )
+  {
+    setAreas(areas);
+    setSorted(sorted);
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  /**
+    Extracts text strings from the given content context.
+
+    @param contentContext Source content context.
+  */
+  public Map<Rectangle2D,List<ITextString>> extract(
+    IContentContext contentContext
+    )
+  {
+    Map<Rectangle2D,List<ITextString>> extractedTextStrings;
+    {
+      List<ITextString> textStrings = new ArrayList<ITextString>();
+      {
+        // 1. Extract the source text strings!
+        List<ContentScanner.TextStringWrapper> rawTextStrings = new ArrayList<ContentScanner.TextStringWrapper>();
+        extract(
+          new ContentScanner(contentContext),
+          rawTextStrings
+          );
+
+        // 2. Sort the target text strings!
+        if(sorted)
+        {sort(rawTextStrings,textStrings);}
+        else
+        {textStrings.addAll(rawTextStrings);}
+      }
+
+      // 3. Filter the target text strings!
+      if(areas.isEmpty())
+      {
+        extractedTextStrings = new HashMap<Rectangle2D, List<ITextString>>();
+        extractedTextStrings.put(null, textStrings);
+      }
+      else
+      {extractedTextStrings = filter(textStrings,areas.toArray(new Rectangle2D[areas.size()]));}
+    }
+    return extractedTextStrings;
+  }
+
+  /**
+    Extracts text strings from the given contents.
+
+    @param contents Source contents.
+  */
+  public Map<Rectangle2D,List<ITextString>> extract(
+    Contents contents
+    )
+  {return extract(contents.getContentContext());}
+
+  /**
+    Extracts plain text from the given content context.
+
+    @param contentContext Source content context.
+  */
+  public String extractPlain(
+    IContentContext contentContext
+    )
+  {
+    StringBuilder textBuilder = new StringBuilder();
+    for(List<ITextString> textStrings : extract(contentContext).values())
+    {
+      if(textBuilder.length() > 0)
+      {textBuilder.append('\n'); /* Separates text belonging to different areas. */}
+
+      for(ITextString textString : textStrings)
+      {textBuilder.append(textString.getText() + '\n');}
+    }
+    return textBuilder.toString();
+  }
+
+  /**
+    Extracts plain text from the given contents.
+
+    @param contents Source contents.
+  */
+  public String extractPlain(
+    Contents contents
+    )
+  {return extractPlain(contents.getContentContext());}
+
+  /**
+    Gets the text strings matching the given area.
+
+    @param textStrings Text strings to filter, grouped by source area.
+    @param area Graphic area which text strings have to be matched to.
+  */
+  public List<ITextString> filter(
+    Map<Rectangle2D,List<ITextString>> textStrings,
+    Rectangle2D area
+    )
+  {return filter(textStrings,new Rectangle2D[]{area}).get(area);}
+
+  /**
+    Gets the text strings matching the given areas.
+
+    @param textStrings Text strings to filter, grouped by source area.
+    @param areas Graphic areas which text strings have to be matched to.
+  */
+  public Map<Rectangle2D,List<ITextString>> filter(
+    Map<Rectangle2D,List<ITextString>> textStrings,
+    Rectangle2D... areas
+    )
+  {
+    Map<Rectangle2D,List<ITextString>> filteredTextStrings = null;
+    for(List<ITextString> areaTextStrings : textStrings.values())
+    {
+      Map<Rectangle2D,List<ITextString>> filteredAreasTextStrings = filter(areaTextStrings,areas);
+      if(filteredTextStrings == null)
+      {filteredTextStrings = filteredAreasTextStrings;}
+      else
+      {
+        for(Map.Entry<Rectangle2D,List<ITextString>> filteredAreaTextStringsEntry : filteredAreasTextStrings.entrySet())
+        {filteredTextStrings.get(filteredAreaTextStringsEntry.getKey()).addAll(filteredAreaTextStringsEntry.getValue());}
+      }
+    }
+    return filteredTextStrings;
+  }
+
+  /**
+    Gets the text strings matching the given area.
+
+    @param textStrings Text strings to filter.
+    @param area Graphic area which text strings have to be matched to.
+  */
+  public List<ITextString> filter(
+    List<? extends ITextString> textStrings,
+    Rectangle2D area
+    )
+  {return filter(textStrings,new Rectangle2D[]{area}).get(area);}
+
+  /**
+    Gets the text strings matching the given areas.
+
+    @param textStrings Text strings to filter.
+    @param areas Graphic areas which text strings have to be matched to.
+  */
+  public Map<Rectangle2D,List<ITextString>> filter(
+    List<? extends ITextString> textStrings,
+    Rectangle2D... areas
+    )
+  {
+    Map<Rectangle2D,List<ITextString>> filteredAreasTextStrings = new HashMap<Rectangle2D,List<ITextString>>();
+    for(Rectangle2D area : areas)
+    {
+      List<ITextString> filteredAreaTextStrings = new ArrayList<ITextString>();
+      filteredAreasTextStrings.put(area, filteredAreaTextStrings);
+      Rectangle2D toleratedArea = (areaTolerance != 0
+        ? new Rectangle2D.Double(area.getX()-areaTolerance, area.getY()-areaTolerance, area.getWidth()+areaTolerance*2, area.getHeight()+areaTolerance*2)
+        : area);
+      for(ITextString textString : textStrings)
+      {
+        Rectangle2D textStringBox = textString.getBox();
+        if(toleratedArea.intersects(textStringBox))
+        {
+          TextString filteredTextString = new TextString();
+          List<TextChar> filteredTextStringChars = filteredTextString.getTextChars();
+          for(TextChar textChar : textString.getTextChars())
+          {
+            Rectangle2D textCharBox = textChar.box;
+            if((areaMode == AreaModeEnum.Containment && toleratedArea.contains(textCharBox))
+              || (areaMode == AreaModeEnum.Intersection && toleratedArea.intersects(textCharBox)))
+            {filteredTextStringChars.add(textChar);}
+          }
+          filteredAreaTextStrings.add(filteredTextString);
+        }
+      }
+    }
+    return filteredAreasTextStrings;
+  }
+
+  /**
+    Gets the text-to-area matching mode.
+   */
+  public AreaModeEnum getAreaMode(
+    )
+  {return areaMode;}
+
+  /**
+    Gets the graphic areas whose text has to be extracted.
+  */
+  public List<Rectangle2D> getAreas(
+    )
+  {return areas;}
+
+  /**
+    Gets the admitted outer area (in points) for containment matching purposes.
+    <h3>Remarks</h3>
+    <p>This measure is useful to ensure that text whose boxes overlap with the area bounds
+    is not excluded from the match.</p>
+   */
+  public double getAreaTolerance(
+    )
+  {return areaTolerance;}
+
+  /**
+    Gets whether the text strings have to be sorted.
+  */
+  public boolean isSorted(
+    )
+  {return sorted;}
+
+  /**
+    @see #getAreaMode()
+  */
+  public void setAreaMode(
+    AreaModeEnum value
+    )
+  {areaMode = value;}
+
+  /**
+    @see #getAreas()
+  */
+  public void setAreas(
+    List<Rectangle2D> value
+    )
+  {areas = (value == null ? new ArrayList<Rectangle2D>() : value);}
+
+  /**
+    @see #getAreaTolerance()
+  */
+  public void setAreaTolerance(
+    double value
+    )
+  {areaTolerance = value;}
+
+  /**
+    @see #isSorted()
+  */
+  public void setSorted(
+    boolean value
+    )
+  {sorted = value;}
+  // </public>
+
+  // <private>
+  /**
+    Scans a content level looking for text.
+  */
+  private void extract(
+    ContentScanner level,
+    List<ContentScanner.TextStringWrapper> extractedTextStrings
+    )
+  {
+    while(level.moveNext())
+    {
+      ContentObject content = level.getCurrent();
+      if(content instanceof Text)
+      {
+        // Collect the text strings!
+        extractedTextStrings.addAll(
+          ((ContentScanner.TextWrapper)level.getCurrentWrapper()).getTextStrings()
+          );
+      }
+      else if(content instanceof ContainerObject)
+      {
+        // Scan the inner level!
+        extract(
+          level.getChildLevel(),
+          extractedTextStrings
+          );
+      }
+    }
+  }
+
+  /**
+    Sorts the extracted text strings.
+    <h3>Remarks</h3>
+    <p>Sorting implies text position ordering, integration and aggregation.</p>
+
+    @param rawTextStrings Source (lower-level) text strings.
+    @param textStrings Target (higher-level) text strings.
+   */
+  private void sort(
+    List<ContentScanner.TextStringWrapper> rawTextStrings,
+    List<ITextString> textStrings
+    )
+  {
+    // Sorting the source text strings...
+    {
+      TextStringPositionComparator positionComparator = new TextStringPositionComparator();
+      Collections.sort(rawTextStrings, positionComparator);
+    }
+
+    // Aggregating and integrating the source text strings into the target ones...
+    TextString textString = null;
+    TextChar previousTextChar = null;
+    for(ContentScanner.TextStringWrapper rawTextString : rawTextStrings)
+    {
+      /*
+        NOTE: Contents on the same line are grouped together within the same text string.
+      */
+      // Add a new text string in case of new line!
+      if(textString == null
+        || (!textString.getTextChars().isEmpty()
+          && !TextStringPositionComparator.isOnTheSameLine(
+            textString.getBox(),
+            rawTextString.getBox())))
+      {
+        textStrings.add(textString = new TextString());
+        previousTextChar = null;
+      }
+
+      TextStyle textStyle = rawTextString.getStyle();
+      double spaceWidth = 0;
+      try
+      {spaceWidth = textStyle.font.getWidth(' ', textStyle.fontSize);}
+      catch(Exception e)
+      { /* Ignore. */ }
+      if(spaceWidth == 0)
+      {spaceWidth = textStyle.fontSize * .25; /* NOTE: as a rule of thumb, space width is estimated according to the font size. */}
+      for(TextChar textChar : rawTextString.getTextChars())
+      {
+        if(previousTextChar != null)
+        {
+          /*
+            NOTE: PDF files may have text contents omitting space characters,
+            so they must be inferred and synthesized, marking them as virtual
+            in order to allow the user to distinguish between original contents
+            and augmented ones.
+          */
+          double characterSpace = textChar.box.getX() - previousTextChar.box.getMaxX();
+          if(characterSpace >= spaceWidth)
+          {
+            // Add synthesized space character!
+            textString.textChars.add(
+              new TextChar(
+                ' ',
+                new Rectangle2D.Double(
+                  previousTextChar.box.getMaxX(),
+                  textChar.box.getY(),
+                  characterSpace,
+                  textChar.box.getHeight()
+                  ),
+                textStyle,
+                true
+                )
+              );
+          }
+        }
+        textString.textChars.add(previousTextChar = textChar);
+      }
+    }
+  }
+  // </private>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/tools/package.html
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/tools/package.html	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/tools/package.html	(revision 23703)
@@ -0,0 +1,37 @@
+<html>
+<head>
+<!--
+  Copyright 2008-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+-->
+</head>
+<body>
+<p>Specialized tools for performing common operations on PDF files.</p>
+
+<h2>Related Documentation</h2>
+<p>For overviews, tutorials, examples, guides, and tool documentation, please see:</p>
+<ul>
+  <li><a href="http://clown.stefanochizzolini.it">PDF Clown Home Page</a>
+</ul>
+</body>
+</html>
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/util/BiMap.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/util/BiMap.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/util/BiMap.java	(revision 23703)
@@ -0,0 +1,138 @@
+/*
+  Copyright 2009-2010 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.util;
+
+import java.util.Hashtable;
+import java.util.Map;
+
+/**
+  Bidirectional bijective map.
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+  @since 0.0.8
+*/
+public class BiMap<K,V>
+  extends Hashtable<K,V>
+{
+  // <class>
+  // <static>
+  // <fields>
+  private static final long serialVersionUID = 1L;
+  // </fields>
+  // </static>
+  
+  // <dynamic>
+  // <fields>
+  private Hashtable<V,K> inverseMap = new Hashtable<V,K>();
+  // </fields>
+
+  // <constructors>
+  public BiMap(
+    )
+  {super();}
+
+  public BiMap(
+    int initialCapacity
+    )
+  {super(initialCapacity);}
+
+  public BiMap(
+    Map<? extends K,? extends V> map
+    )
+  {
+    super();
+    putAll(map);
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public boolean contains(
+    Object value
+    )
+  {return containsValue(value);}
+
+  @Override
+  public boolean containsValue(
+    Object value
+    )
+  {return inverseMap.containsKey(value);}
+
+  public K getKey(
+    V value
+    )
+  {return inverseMap.get(value);}
+
+  @Override
+  public V put(
+    K key,
+    V value
+    )
+  {
+    V oldValue = super.put(key, value);
+    if(oldValue != null)
+    {inverseMap.remove(oldValue);}
+
+    inverseMap.put(value, key);
+
+    return oldValue;
+  }
+
+  @Override
+  public void putAll(Map<? extends K,? extends V> map)
+  {
+    if(map == null)
+      return;
+
+    for(Map.Entry<? extends K,? extends V> entry : map.entrySet())
+    {put(entry.getKey(),entry.getValue());}
+  }
+
+  public void putAllInverse(Map<? extends V,? extends K> map)
+  {
+    if(map == null)
+      return;
+
+    for(Map.Entry<? extends V,? extends K> entry : map.entrySet())
+    {put(entry.getValue(),entry.getKey());}
+  }
+
+  @Override
+  public V remove(Object key)
+  {
+    V value = super.remove(key);
+    if(value != null)
+    {inverseMap.remove(value);}
+
+    return value;
+  }
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/util/ByteArray.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/util/ByteArray.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/util/ByteArray.java	(revision 23703)
@@ -0,0 +1,78 @@
+/*
+  Copyright 2009 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.util;
+
+import java.util.Arrays;
+
+/**
+  Byte array.
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+  @since 0.0.8
+*/
+/*
+  NOTE: This class is useful when applied as map key.
+*/
+public final class ByteArray
+{
+  public final byte[] data; //TODO: yes, I know it's risky (temporary simplification)...
+
+  public ByteArray(byte[] data)
+  {this.data = Arrays.copyOf(data,data.length);}
+
+  @Override
+  public boolean equals(
+    Object object
+    )
+  {
+    if (!(object instanceof ByteArray))
+      return false;
+
+    return Arrays.equals(data,((ByteArray)object).data);
+  }
+
+  @Override
+  public int hashCode(
+    )
+  {return Arrays.hashCode(data);}
+
+  @Override
+  public String toString(
+    )
+  {
+    StringBuilder builder = new StringBuilder("[");
+    for(byte datum : data)
+    {
+      if(builder.length() > 1)
+      {builder.append(",");}
+
+      builder.append(datum & 0xFF);
+    }
+    builder.append("]");
+    return builder.toString();
+  }
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/util/ConvertUtils.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/util/ConvertUtils.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/util/ConvertUtils.java	(revision 23703)
@@ -0,0 +1,150 @@
+/*
+  Copyright 2009 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.util;
+
+import java.nio.ByteOrder;
+
+/**
+  Data convertion utility.
+  <h3>Remarks</h3>
+  <p>This class is a specialized adaptation from the original <a href="http://commons.apache.org/codec/">
+  Apache Commons Codec</a> project, licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">
+  Apache License, Version 2.0</a>.</p>
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @version 0.0.8
+  @since 0.0.8
+*/
+public class ConvertUtils
+{
+  // <class>
+  // <static>
+  // <fields>
+  private static final char[] HexDigits = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
+  // </fields>
+
+  // <interface>
+  // <public>
+  public static String byteArrayToHex(
+    byte[] data
+    )
+  {
+    int dataLength = data.length;
+    char[] out = new char[dataLength * 2];
+    for(
+      int dataIndex = 0,
+        outIndex = 0;
+      dataIndex < dataLength;
+      dataIndex++
+      )
+    {
+      out[outIndex++] = HexDigits[(0xF0 & data[dataIndex]) >>> 4];
+      out[outIndex++] = HexDigits[0x0F & data[dataIndex]];
+    }
+
+    return new String(out);
+  }
+
+  public static int byteArrayToInt(
+    byte[] data
+    )
+  {return byteArrayToInt(data,0,ByteOrder.BIG_ENDIAN);}
+
+  public static int byteArrayToInt(
+    byte[] data,
+    int index,
+    ByteOrder byteOrder
+    )
+  {return byteArrayToNumber(data,index,4,byteOrder);}
+
+  public static int byteArrayToNumber(
+    byte[] data,
+    int index,
+    int length,
+    ByteOrder byteOrder
+    )
+  {
+    int value = 0;
+    length = Math.min(length,data.length-index);
+    for(
+      int i = index,
+        endIndex = index+length;
+      i < endIndex;
+      i++
+      )
+    {value |= (data[i] & 0xff) << 8 * (byteOrder == ByteOrder.LITTLE_ENDIAN ? i-index : endIndex-i-1);}
+
+    return value;
+  }
+
+  public static byte[] hexToByteArray(
+    String data
+    )
+  {
+    char[] dataChars = data.toCharArray();
+    int dataLength = dataChars.length;
+    if((dataLength % 2) != 0)
+      throw new RuntimeException("Odd number of characters.");
+
+    byte[] out = new byte[dataLength / 2];
+    for(
+      int outIndex = 0,
+        dataIndex = 0;
+      dataIndex < dataLength;
+      outIndex++
+      )
+    {
+      out[outIndex] = (byte)((
+        toHexDigit(dataChars[dataIndex++]) << 4
+          | toHexDigit(dataChars[dataIndex++])
+          ) & 0xFF);
+    }
+
+    return out;
+  }
+
+  public static byte[] intToByteArray(
+    int data
+    )
+  {return new byte[]{(byte)(data >> 24), (byte)(data >> 16), (byte)(data >> 8), (byte)data};}
+  // </public>
+
+  // <private>
+  private static int toHexDigit(
+    char dataChar
+    )
+  {
+    int digit = Character.digit(dataChar, 16);
+    if(digit == -1)
+      throw new RuntimeException("Illegal hexadecimal character " + dataChar);
+
+    return digit;
+  }
+  // </private>
+  // </interface>
+  // </static>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/util/NotImplementedException.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/util/NotImplementedException.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/util/NotImplementedException.java	(revision 23703)
@@ -0,0 +1,71 @@
+/*
+  Copyright 2007 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.util;
+
+/**
+  Exception thrown to indicate that a block of code has not been implemented yet.
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.3
+  @version 0.0.3
+*/
+public class NotImplementedException
+  extends UnsupportedOperationException
+{
+  // <class>
+  // <static>
+  // <fields>
+  private static final long serialVersionUID = 1L;
+  // </fields>
+  // </static>
+
+  // <dynamic>
+  // <constructors>
+  public NotImplementedException(
+    )
+  {this(null,null);}
+
+  public NotImplementedException(
+    String message
+    )
+  {this(message,null);}
+
+  public NotImplementedException(
+    String message,
+    Throwable cause
+    )
+  {
+    super(
+      message == null ?
+        "There's work for you! You reached a code block that hasn't been implemented yet."
+        : message,
+      cause
+      );
+  }
+  // </constructors>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/util/math/LUDecomposition.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/util/math/LUDecomposition.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/util/math/LUDecomposition.java	(revision 23703)
@@ -0,0 +1,263 @@
+/*
+  Copyright 2007 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.util.math;
+
+/**
+  LU matrix decomposition.
+  <p>The LU decomposition is a lower triangular matrix L, an upper triangular matrix U,
+   and a permutation <code>size</code>-long pivot vector.</p>
+  <h3>Remarks</h3>
+  <p>This class is a specialized adaptation from the original <a href="http://math.nist.gov/javanumerics/jama/">JAMA</a>
+  (Java Matrix Package) project, brought to the public domain by The MathWorks, Inc. and the National Institute of Standards
+  and Technology.</p>
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.4
+  @version 0.0.4
+*/
+public final class LUDecomposition
+{
+  // <class>
+  // <dynamic>
+  /** Array for internal storage of decomposition. */
+  private double[][] data;
+
+  /** Matrix size. */
+  private int size;
+
+  /** Pivot sign. */
+  private int pivsign;
+
+  /** Internal storage of pivot vector. */
+  private int[] piv;
+
+  // <constructors>
+  /**
+    @param matrix Matrix to decompose.
+  */
+  public LUDecomposition(
+    SquareMatrix matrix
+    )
+  {
+    /*
+      NOTE: Use a "left-looking", dot-product, Crout/Doolittle algorithm.
+    */
+    this.data = ((SquareMatrix)matrix.clone()).getData();
+    this.size = matrix.getSize();
+
+    this.piv = new int[size];
+    for(int i = 0; i < size; i++)
+    {piv[i] = i;}
+
+    pivsign = 1;
+    double[] LUrowi;
+    double[] LUcolj = new double[size];
+
+    for(int j = 0; j < size; j++)
+    {
+      // Making a copy of the j-th column to localize references...
+      for(int i = 0; i < size; i++)
+      {LUcolj[i] = data[i][j];}
+
+      // Applying previous transformations...
+      for(int i = 0; i < size; i++)
+      {
+        LUrowi = data[i];
+
+        int kmax = Math.min(i,j);
+        double s = 0.0;
+        for(int k = 0; k < kmax; k++)
+        {s += LUrowi[k] * LUcolj[k];}
+
+        LUrowi[j] = LUcolj[i] -= s;
+      }
+
+      // Finding pivot and exchanging if necessary...
+      int p = j;
+      for(int i = j+1; i < size; i++)
+      {
+        if (Math.abs(LUcolj[i]) > Math.abs(LUcolj[p]))
+        {p = i;}
+      }
+
+      if(p != j)
+      {
+        for(int k = 0; k < size; k++)
+        {double t = data[p][k]; data[p][k] = data[j][k]; data[j][k] = t;}
+
+        int k = piv[p]; piv[p] = piv[j]; piv[j] = k;
+
+        pivsign = -pivsign;
+      }
+
+      // Computing multipliers...
+      if(j < size
+        & data[j][j] != 0.0)
+      {
+        for(
+          int i = j+1;
+          i < size;
+          i++
+          )
+        {data[i][j] /= data[j][j];}
+      }
+    }
+  }
+  // </constructors>
+
+  /**
+    Gets the determinant.
+  */
+  public double getDet(
+    )
+  {
+    double d = (double) pivsign;
+    for(int j = 0; j < size; j++)
+    {d *= data[j][j];}
+
+    return d;
+  }
+
+  /**
+    Gets the lower triangular factor.
+  */
+  public SquareMatrix getL(
+    )
+  {
+    SquareMatrix X = new SquareMatrix(size);
+    double[][] L = X.getData();
+    for(int i = 0; i < size; i++)
+    {
+      for(int j = 0; j < size; j++)
+      {
+        if(i > j)
+        {L[i][j] = data[i][j];}
+        else if(i == j)
+        {L[i][j] = 1.0;}
+        else
+        {L[i][j] = 0.0;}
+      }
+    }
+
+    return X;
+  }
+
+  /**
+    Gets the upper triangular factor.
+  */
+  public SquareMatrix getU(
+    )
+  {
+    SquareMatrix X = new SquareMatrix(size);
+    double[][] U = X.getData();
+    for(int i = 0; i < size; i++)
+    {
+      for(int j = 0; j < size; j++)
+      {
+        if(i <= j)
+        {U[i][j] = data[i][j];}
+        else
+        {U[i][j] = 0.0;}
+      }
+    }
+
+    return X;
+  }
+
+  /**
+    Gets the pivot permutation vector.
+  */
+  public int[] getPivot(
+    )
+  {
+    int[] pivot = new int[size];
+    for(int i = 0; i < size; i++)
+    {pivot[i] = piv[i];}
+
+    return pivot;
+  }
+
+  /**
+    Gets whether the matrix is non-singular.
+  */
+  public boolean isNonsingular(
+    )
+  {
+    for(int j = 0; j < size; j++)
+      if (data[j][j] == 0)
+        return false;
+
+    return true;
+  }
+
+  /**
+    Solves [this] * [return] = [target]
+    @param target Resulting matrix.
+    @return Solution.
+    @exception IllegalArgumentException Matrix sizes must agree.
+    @exception RuntimeException Matrix is singular.
+  */
+  public SquareMatrix solve(
+    SquareMatrix target
+    )
+  {
+      if (target.getSize() != size)
+         throw new IllegalArgumentException("Matrix size must agree.");
+      if (!this.isNonsingular())
+         throw new RuntimeException("Matrix is singular.");
+
+      // Copy right hand side with pivoting
+      SquareMatrix Xmat = target.getMatrix(piv,0);
+      double[][] X = Xmat.getData();
+
+      // Solve L*Y = target(piv,:)
+      for(int k = 0; k < size; k++)
+      {
+        for(int i = k+1; i < size; i++)
+        {
+          for(int j = 0; j < size; j++)
+          {X[i][j] -= X[k][j] * data[i][k];}
+        }
+      }
+
+      // Solve U*X = Y;
+      for(int k = size - 1; k >= 0; k--)
+      {
+         for(int j = 0; j < size; j++)
+         {X[k][j] /= data[k][k];}
+
+         for(int i = 0; i < k; i++)
+         {
+            for(int j = 0; j < size; j++)
+            {X[i][j] -= X[k][j] * data[i][k];}
+         }
+      }
+
+      return Xmat;
+   }
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/util/math/OperationUtils.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/util/math/OperationUtils.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/util/math/OperationUtils.java	(revision 23703)
@@ -0,0 +1,91 @@
+/*
+  Copyright 2009 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.util.math;
+
+/**
+  Specialized math operations.
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.8
+  @version 0.0.8
+*/
+public final class OperationUtils
+{
+  // <class>
+  // <static>
+  /**
+    Big-endian comparison.
+  */
+  public static int compare(
+    byte[] data1,
+    byte[] data2
+    )
+  {
+    for(
+      int index = 0,
+        length = data1.length;
+      index < length;
+      index++
+      )
+    {
+      switch((int)Math.signum((data1[index] & 0xff)-(data2[index] & 0xff)))
+      {
+        case -1:
+          return -1;
+        case 1:
+          return 1;
+      }
+    }
+    return 0;
+  }
+
+  /**
+    Big-endian increment.
+  */
+  public static void increment(
+    byte[] data
+    )
+  {increment(data, data.length-1);}
+
+  /**
+    Big-endian increment.
+  */
+  public static void increment(
+    byte[] data,
+    int position
+    )
+  {
+    if((data[position] & 0xff) == 255)
+    {
+      data[position] = 0;
+      increment(data, position-1);
+    }
+    else
+    {data[position]++;}
+  }
+  // </static>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/util/math/SquareMatrix.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/util/math/SquareMatrix.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/util/math/SquareMatrix.java	(revision 23703)
@@ -0,0 +1,415 @@
+/*
+  Copyright 2007 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.util.math;
+
+/**
+  Square matrix providing fundamental operations of linear algebra.
+  <h3>Remarks</h3>
+  <p>This class is a specialized adaptation from the original <a href="http://math.nist.gov/javanumerics/jama/">JAMA</a>
+  (Java Matrix Package) project, brought to the public domain by The MathWorks, Inc. and the National Institute of Standards
+  and Technology.</p>
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+  @since 0.0.4
+  @version 0.0.4
+*/
+public final class SquareMatrix
+  implements Cloneable
+{
+  // <class>
+  // <static>
+  /**
+    Gets the identity matrix.
+    @param size Matrix size.
+  */
+  public static SquareMatrix getIdentity(
+    int size
+    )
+  {
+    SquareMatrix matrix = new SquareMatrix(size);
+    double[][] matrixData = matrix.getData();
+    for(int i = 0; i < size; i++)
+    {
+      for(int j = 0; j < size; j++)
+      {matrixData[i][j] = (i == j ? 1.0 : 0.0);}
+    }
+
+    return matrix;
+  }
+
+  //TODO: implement if necessary!!!
+  /*
+    [return] = [matrix1] + [matrix2]
+    @param matrix1 1st addend matrix.
+    @param matrix2 2nd addend matrix.
+  */
+//   public static SquareMatrix sum(
+//     SquareMatrix matrix1,
+//     SquareMatrix matrix2
+//     )
+//   {
+//     checkSize(matrix1,matrix2);
+//
+//     SquareMatrix sumMatrix = new SquareMatrix(matrix1.size);
+//
+//     sum(matrix1.data,matrix2.data,sumMatrix.data);
+//
+//     return sumMatrix;
+//   }
+
+//   private static void checkSize(
+//     SquareMatrix matrix1,
+//     SquareMatrix matrix2
+//     )
+//   {
+//     if (matrix1.getSize() != matrix2.getSize())
+//       throw new IllegalArgumentException("SquareMatrix dimensions must agree.");
+//   }
+
+//   private static void sum(
+//     double[][] matrix1Data,
+//     double[][] matrix2Data,
+//     double[][] sumMatrixData
+//     )
+//   {
+//     for(int i = 0; i < matrix1Data.length; i++)
+//     {
+//       for(int j = 0; j < matrix1Data.length; j++)
+//       {sumMatrixData[i][j] = matrix1Data[i][j] + matrix2Data[i][j];}
+//     }
+//   }
+  // </static>
+
+  // <dynamic>
+  private double[][] data;
+  private int size;
+
+  // <constructors>
+  public SquareMatrix(
+    int size
+    )
+  {
+    this.size = size;
+    data = new double[size][size];
+  }
+
+  /**
+    Construct a matrix from a 2-D array.
+    @param data Two-dimensional array of doubles.
+    @exception IllegalArgumentException All rows must have the same length
+  */
+  public SquareMatrix(
+    double[][] data
+    )
+  {
+      size = data.length;
+      for(
+        int i = 0;
+        i < size;
+        i++
+        )
+      {
+         if (data[i].length != size)
+            throw new IllegalArgumentException("All rows must have the same length.");
+      }
+      this.data = data;
+   }
+  // </constructors>
+
+  public Object clone(
+    )
+  {
+    SquareMatrix clone = new SquareMatrix(size);
+    double[][] cloneData = clone.getData();
+    for(int i = 0; i < size; i++)
+    {
+      for(int j = 0; j < size; j++)
+      {cloneData[i][j] = data[i][j];}
+    }
+
+    return clone;
+  }
+
+  /**
+    Gets the internal two-dimensional array.
+  */
+  public double[][] getData(
+    )
+  {return data;}
+
+  /**
+    Gets a submatrix.
+    @param rowIndexes Array of row indices.
+    @param startColumnIndex Initial column index.
+    @exception  ArrayIndexOutOfBoundsException Submatrix indices
+  */
+  public SquareMatrix getMatrix(
+    int[] rowIndexes,
+    int startColumnIndex
+    )
+  {
+    SquareMatrix subMatrix = new SquareMatrix(rowIndexes.length);
+    double[][] subMatrixData = subMatrix.getData();
+    int endColumnIndex = startColumnIndex + rowIndexes.length - 1;
+    try
+    {
+      for(int i = 0; i < rowIndexes.length; i++)
+      {
+        for(int j = startColumnIndex; j <= endColumnIndex; j++)
+        {subMatrixData[i][j - startColumnIndex] = data[rowIndexes[i]][j];}
+      }
+    }
+    catch(ArrayIndexOutOfBoundsException e)
+    {throw new ArrayIndexOutOfBoundsException("Submatrix indices");}
+
+    return subMatrix;
+  }
+
+  /*
+    [this] = [this] + [matrix]
+    @param matrix Addend.
+  */
+//   public SquareMatrix sum(
+//     SquareMatrix matrix
+//     )
+//   {
+//     checkSize(matrix);
+//
+//     sum(data,matrix.data,data);
+//
+//     return this;
+//   }
+
+   /* C = data - B
+   @param B    another matrix
+   @return     data - B
+   */
+//    public SquareMatrix minus (SquareMatrix B) {
+//       checkSize(B);
+//       SquareMatrix X = new SquareMatrix(m,n);
+//       double[][] C = X.getData();
+//       for (int i = 0; i < m; i++) {
+//          for (int j = 0; j < n; j++) {
+//             C[i][j] = data[i][j] - B.data[i][j];
+//          }
+//       }
+//       return X;
+//    }
+
+   /* data = data - B
+   @param B    another matrix
+   @return     data - B
+   */
+//    public SquareMatrix minusEquals (SquareMatrix B) {
+//       checkSize(B);
+//       for (int i = 0; i < m; i++) {
+//          for (int j = 0; j < n; j++) {
+//             data[i][j] = data[i][j] - B.data[i][j];
+//          }
+//       }
+//       return this;
+//    }
+
+   /* Element-by-element multiplication, C = data.*B
+   @param B    another matrix
+   @return     data.*B
+   */
+//    public SquareMatrix arrayTimes (SquareMatrix B) {
+//       checkSize(B);
+//       SquareMatrix X = new SquareMatrix(m,n);
+//       double[][] C = X.getData();
+//       for (int i = 0; i < m; i++) {
+//          for (int j = 0; j < n; j++) {
+//             C[i][j] = data[i][j] * B.data[i][j];
+//          }
+//       }
+//       return X;
+//    }
+
+   /* Element-by-element multiplication in place, data = data.*B
+   @param B    another matrix
+   @return     data.*B
+   */
+//    public SquareMatrix arrayTimesEquals (SquareMatrix B) {
+//       checkSize(B);
+//       for (int i = 0; i < m; i++) {
+//          for (int j = 0; j < n; j++) {
+//             data[i][j] = data[i][j] * B.data[i][j];
+//          }
+//       }
+//       return this;
+//    }
+
+   /* Element-by-element right division, C = data./B
+   @param B    another matrix
+   @return     data./B
+   */
+//    public SquareMatrix arrayRightDivide (SquareMatrix B) {
+//       checkSize(B);
+//       SquareMatrix X = new SquareMatrix(m,n);
+//       double[][] C = X.getData();
+//       for (int i = 0; i < m; i++) {
+//          for (int j = 0; j < n; j++) {
+//             C[i][j] = data[i][j] / B.data[i][j];
+//          }
+//       }
+//       return X;
+//    }
+
+   /* Element-by-element right division in place, data = data./B
+   @param B    another matrix
+   @return     data./B
+   */
+//    public SquareMatrix arrayRightDivideEquals (SquareMatrix B) {
+//       checkSize(B);
+//       for (int i = 0; i < m; i++) {
+//          for (int j = 0; j < n; j++) {
+//             data[i][j] = data[i][j] / B.data[i][j];
+//          }
+//       }
+//       return this;
+//    }
+
+   /* Element-by-element left division, C = data.\B
+   @param B    another matrix
+   @return     data.\B
+   */
+//    public SquareMatrix arrayLeftDivide (SquareMatrix B) {
+//       checkSize(B);
+//       SquareMatrix X = new SquareMatrix(m,n);
+//       double[][] C = X.getData();
+//       for (int i = 0; i < m; i++) {
+//          for (int j = 0; j < n; j++) {
+//             C[i][j] = B.data[i][j] / data[i][j];
+//          }
+//       }
+//       return X;
+//    }
+
+   /* Element-by-element left division in place, data = data.\B
+   @param B    another matrix
+   @return     data.\B
+   */
+//    public SquareMatrix arrayLeftDivideEquals (SquareMatrix B) {
+//       checkSize(B);
+//       for (int i = 0; i < m; i++) {
+//          for (int j = 0; j < n; j++) {
+//             data[i][j] = B.data[i][j] / data[i][j];
+//          }
+//       }
+//       return this;
+//    }
+
+   /* Multiply a matrix by a scalar, C = s*data
+   @param s    scalar
+   @return     s*data
+   */
+//    public SquareMatrix times (double s) {
+//       SquareMatrix X = new SquareMatrix(m,n);
+//       double[][] C = X.getData();
+//       for (int i = 0; i < m; i++) {
+//          for (int j = 0; j < n; j++) {
+//             C[i][j] = s*data[i][j];
+//          }
+//       }
+//       return X;
+//    }
+
+   /* Multiply a matrix by a scalar in place, data = s*data
+   @param s    scalar
+   @return     replace data by s*data
+   */
+//    public SquareMatrix timesEquals (double s) {
+//       for (int i = 0; i < m; i++) {
+//          for (int j = 0; j < n; j++) {
+//             data[i][j] = s*data[i][j];
+//          }
+//       }
+//       return this;
+//    }
+
+   /* Linear algebraic matrix multiplication, data * B
+   @param B    another matrix
+   @return     SquareMatrix product, data * B
+   @exception  IllegalArgumentException SquareMatrix inner dimensions must agree.
+   */
+//    public SquareMatrix times (SquareMatrix B) {
+//       if (B.m != n) {
+//          throw new IllegalArgumentException("SquareMatrix inner dimensions must agree.");
+//       }
+//       SquareMatrix X = new SquareMatrix(m,B.n);
+//       double[][] C = X.getData();
+//       double[] Bcolj = new double[n];
+//       for (int j = 0; j < B.n; j++) {
+//          for (int k = 0; k < n; k++) {
+//             Bcolj[k] = B.data[k][j];
+//          }
+//          for (int i = 0; i < m; i++) {
+//             double[] Arowi = data[i];
+//             double s = 0;
+//             for (int k = 0; k < n; k++) {
+//                s += Arowi[k]*Bcolj[k];
+//             }
+//             C[i][j] = s;
+//          }
+//       }
+//       return X;
+//    }
+
+  /**
+    Gets the matrix determinant.
+  */
+  public double getDet(
+    )
+  {return (new LUDecomposition(this)).getDet();}
+
+  /**
+    Gets the matrix inverse.
+  */
+  public SquareMatrix getInverse(
+    )
+  {return solve(getIdentity(size));}
+
+  /**
+    Gets the matrix size.
+  */
+  public int getSize(
+    )
+  {return size;}
+
+ /**
+    Solves [this] * [return] = [target]
+
+    @param target Resulting matrix.
+    @return Solution.
+  */
+  public SquareMatrix solve(
+    SquareMatrix target
+    )
+  {return (new LUDecomposition(this)).solve(target);}
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/util/math/geom/Dimension.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/util/math/geom/Dimension.java	(revision 23703)
+++ /applications/editors/josm/plugins/pdfimport/src/it/stefanochizzolini/clown/util/math/geom/Dimension.java	(revision 23703)
@@ -0,0 +1,81 @@
+/*
+  Copyright 2007 Stefano Chizzolini. http://clown.stefanochizzolini.it
+
+  Contributors:
+    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)
+
+  This file should be part of the source code distribution of "PDF Clown library"
+  (the Program): see the accompanying README files for more info.
+
+  This Program is free software; you can redistribute it and/or modify it under the terms
+  of the GNU Lesser General Public License as published by the Free Software Foundation;
+  either version 3 of the License, or (at your option) any later version.
+
+  This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY,
+  either expressed or implied; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License along with this
+  Program (see README files); if not, go to the GNU website (http://www.gnu.org/licenses/).
+
+  Redistribution and use, with or without modification, are permitted provided that such
+  redistributions retain the above copyright notice, license and disclaimer, along with
+  this list of conditions.
+*/
+
+package it.stefanochizzolini.clown.util.math.geom;
+
+import java.awt.geom.Dimension2D;
+
+/**
+  Double-precision 2D dimension.
+
+  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
+*/
+public final class Dimension
+  extends Dimension2D
+{
+  // <class>
+  // <dynamic>
+  // <fields>
+  private double height;
+  private double width;
+  // </fields>
+
+  // <constructors>
+  public Dimension(
+    double width,
+    double height
+    )
+  {
+    this.width = width;
+    this.height = height;
+  }
+  // </constructors>
+
+  // <interface>
+  // <public>
+  @Override
+  public double getHeight(
+    )
+  {return height;}
+
+  @Override
+  public double getWidth(
+    )
+  {return width;}
+
+  @Override
+  public void setSize(
+    double width,
+    double height
+    )
+  {
+    this.width = width;
+    this.height = height;
+  }
+  // </public>
+  // </interface>
+  // </dynamic>
+  // </class>
+}
Index: /applications/editors/josm/plugins/pdfimport/src/pdfimport/LoadPdfDialog.java
===================================================================
--- /applications/editors/josm/plugins/pdfimport/src/pdfimport/LoadPdfDialog.java	(revision 23702)
+++ /applications/editors/josm/plugins/pdfimport/src/pdfimport/LoadPdfDialog.java	(revision 23703)
@@ -226,5 +226,5 @@
 
 		this.loadFileButton.setEnabled(false);
-		this.loadFileButton.setText(tr("Lading..."));
+		this.loadFileButton.setText(tr("Loading..."));
 
 
