How to split PDF based on bookmarks?

Q: How to split PDF based on bookmarks?
C#.NET is preferred although I can also use VB.NET
----

A: The following is a short sample code that illustrates how to split a
document based on bookmarks. You may want to use this code as a
starting point for your project:

class BookmarkSplit
{
static int max_bookmark_levels = 3;
static string output_path = "../../../../TestFiles/Output/";

static void CreateSplitList(PDFDoc doc, Bookmark item, SortedList
slist, int level)
{
  for (; item.IsValid(); item=item.GetNext())
  {
    Action action = item.GetAction();
    if (action.IsValid() && action.GetType() == Action.Type.e_GoTo) {
      Destination dest = action.GetDest();
      Page page = dest.GetPage();
      int page_idx = page.GetIndex();
      if (slist.ContainsKey(page_idx) == false) {
        slist.Add(page_idx, item.GetTitle());
      }
    }
    if (level<max_bookmark_levels && item.HasChildren()) {
      CreateSplitList(doc, item.GetFirstChild(), slist, level+1);
    }
  }
}

static void SplitByBookmarks(PDFDoc doc, Bookmark item)
{
SortedList slist = new SortedList();
CreateSplitList(doc, item, slist, 1);

// Now we have a sorted list of pages indexes
// whic can be used to split the source document.
if (slist.Count == 0)
{
  Console.WriteLine("No document bookmarks");
}

if (slist.ContainsKey(1) == false) {
  slist.Add(1, "First page");
}

int num_pages = doc.GetPagesCount();
if (slist.ContainsKey(num_pages) == false)
{
  slist.Add(num_pages, "Last page");
}

for (int i=1; i<slist.Count; ++i)
{
  int range_start = (int) slist.GetKey(i-1);
  int range_end = (int) slist.GetKey(i);
  string bookmark_title = (string) slist.GetByIndex(i-1);
  Console.WriteLine("Page Range {0:d}-{1:d} Title: {2}", range_start,
range_end, bookmark_title);

  PDFDoc new_doc = new PDFDoc();
  ArrayList copy_pages = new ArrayList();
  PageIterator itr = doc.PageFind(range_start);
  PageIterator end = doc.PageFind(range_end);
  for (; itr!=end; itr.Next()) {
    copy_pages.Add(itr.Current());
  }

  ArrayList imported_pages = new_doc.ImportPages(copy_pages);
  for (int j=0; j!=imported_pages.Count; ++j) {
    new_doc.PagePushBack((Page)imported_pages[j]);
  }

  string outname = string.Format("split_{0:d}_{1:d}.pdf", range_start,
range_end);
  //string outname = string.Format("split_{0:d}_{1:d}-{2}.pdf",
range_start, range_end, bookmark_title);
  new_doc.Save(output_path + outname, 0);
  new_doc.Close();
}
}

/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main(string[] args)
{
  PDFNet.Initialize();
  try {
    PDFDoc doc = new PDFDoc("C:/PDFReference16.pdf");
  doc.InitSecurityHandler();

  // Get the root bookmark...
  Bookmark root = doc.GetFirstBookmark();
  if (!root.IsValid()) Console.WriteLine("No bookmarks");

  SplitByBookmarks(doc, root);
  doc.Close();
}
catch (PDFNetException e)
{
  Console.WriteLine(e.Message);
}

PDFNet.Terminate();
Console.WriteLine("Done.");
}