Index: PdfDocument.cpp
===================================================================
--- PdfDocument.cpp	(revision 1467)
+++ PdfDocument.cpp	(working copy)
@@ -226,6 +226,11 @@
     return m_pPagesTree->CreatePage( rSize );
 }
 
+void PdfDocument::CreatePages( const std::vector<PdfRect>& vecSizes )
+{
+    m_pPagesTree->CreatePages( vecSizes );
+}
+
 void PdfDocument::EmbedSubsetFonts()
 {
 	m_fontCache.EmbedSubsetFonts();
Index: PdfDocument.h
===================================================================
--- PdfDocument.h	(revision 1467)
+++ PdfDocument.h	(working copy)
@@ -291,6 +291,17 @@
      */
     PdfPage* CreatePage( const PdfRect & rSize );
 
+
+    /** Creates several new page objects and inserts them into the internal
+     *  page tree. 
+     *  The created pages are owned by the PdfDocument
+     *  and will get deleted along with it!
+     *
+     *  \param vecSizes a vector PdfRect's specifying the size of the pages (i.e the /MediaBox key) in PDF Units
+     */
+    void CreatePages( const std::vector<PdfRect>& vecSizes );
+
+
     /** Appends another PdfDocument to this document
      *  \param rDoc the document to append
      *  \param bAppendAll specifies whether pages and outlines are appended too
Index: PdfPagesTree.cpp
===================================================================
--- PdfPagesTree.cpp	(revision 1467)
+++ PdfPagesTree.cpp	(working copy)
@@ -103,33 +103,33 @@
 }
 
 
-void PdfPagesTree::InsertPage( int inAfterPageNumber, PdfPage* inPage )
+void PdfPagesTree::InsertPage( int nAfterPageIndex, PdfPage* inPage )
 {
-    this->InsertPage( inAfterPageNumber, inPage->GetObject() );
+    this->InsertPage( nAfterPageIndex, inPage->GetObject() );
 }
 
-void PdfPagesTree::InsertPage( int nAfterPageNumber, PdfObject* pPage )
+void PdfPagesTree::InsertPage( int nAfterPageIndex, PdfObject* pPage )
 {
     bool bInsertBefore = false;
 
-    if( ePdfPageInsertionPoint_InsertBeforeFirstPage == nAfterPageNumber )
+    if( ePdfPageInsertionPoint_InsertBeforeFirstPage == nAfterPageIndex )
     {
         bInsertBefore = true;
-        nAfterPageNumber = 0;
+        nAfterPageIndex = 0;
     }
-    else if( nAfterPageNumber < 0 ) 
+    else if( nAfterPageIndex < 0 ) 
     {
         // Only ePdfPageInsertionPoint_InsertBeforeFirstPage is valid here
         PdfError::LogMessage( eLogSeverity_Information,
                               "Invalid argument to PdfPagesTree::InsertPage: %i (Only ePdfPageInsertionPoint_InsertBeforeFirstPage is valid here).",
-                              nAfterPageNumber );
+                              nAfterPageIndex );
         return;
     }
 
-    //printf("Fetching page node: %i\n", nAfterPageNumber);
+    //printf("Fetching page node: %i\n", nAfterPageIndex);
     PdfObjectList lstParents;
-    //printf("Searching page=%i\n", nAfterPageNumber );
-    PdfObject* pPageBefore = this->GetPageNode( nAfterPageNumber, this->GetRoot(), lstParents );
+    //printf("Searching page=%i\n", nAfterPageIndex );
+    PdfObject* pPageBefore = this->GetPageNode( nAfterPageIndex, this->GetRoot(), lstParents );
     
     //printf("pPageBefore=%p lstParents=%i\n", pPageBefore,lstParents.size() );
     if( !pPageBefore || lstParents.size() == 0 ) 
@@ -138,7 +138,7 @@
         {
             PdfError::LogMessage( eLogSeverity_Critical,
                                   "Cannot find page %i or page %i has no parents. Cannot insert new page.",
-                                  nAfterPageNumber, nAfterPageNumber );
+                                  nAfterPageIndex, nAfterPageIndex );
             return;
         }
         else
@@ -160,10 +160,58 @@
         InsertPageIntoNode( pParent, lstParents, nKidsIndex, pPage );
     }
 
-    m_cache.InsertPage( nAfterPageNumber );
+    m_cache.InsertPage( (bInsertBefore && nAfterPageIndex == 0) ? ePdfPageInsertionPoint_InsertBeforeFirstPage : nAfterPageIndex );
 }
 
+void PdfPagesTree::InsertPages( int nAfterPageIndex, const std::vector<PdfObject*>& vecPages )
+{
+    bool bInsertBefore = false;
+    if( ePdfPageInsertionPoint_InsertBeforeFirstPage == nAfterPageIndex )
+    {
+        bInsertBefore = true;
+        nAfterPageIndex = 0;
+    }
+    else if( nAfterPageIndex < 0 ) 
+    {
+        // Only ePdfPageInsertionPoint_InsertBeforeFirstPage is valid here
+        PdfError::LogMessage( eLogSeverity_Information,
+                              "Invalid argument to PdfPagesTree::InsertPage: %i (Only ePdfPageInsertionPoint_InsertBeforeFirstPage is valid here).",
+                              nAfterPageIndex );
+        return;
+    }
 
+    PdfObjectList lstParents;
+    PdfObject* pPageBefore = this->GetPageNode( nAfterPageIndex, this->GetRoot(), lstParents );
+    
+    if( !pPageBefore || lstParents.size() == 0 ) 
+    {
+        if( this->GetTotalNumberOfPages() != 0 ) 
+        {
+            PdfError::LogMessage( eLogSeverity_Critical,
+                                  "Cannot find page %i or page %i has no parents. Cannot insert new page.",
+                                  nAfterPageIndex, nAfterPageIndex );
+            return;
+        }
+        else
+        {
+            // We insert the first page into an empty pages tree
+            PdfObjectList lstPagesTree;
+            lstPagesTree.push_back( this->GetObject() );
+            // Use -1 as index to insert before the empty kids array
+            InsertPagesIntoNode( this->GetObject(), lstPagesTree, -1, vecPages );
+        }
+    }
+    else
+    {
+        PdfObject* pParent = lstParents.back();
+        int nKidsIndex = bInsertBefore  ? -1 : this->GetPosInKids( pPageBefore, pParent );
+
+        InsertPagesIntoNode( pParent, lstParents, nKidsIndex, vecPages );
+    }
+
+    m_cache.InsertPages( (bInsertBefore && nAfterPageIndex == 0) ? ePdfPageInsertionPoint_InsertBeforeFirstPage : nAfterPageIndex,  vecPages.size() );
+}
+
 PdfPage* PdfPagesTree::CreatePage( const PdfRect & rSize )
 {
     PdfPage* pPage = new PdfPage( rSize, GetRoot()->GetOwner() );
@@ -174,6 +222,21 @@
     return pPage;
 }
 
+void PdfPagesTree::CreatePages( const std::vector<PdfRect>& vecSizes )
+{
+    std::vector<PdfPage*> vecPages;
+    std::vector<PdfObject*> vecObjects;
+    for (std::vector<PdfRect>::const_iterator it = vecSizes.begin(); it != vecSizes.end(); ++it)
+    {
+        PdfPage* pPage = new PdfPage( (*it), GetRoot()->GetOwner() );
+        vecPages.push_back( pPage );
+        vecObjects.push_back( pPage->GetObject() );
+    }
+
+    InsertPages( this->GetTotalNumberOfPages() - 1, vecObjects );
+    m_cache.AddPageObjects( this->GetTotalNumberOfPages() - 1, vecPages );
+}
+
 void PdfPagesTree::DeletePage( int nPageNumber )
 {
     // Delete from cache
@@ -487,6 +550,64 @@
     pPage->GetDictionary().AddKey( PdfName("Parent"), pParent->Reference() );
 }
 
+void PdfPagesTree::InsertPagesIntoNode( PdfObject* pParent, const PdfObjectList & rlstParents, 
+                                       int nIndex, const std::vector<PdfObject*>& vecPages )
+{
+    if( !pParent || !vecPages.size() ) 
+    {
+        PODOFO_RAISE_ERROR( ePdfError_InvalidHandle );
+    }
+
+    // 1. Add the reference of the new page to the kids array of pParent
+    // 2. Increase count of every node in lstParents (which also includes pParent)
+    // 3. Add Parent key to the page
+
+    // 1. Add reference
+    const PdfArray oldKids = pParent->GetDictionary().GetKey( PdfName("Kids") )->GetArray();
+    PdfArray newKids;
+    newKids.reserve( oldKids.GetSize() + vecPages.size() );
+
+    bool bIsPushedIn = false;
+    int i=0;
+    for (PdfArray::const_iterator it=oldKids.begin(); it!=oldKids.end(); ++it, ++i ) 
+    {
+        if ( !bIsPushedIn && (nIndex < i) )    // Pushing before
+        {
+            for (std::vector<PdfObject*>::const_iterator itPages=vecPages.begin(); itPages!=vecPages.end(); ++itPages)
+            {
+                newKids.push_back( (*itPages)->Reference() );    // Push all new kids at once
+            }
+            bIsPushedIn = true;
+        }
+        newKids.push_back( *it );    // Push in the old kids
+    }
+
+    // If new kids are still not pushed in then they may be appending to the end
+    if ( !bIsPushedIn && ( (nIndex + 1) == oldKids.size()) ) 
+    {
+        for (std::vector<PdfObject*>::const_iterator itPages=vecPages.begin(); itPages!=vecPages.end(); ++itPages)
+        {
+            newKids.push_back( (*itPages)->Reference() );    // Push all new kids at once
+        }
+        bIsPushedIn = true;
+    }
+
+    pParent->GetDictionary().AddKey( PdfName("Kids"), newKids );
+ 
+
+    // 2. increase count
+    for ( PdfObjectList::const_reverse_iterator itParents = rlstParents.rbegin(); itParents != rlstParents.rend(); ++itParents )
+    {
+        this->ChangePagesCount( *itParents, vecPages.size() );
+    } 
+
+    // 3. add parent key to each of the pages
+    for (std::vector<PdfObject*>::const_iterator itPages=vecPages.begin(); itPages!=vecPages.end(); ++itPages)
+    {
+        (*itPages)->GetDictionary().AddKey( PdfName("Parent"), pParent->Reference() );
+    }
+}
+
 void PdfPagesTree::DeletePageFromNode( PdfObject* pParent, const PdfObjectList & rlstParents, 
                                        int nIndex, PdfObject* pPage )
 {
Index: PdfPagesTree.h
===================================================================
--- PdfPagesTree.h	(revision 1467)
+++ PdfPagesTree.h	(working copy)
@@ -90,24 +90,34 @@
     /** Inserts an existing page object into the internal page tree. 
      *	after the specified page number
      *
-     *  \param nAfterPageNumber an integer specifying after what page
+     *  \param nAfterPageIndex an integer specifying after what page
      *         - may be one of the special values from EPdfPageInsertionPoint.
      *         Pages are 0 based.
      *         
      *  \param pPage musst be a PdfObject with type /Page
      */
-    void InsertPage( int nAfterPageNumber, PdfObject* pPage );
+    void InsertPage( int nAfterPageIndex, PdfObject* pPage );
 
     /** Inserts an existing page object into the internal page tree. 
      *	after the specified page number
      *
-     *  \param nAfterPageNumber an integer specifying after what page
+     *  \param nAfterPageIndex an integer specifying after what page
      *         - may be one of the special values  from EPdfPageInsertionPoint.
      *         Pages are 0 based.
      *  \param pPage a PdfPage to be inserted, the PdfPage will not get owned by the PdfPagesTree
      */
-    void InsertPage( int nAfterPageNumber, PdfPage* pPage );
+    void InsertPage( int nAfterPageIndex, PdfPage* pPage );
 
+    /** Inserts a vector of page objects at once into the internal page tree
+     *  after the specified page index (zero based index)
+     *
+     *  \param nAfterPageIndex a zero based integer index specifying after what page to insert
+     *         - you need to pass ePdfPageInsertionPoint_InsertBeforeFirstPage if you want to insert before the first page.
+     *         
+     *  \param vecPages must be a vector of PdfObjects with type /Page
+     */
+    void InsertPages( int nAfterPageIndex, const std::vector<PdfObject*>& vecPages );
+
     /** Creates a new page object and inserts it into the internal
      *  page tree.
      *  The returned page is owned by the pages tree and will get deleted along
@@ -117,7 +127,18 @@
      *  \returns a pointer to a PdfPage object
      */
     PdfPage* CreatePage( const PdfRect & rSize );
-    
+
+    /** Creates several new page objects and inserts them into the internal
+     *  page tree.
+     *  The new pages are owned by the pages tree and will get deleted along
+     *  with it!
+	 *  Note: this function will attach all new pages onto the same page node
+	 *  which can cause the tree to be unbalanced if 
+     *
+     *  \param vecSize a vector of PdfRect specifying the size of each of the pages to create (i.e the /MediaBox key) in PDF units
+     */
+    void CreatePages( const std::vector<PdfRect>& vecSizes );
+
     /**  Delete the specified page object from the internal pages tree.
      *   It does NOT remove any PdfObjects from memory - just the reference from the tree
      *
@@ -185,6 +206,19 @@
     void InsertPageIntoNode( PdfObject* pNode, const PdfObjectList & rlstParents, 
                              int nIndex, PdfObject* pPage );
 
+     /**
+     * Insert a vector of page objects into a pages node
+     * Same as InsertPageIntoNode except that it allows for adding multiple pages at one time
+	 * Note that adding many pages onto the same node will create an unbalanced page tree
+     *
+     * @param pNode the pages node whete pPage is to be inserted
+     * @param rlstParents list of all (future) parent pages nodes in the pages tree
+     *                   of pPage
+     * @param nIndex index where pPage is to be inserted in pNode's kids array
+     * @param vecPages a vector of the page objects which are to be inserted
+     */
+    void InsertPagesIntoNode( PdfObject* pParent, const PdfObjectList & rlstParents, 
+                              int nIndex, const std::vector<PdfObject*>& vecPages );
     
     /**
      * Delete a page object from a pages node
@@ -197,7 +231,7 @@
      */
     void DeletePageFromNode( PdfObject* pNode, const PdfObjectList & rlstParents, 
                              int nIndex, PdfObject* pPage );
-    
+
     /**
      * Delete a single page node or page object from the kids array of pParent
      *
Index: PdfPagesTreeCache.cpp
===================================================================
--- PdfPagesTreeCache.cpp	(revision 1467)
+++ PdfPagesTreeCache.cpp	(working copy)
@@ -56,31 +56,53 @@
     PdfPage* pOldPage = GetPage( nIndex );
     delete pOldPage;
 
-    if( nIndex+1 > static_cast<int>(m_deqPageObjs.size()) )
+    if( nIndex >= static_cast<int>(m_deqPageObjs.size()) )
     {
-        m_deqPageObjs.resize( nIndex+1 );
+        m_deqPageObjs.resize( nIndex + 1 );
     }
 
     m_deqPageObjs[nIndex] = pPage;
 }
 
-void PdfPagesTreeCache::InsertPage( int nIndex ) 
+void PdfPagesTreeCache::AddPageObjects( int nIndex, std::vector<PdfPage*> vecPages )
 {
-    if( nIndex == ePdfPageInsertionPoint_InsertBeforeFirstPage ) 
+    if( nIndex + vecPages.size() >= static_cast<int>(m_deqPageObjs.size()) )
     {
-        m_deqPageObjs.push_front( NULL );
-    } 
-    else
+        m_deqPageObjs.resize( nIndex + vecPages.size() + 1 );
+    }
+    
+    for (size_t i=0; i<vecPages.size(); ++i)
     {
-        if( nIndex > static_cast<int>(m_deqPageObjs.size()) )
-        {
-            m_deqPageObjs.resize( nIndex );
-        }
-        
-        m_deqPageObjs.insert( m_deqPageObjs.begin() + nIndex, static_cast<PdfPage*>(NULL) );
+        // Delete any old pages if it is at the same position
+        PdfPage* pOldPage = GetPage( nIndex + i );
+        delete pOldPage;
+
+        // Assign the new page
+        m_deqPageObjs[nIndex + i]  = vecPages.at(i);
     }
 }
 
+void PdfPagesTreeCache::InsertPage( int nAfterPageIndex ) 
+{
+    const int nBeforeIndex = ( nAfterPageIndex == ePdfPageInsertionPoint_InsertBeforeFirstPage ) ? 0 : nAfterPageIndex+1;
+
+    if( nBeforeIndex >= static_cast<int>(m_deqPageObjs.size()) )
+        m_deqPageObjs.resize( nBeforeIndex + 1 );
+
+    m_deqPageObjs.insert( m_deqPageObjs.begin() + nBeforeIndex, static_cast<PdfPage*>(NULL) );
+}
+
+void PdfPagesTreeCache::InsertPages( int nAfterPageIndex, int nCount ) 
+{
+    const int nBeforeIndex = ( nAfterPageIndex == ePdfPageInsertionPoint_InsertBeforeFirstPage ) ? 0 : nAfterPageIndex+1;
+
+    if( nBeforeIndex+nCount >= static_cast<int>(m_deqPageObjs.size()) )
+        m_deqPageObjs.resize( nBeforeIndex + nCount + 1 );
+
+    for (int i=0; i<nCount; ++i)
+        m_deqPageObjs.insert( m_deqPageObjs.begin() + nBeforeIndex + i, static_cast<PdfPage*>(NULL) );
+}
+
 void PdfPagesTreeCache::DeletePage( int nIndex )
 {
     if( nIndex < 0 || nIndex >= static_cast<int>(m_deqPageObjs.size()) ) 
Index: PdfPagesTreeCache.h
===================================================================
--- PdfPagesTreeCache.h	(revision 1467)
+++ PdfPagesTreeCache.h	(working copy)
@@ -64,14 +64,32 @@
     virtual void AddPageObject( int nIndex, PdfPage* pPage );
 
     /**
+     * Add several PdfPage objects to the cache, replacing any existing at the given index
+     * @param nIndex zero based index of where the first page will be placed
+     * @param vecPages vector of the page objects to add
+     */
+    virtual void AddPageObjects( int nIndex, std::vector<PdfPage*> vecPages );
+
+    /**
      * A page was inserted into the pagestree,
      * therefore the cache has to be updated
      *
-     * @param nIndex index where the page was inserted
+     * @param nAfterPageIndex zero based index of the page we are inserting after
+	 *         - may be one of the special values  from EPdfPageInsertionPoint.
      */
-    virtual void InsertPage( int nIndex );
+    virtual void InsertPage( int nAfterPageIndex );
 
     /**
+     * Insert several pages into the pagestree, after the given index
+     * therefore the cache has to be updated
+     *
+     * @param nAfterPageIndex zero based index of the page we are inserting after
+	 *         - may be one of the special values  from EPdfPageInsertionPoint.
+     * @param nCount number of pages that were inserted
+     */
+    virtual void InsertPages( int nAfterPageIndex, int nCount );
+
+    /**
      * Delete a PdfPage from the cache
      * @param nIndex index of the page
      */
