Make GooList a template type

One more step towards getting rid of it completely.
diff --git a/cpp/poppler-font.cpp b/cpp/poppler-font.cpp
index d6daf39..4fceb30 100644
--- a/cpp/poppler-font.cpp
+++ b/cpp/poppler-font.cpp
@@ -217,7 +217,7 @@
 
     ++d->current_page;
 
-    GooList *items = d->font_info_scanner.scan(1);
+    GooList<FontInfo*> *items = d->font_info_scanner.scan(1);
     if (!items) {
         return std::vector<font_info>();
     }
@@ -225,7 +225,7 @@
     for (std::size_t i = 0; i < items->size(); ++i) {
         fonts[i] = font_info(*new font_info_private((FontInfo *)items->get(i)));
     }
-    deleteGooList<FontInfo>(items);
+    deleteGooList<FontInfo*>(items);
     return fonts;
 }
 
diff --git a/cpp/poppler-toc-private.h b/cpp/poppler-toc-private.h
index a8ea863..8560ca3 100644
--- a/cpp/poppler-toc-private.h
+++ b/cpp/poppler-toc-private.h
@@ -25,7 +25,8 @@
 
 #include <vector>
 
-class GooList;
+#include "goo/GooList.h"
+
 class Outline;
 class OutlineItem;
 
@@ -54,7 +55,7 @@
     toc_item_private& operator=(const toc_item_private &) = delete;
 
     void load(const OutlineItem *item);
-    void load_children(const GooList *items);
+    void load_children(const GooList<OutlineItem*> *items);
 
     std::vector<toc_item*> children;
     ustring title;
diff --git a/cpp/poppler-toc.cpp b/cpp/poppler-toc.cpp
index 666c650..091b34c 100644
--- a/cpp/poppler-toc.cpp
+++ b/cpp/poppler-toc.cpp
@@ -44,7 +44,7 @@
         return nullptr;
     }
 
-    const GooList *items = outline->getItems();
+    const GooList<OutlineItem*> *items = outline->getItems();
     if (!items || items->size() < 1) {
         return nullptr;
     }
@@ -74,7 +74,7 @@
     is_open = item->isOpen();
 }
 
-void toc_item_private::load_children(const GooList *items)
+void toc_item_private::load_children(const GooList<OutlineItem*> *items)
 {
     const int num_items = items->size();
     children.resize(num_items);
@@ -86,7 +86,7 @@
         children[i] = new_item;
 
         item->open();
-        const GooList *item_children = item->getKids();
+        const GooList<OutlineItem*> *item_children = item->getKids();
         if (item_children) {
             new_item->d->load_children(item_children);
         }
diff --git a/glib/poppler-action.cc b/glib/poppler-action.cc
index fffe588..b78d34f 100644
--- a/glib/poppler-action.cc
+++ b/glib/poppler-action.cc
@@ -580,7 +580,7 @@
 		 PopplerAction   *action,
 		 const LinkOCGState    *ocg_state)
 {
-	const GooList *st_list = ocg_state->getStateList();
+	const auto *st_list = ocg_state->getStateList();
 	bool    preserve_rb = ocg_state->getPreserveRB();
 	GList   *layer_state = nullptr;
 
diff --git a/glib/poppler-document.cc b/glib/poppler-document.cc
index 5e0cc08..3064893 100644
--- a/glib/poppler-document.cc
+++ b/glib/poppler-document.cc
@@ -2163,7 +2163,7 @@
 struct _PopplerIndexIter
 {
 	PopplerDocument *document;
-	const GooList *items;
+	const GooList<OutlineItem*> *items;
 	int index;
 };
 
@@ -2238,7 +2238,7 @@
 {
 	PopplerIndexIter *iter;
 	Outline *outline;
-	const GooList *items;
+	const GooList<OutlineItem*> *items;
 
 	outline = document->doc->getOutline();
 	if (outline == nullptr)
@@ -2401,7 +2401,7 @@
 
 struct _PopplerFontsIter
 {
-	GooList *items;
+	GooList<FontInfo*> *items;
 	int index;
 };
 
@@ -2632,7 +2632,7 @@
 
 	new_iter = g_slice_dup (PopplerFontsIter, iter);
 
-	new_iter->items = new GooList ();
+	new_iter->items = new GooList<FontInfo*> ();
 	for (std::size_t i = 0; i < iter->items->size(); i++) {
 		FontInfo *info = (FontInfo *)iter->items->get(i);
 		new_iter->items->push_back (new FontInfo (*info));
@@ -2653,13 +2653,13 @@
 	if (G_UNLIKELY (iter == nullptr))
 		return;
 
-	deleteGooList<FontInfo> (iter->items);
+	deleteGooList<FontInfo*> (iter->items);
 
 	g_slice_free (PopplerFontsIter, iter);
 }
 
 static PopplerFontsIter *
-poppler_fonts_iter_new (GooList *items)
+poppler_fonts_iter_new (GooList<FontInfo*> *items)
 {
 	PopplerFontsIter *iter;
 
@@ -2763,7 +2763,7 @@
 			int                n_pages,
 			PopplerFontsIter **iter)
 {
-	GooList *items;
+	GooList<FontInfo*> *items;
 
 	g_return_val_if_fail (iter != nullptr, FALSE);
 
diff --git a/glib/poppler-page.cc b/glib/poppler-page.cc
index a36d3bc..ec54950 100644
--- a/glib/poppler-page.cc
+++ b/glib/poppler-page.cc
@@ -636,7 +636,6 @@
   PDFRectangle poppler_selection;
   TextPage *text;
   SelectionStyle selection_style = selectionStyleGlyph;
-  GooList *list;
   GList *region = nullptr;
 
   poppler_selection.x1 = selection->x1;
@@ -658,7 +657,7 @@
     }
 
   text = poppler_page_get_text_page (page);
-  list = text->getSelectionRegion(&poppler_selection,
+  auto list = text->getSelectionRegion(&poppler_selection,
 				  selection_style, scale);
 
   for (std::size_t i = 0; i < list->size(); i++) {
@@ -725,7 +724,6 @@
   PDFRectangle poppler_selection;
   TextPage *text;
   SelectionStyle selection_style = selectionStyleGlyph;
-  GooList *list;
   cairo_region_t *region;
 
   poppler_selection.x1 = selection->x1;
@@ -747,7 +745,7 @@
     }
 
   text = poppler_page_get_text_page (page);
-  list = text->getSelectionRegion(&poppler_selection,
+  auto list = text->getSelectionRegion(&poppler_selection,
 				  selection_style, 1.0);
 
   region = cairo_region_create ();
@@ -2169,7 +2167,6 @@
   guint n_rects = 0;
   gdouble x1, y1, x2, y2;
   gdouble x3, y3, x4, y4;
-  GooList **word_list;
   int n_lines;
 
   g_return_val_if_fail (POPPLER_IS_PAGE (page), FALSE);
@@ -2183,14 +2180,14 @@
   selection.y2 = area->y2;
 
   text = poppler_page_get_text_page (page);
-  word_list = text->getSelectionWords (&selection, selectionStyleGlyph, &n_lines);
+  auto word_list = text->getSelectionWords (&selection, selectionStyleGlyph, &n_lines);
   if (!word_list)
           return FALSE;
 
   n_rects += n_lines - 1;
   for (i = 0; i < n_lines; i++)
     {
-      GooList *line_words = word_list[i];
+      auto *line_words = word_list[i];
       n_rects += line_words->size() - 1;
       for (std::size_t j = 0; j < line_words->size(); j++)
         {
@@ -2204,7 +2201,7 @@
 
   for (i = 0; i < n_lines; i++)
     {
-      GooList *line_words = word_list[i];
+      auto *line_words = word_list[i];
       for (std::size_t j = 0; j < line_words->size(); j++)
         {
           TextWordSelection *word_sel = (TextWordSelection *)line_words->get(j);
@@ -2350,7 +2347,6 @@
 {
   TextPage *text;
   PDFRectangle selection;
-  GooList **word_list;
   int n_lines;
   PopplerTextAttributes *attrs = nullptr;
   TextWord *word, *prev_word = nullptr;
@@ -2368,13 +2364,13 @@
   selection.y2 = area->y2;
 
   text = poppler_page_get_text_page (page);
-  word_list = text->getSelectionWords (&selection, selectionStyleGlyph, &n_lines);
+  auto word_list = text->getSelectionWords (&selection, selectionStyleGlyph, &n_lines);
   if (!word_list)
           return nullptr;
 
   for (i = 0; i < n_lines; i++)
     {
-      GooList *line_words = word_list[i];
+      auto *line_words = word_list[i];
       for (std::size_t j = 0; j < line_words->size(); j++)
         {
           TextWordSelection *word_sel = (TextWordSelection *)line_words->get(j);
diff --git a/goo/GooList.h b/goo/GooList.h
index 78685fe..172d0d7 100644
--- a/goo/GooList.h
+++ b/goo/GooList.h
@@ -31,7 +31,8 @@
 // GooList
 //------------------------------------------------------------------------
 
-class GooList : public std::vector<void *> {
+template <typename T>
+class GooList : public std::vector<T> {
 public:
 
   // Create an empty list.
@@ -45,18 +46,18 @@
   GooList& operator=(const GooList &other) = delete;
 
   // Zero cost conversion from std::vector
-  explicit GooList(const std::vector<void *>& vec) : std::vector<void *>(vec) {}
-  explicit GooList(std::vector<void *>&& vec) : std::vector<void *>(std::move(vec)) {}
+  explicit GooList(const std::vector<T>& vec) : std::vector<T>(vec) {}
+  explicit GooList(std::vector<T>&& vec) : std::vector<T>(std::move(vec)) {}
 
   // Return the <i>th element.
   // Assumes 0 <= i < length.
-  void *get(int i) const { return (*this)[i]; }
+  const T& get(int i) const { return (*this)[i]; }
 };
 
 template<typename T>
-inline void deleteGooList(GooList* list) {
+inline void deleteGooList(GooList<T>* list) {
   for (auto ptr : *list) {
-    delete static_cast<T *>(ptr);
+    delete ptr;
   }
   delete list;
 }
diff --git a/poppler/Annot.cc b/poppler/Annot.cc
index c17992f..29d8037 100644
--- a/poppler/Annot.cc
+++ b/poppler/Annot.cc
@@ -756,7 +756,7 @@
   fontPtSize = -1;
 
   if (da) {
-    GooList * daToks = new GooList();
+    GooList<GooString*> * daToks = new GooList<GooString*>();
     int i = FormFieldText::tokenizeDA(da, daToks, "Tf");
 
     if (i >= 1) {
@@ -786,7 +786,7 @@
         }
       }
     }
-    deleteGooList<GooString>(daToks);
+    deleteGooList<GooString*>(daToks);
   }
 }
 
@@ -4028,7 +4028,7 @@
     bool txField, bool forceZapfDingbats,
     XRef *xref, bool *addedDingbatsResource,
     bool password) {
-  GooList *daToks;
+  GooList<GooString*> *daToks;
   GooString *tok;
   GooString convertedText;
   const GfxFont *font;
@@ -4046,7 +4046,7 @@
   // parse the default appearance string
   tfPos = tmPos = -1;
   if (da) {
-    daToks = new GooList();
+    daToks = new GooList<GooString*>();
     i = 0;
     while (i < da->getLength()) {
       while (i < da->getLength() && Lexer::isSpace(da->getChar(i))) {
@@ -4117,7 +4117,7 @@
   }
   if (!font) {
     if (daToks) {
-      deleteGooList<GooString>(daToks);
+      deleteGooList<GooString*>(daToks);
     }
     return false;
   }
@@ -4425,7 +4425,7 @@
     appearBuf->append("EMC\n");
   }
   if (daToks) {
-    deleteGooList<GooString>(daToks);
+    deleteGooList<GooString*>(daToks);
   }
   if (freeText) {
     delete text;
@@ -4440,7 +4440,7 @@
 // Draw the variable text or caption for a field.
 bool AnnotAppearanceBuilder::drawListBox(const FormFieldChoice *fieldChoice, const AnnotBorder *border, const PDFRectangle *rect,
 			      const GooString *da, const GfxResources *resources, int quadding) {
-  GooList *daToks;
+  GooList<GooString*> *daToks;
   GooString *tok;
   GooString convertedText;
   const GfxFont *font;
@@ -4454,7 +4454,7 @@
   // parse the default appearance string
   tfPos = tmPos = -1;
   if (da) {
-    daToks = new GooList();
+    daToks = new GooList<GooString*>();
     i = 0;
     while (i < da->getLength()) {
       while (i < da->getLength() && Lexer::isSpace(da->getChar(i))) {
@@ -4498,7 +4498,7 @@
   }
   if (!font) {
     if (daToks) {
-      deleteGooList<GooString>(daToks);
+      deleteGooList<GooString*>(daToks);
     }
     return false;
   }
@@ -4514,7 +4514,7 @@
       if (fieldChoice->getChoice(i) == nullptr) {
         error(errSyntaxError, -1, "Invalid annotation listbox");
         if (daToks) {
-	  deleteGooList<GooString>(daToks);
+	  deleteGooList<GooString*>(daToks);
         }
         return false;
       }
@@ -4611,7 +4611,7 @@
   }
 
   if (daToks) {
-    deleteGooList<GooString>(daToks);
+    deleteGooList<GooString*>(daToks);
   }
 
   return true;
diff --git a/poppler/FontInfo.cc b/poppler/FontInfo.cc
index a6dd5a7..3549581 100644
--- a/poppler/FontInfo.cc
+++ b/poppler/FontInfo.cc
@@ -51,8 +51,7 @@
 FontInfoScanner::~FontInfoScanner() {
 }
 
-GooList *FontInfoScanner::scan(int nPages) {
-  GooList *result;
+GooList<FontInfo*> *FontInfoScanner::scan(int nPages) {
   Page *page;
   Dict *resDict;
   Annots *annots;
@@ -62,7 +61,7 @@
     return nullptr;
   }
  
-  result = new GooList();
+  auto result = new GooList<FontInfo*>();
 
   lastPage = currentPage + nPages;
   if (lastPage > doc->getNumPages() + 1) {
@@ -93,7 +92,7 @@
   return result;
 }
 
-void FontInfoScanner::scanFonts(XRef *xrefA, Dict *resDict, GooList *fontsList) {
+void FontInfoScanner::scanFonts(XRef *xrefA, Dict *resDict, GooList<FontInfo*> *fontsList) {
   GfxFontDict *gfxFontDict;
   GfxFont *font;
 
diff --git a/poppler/FontInfo.h b/poppler/FontInfo.h
index 7d6af0c..e851288 100644
--- a/poppler/FontInfo.h
+++ b/poppler/FontInfo.h
@@ -89,7 +89,7 @@
   // Destructor.
   ~FontInfoScanner();
 
-  GooList *scan(int nPages);
+  GooList<FontInfo*> *scan(int nPages);
 
 private:
 
@@ -98,7 +98,7 @@
   std::set<int> fonts;
   std::set<int> visitedObjects;
 
-  void scanFonts(XRef *xrefA, Dict *resDict, GooList *fontsList);
+  void scanFonts(XRef *xrefA, Dict *resDict, GooList<FontInfo*> *fontsList);
 };
 
 #endif
diff --git a/poppler/Form.cc b/poppler/Form.cc
index 71b4d4a..babadbf 100644
--- a/poppler/Form.cc
+++ b/poppler/Form.cc
@@ -1213,7 +1213,7 @@
 
 double FormFieldText::getTextFontSize()
 {
-  GooList* daToks = new GooList();
+  GooList<GooString*>* daToks = new GooList<GooString*>();
   int idx = parseDA(daToks);
   double fontSize = -1;
   if (idx >= 0) {
@@ -1222,18 +1222,18 @@
     if (!p || *p)
       fontSize = -1;
   }
-  deleteGooList<GooString>(daToks);
+  deleteGooList<GooString*>(daToks);
   return fontSize;
 }
 
 void FormFieldText::setTextFontSize(int fontSize)
 {
   if (fontSize > 0 && obj.isDict()) {
-    GooList* daToks = new GooList();
+    GooList<GooString*>* daToks = new GooList<GooString*>();
     int idx = parseDA(daToks);
     if (idx == -1) {
       error(errSyntaxError, -1, "FormFieldText:: invalid DA object\n");
-      deleteGooList<GooString>(daToks);
+      deleteGooList<GooString*>(daToks);
       return;
     }
     if (defaultAppearance)
@@ -1248,14 +1248,14 @@
         defaultAppearance->append(static_cast<GooString*>(daToks->get(i)));
       }
     }
-    deleteGooList<GooString>(daToks);
+    deleteGooList<GooString*>(daToks);
     obj.dictSet("DA", Object(defaultAppearance->copy()));
     xref->setModifiedObject(&obj, ref);
     updateChildrenAppearance();
   }
 }
 
-int FormFieldText::tokenizeDA(const GooString* da, GooList* daToks, const char* searchTok)
+int FormFieldText::tokenizeDA(const GooString* da, GooList<GooString*>* daToks, const char* searchTok)
 {
   int idx = -1;
   if(da && daToks) {
@@ -1279,7 +1279,7 @@
   return idx;
 }
 
-int FormFieldText::parseDA(GooList* daToks)
+int FormFieldText::parseDA(GooList<GooString*>* daToks)
 {
   int idx = -1;
   if (obj.isDict()) {
diff --git a/poppler/Form.h b/poppler/Form.h
index 9b12146..496680b 100644
--- a/poppler/Form.h
+++ b/poppler/Form.h
@@ -426,10 +426,10 @@
 
   void print(int indent) override;
 
-  static int tokenizeDA(const GooString* daString, GooList* daToks, const char* searchTok);
+  static int tokenizeDA(const GooString* daString, GooList<GooString*>* daToks, const char* searchTok);
 
 protected:
-  int parseDA(GooList* daToks);
+  int parseDA(GooList<GooString*>* daToks);
 
   GooString* content;
   bool multiline;
diff --git a/poppler/GfxState.cc b/poppler/GfxState.cc
index 0d013ca..27f6614 100644
--- a/poppler/GfxState.cc
+++ b/poppler/GfxState.cc
@@ -432,7 +432,7 @@
   return cs;
 }
 
-void GfxColorSpace::createMapping(GooList *separationList, int maxSepComps) {
+void GfxColorSpace::createMapping(GooList<GfxSeparationColorSpace*> *separationList, int maxSepComps) {
   return;
 }
 
@@ -2857,7 +2857,7 @@
   color->c[0] = gfxColorComp1;
 }
 
-void GfxSeparationColorSpace::createMapping(GooList *separationList, int maxSepComps) {
+void GfxSeparationColorSpace::createMapping(GooList<GfxSeparationColorSpace*> *separationList, int maxSepComps) {
   if (nonMarking)
     return;
   mapping = (int *)gmalloc(sizeof(int));
@@ -2900,7 +2900,7 @@
         return;
       }
       *mapping = separationList->size() + 4;
-      separationList->push_back(copy());
+      separationList->push_back((GfxSeparationColorSpace*)copy());
       overprintMask = newOverprintMask;
       break;
   }
@@ -2914,7 +2914,7 @@
 					   GooString **namesA,
 					   GfxColorSpace *altA,
 					   Function *funcA,
-					   GooList *sepsCSA) {
+					   GooList<GfxSeparationColorSpace*> *sepsCSA) {
   int i;
 
   nComps = nCompsA;
@@ -2949,7 +2949,7 @@
 					   GooString **namesA,
 					   GfxColorSpace *altA,
 					   Function *funcA,
-					   GooList *sepsCSA,
+					   GooList<GfxSeparationColorSpace*> *sepsCSA,
 					   int *mappingA,
 					   bool nonMarkingA,
 					   unsigned int overprintMaskA) {
@@ -2975,7 +2975,7 @@
   }
   delete alt;
   delete func;
-  deleteGooList<GfxSeparationColorSpace>(sepsCS);
+  deleteGooList<GfxSeparationColorSpace*>(sepsCS);
   if (mapping != nullptr)
     gfree(mapping);
 }
@@ -2984,12 +2984,12 @@
   int i;
   int *mappingA = nullptr;
 
-  GooList *sepsCSA = new GooList();
+  auto sepsCSA = new GooList<GfxSeparationColorSpace*>();
   sepsCSA->reserve(sepsCS->size());
   for (std::size_t i = 0; i < sepsCS->size(); i++) {
     GfxSeparationColorSpace *scs = (GfxSeparationColorSpace *) sepsCS->get(i);
     if (likely(scs != nullptr)) {
-      sepsCSA->push_back(scs->copy());
+      sepsCSA->push_back((GfxSeparationColorSpace*)scs->copy());
     }
   }
   if (mapping != nullptr) {
@@ -3009,7 +3009,7 @@
   Function *funcA;
   Object obj1;
   int i;
-  GooList *separationList = new GooList();
+  auto separationList = new GooList<GfxSeparationColorSpace*>();
 
   if (arr->getLength() != 4 && arr->getLength() != 5) {
     error(errSyntaxWarning, -1, "Bad DeviceN color space");
@@ -3057,7 +3057,7 @@
       for (i = 0; i < colorants->getLength(); i++) {
         Object obj3 = colorants->getVal(i);
         if (obj3.isArray()) {
-	  separationList->push_back(GfxSeparationColorSpace::parse(res, obj3.getArray(), out, state, recursion));
+	  separationList->push_back((GfxSeparationColorSpace*)GfxSeparationColorSpace::parse(res, obj3.getArray(), out, state, recursion));
         } else {
           error(errSyntaxWarning, -1, "Bad DeviceN color space (colorant value entry is not an Array)");
           goto err5;
@@ -3151,7 +3151,7 @@
   }
 }
 
-void GfxDeviceNColorSpace::createMapping(GooList *separationList, int maxSepComps) {
+void GfxDeviceNColorSpace::createMapping(GooList<GfxSeparationColorSpace*> *separationList, int maxSepComps) {
   if (nonMarking)               // None
     return;
   mapping = (int *)gmalloc(sizeof(int) * nComps);
@@ -3222,7 +3222,7 @@
             GfxSeparationColorSpace *sepCS = (GfxSeparationColorSpace *)sepsCS->get(k);
             if (!sepCS->getName()->cmp(names[i])) {
               found = true;
-	      separationList->push_back(sepCS->copy());
+	      separationList->push_back((GfxSeparationColorSpace*)sepCS->copy());
               break;
             }
           }
diff --git a/poppler/GfxState.h b/poppler/GfxState.h
index 4bfcd73..4bd7620 100644
--- a/poppler/GfxState.h
+++ b/poppler/GfxState.h
@@ -47,10 +47,10 @@
 class GfxFont;
 class PDFRectangle;
 class GfxShading;
-class GooList;
 class OutputDev;
 class GfxState;
 class GfxResources;
+class GfxSeparationColorSpace;
 
 class Matrix {
 public:
@@ -235,7 +235,7 @@
   virtual void getDeviceNLine(unsigned char * /*in*/, unsigned char * /*out*/, int /*length*/) {  error(errInternal, -1, "GfxColorSpace::getDeviceNLine this should not happen"); }
 
   // create mapping for spot colorants
-  virtual void createMapping(GooList *separationList, int maxSepComps);
+  virtual void createMapping(GooList<GfxSeparationColorSpace*> *separationList, int maxSepComps);
 
   // Does this ColorSpace support getRGBLine?
   virtual bool useGetRGBLine() const { return false; }
@@ -621,7 +621,7 @@
   unsigned char *getLookup() { return lookup; }
   GfxColor *mapColorToBase(const GfxColor *color, GfxColor *baseColor) const;
   unsigned int getOverprintMask() { return base->getOverprintMask(); }
-  void createMapping(GooList *separationList, int maxSepComps) override
+  void createMapping(GooList<GfxSeparationColorSpace*> *separationList, int maxSepComps) override
     { base->createMapping(separationList, maxSepComps); }
 
 
@@ -653,7 +653,7 @@
   void getCMYK(const GfxColor *color, GfxCMYK *cmyk) const override;
   void getDeviceN(const GfxColor *color, GfxColor *deviceN) const override;
 
-  void createMapping(GooList *separationList, int maxSepComps) override;
+  void createMapping(GooList<GfxSeparationColorSpace*> *separationList, int maxSepComps) override;
 
   int getNComps() const override { return 1; }
   void getDefaultColor(GfxColor *color) override;
@@ -685,7 +685,7 @@
 public:
 
   GfxDeviceNColorSpace(int nCompsA, GooString **namesA,
-		       GfxColorSpace *alt, Function *func, GooList *sepsCS);
+		       GfxColorSpace *alt, Function *func, GooList<GfxSeparationColorSpace*> *sepsCS);
   ~GfxDeviceNColorSpace();
   GfxColorSpace *copy() override;
   GfxColorSpaceMode getMode() override { return csDeviceN; }
@@ -698,7 +698,7 @@
   void getCMYK(const GfxColor *color, GfxCMYK *cmyk) const override;
   void getDeviceN(const GfxColor *color, GfxColor *deviceN) const override;
 
-  void createMapping(GooList *separationList, int maxSepComps) override;
+  void createMapping(GooList<GfxSeparationColorSpace*> *separationList, int maxSepComps) override;
 
   int getNComps() const override { return nComps; }
   void getDefaultColor(GfxColor *color) override;
@@ -713,8 +713,13 @@
 private:
 
   GfxDeviceNColorSpace(int nCompsA, GooString **namesA,
+<<<<<<< HEAD
 		       GfxColorSpace *alt, Function *func, GooList *sepsCSA,
 		       int *mappingA, bool nonMarkingA, unsigned int overprintMaskA);
+=======
+		       GfxColorSpace *alt, Function *func, GooList<GfxSeparationColorSpace*> *sepsCSA,
+		       int *mappingA, bool nonMarkingA, Guint overprintMaskA);
+>>>>>>> Make GooList a template type
 
   int nComps;			// number of components
   GooString			// colorant names
@@ -722,7 +727,7 @@
   GfxColorSpace *alt;		// alternate color space
   Function *func;		// tint transform (into alternate color space)
   bool nonMarking;
-  GooList *sepsCS; // list of separation cs for spot colorants;
+  GooList<GfxSeparationColorSpace*> *sepsCS; // list of separation cs for spot colorants;
 };
 
 //------------------------------------------------------------------------
diff --git a/poppler/GlobalParams.cc b/poppler/GlobalParams.cc
index d20c7fe..f02567b 100644
--- a/poppler/GlobalParams.cc
+++ b/poppler/GlobalParams.cc
@@ -246,15 +246,15 @@
 			       const char *path);
 #endif
 
-  GooList *fonts;			// [SysFontInfo]
+  GooList<SysFontInfo*> *fonts;
 };
 
 SysFontList::SysFontList() {
-  fonts = new GooList();
+  fonts = new GooList<SysFontInfo*>();
 }
 
 SysFontList::~SysFontList() {
-  deleteGooList<SysFontInfo>(fonts);
+  deleteGooList<SysFontInfo*>(fonts);
 }
 
 SysFontInfo *SysFontList::find(const GooString *name, bool fixedWidth, bool exact) {
@@ -394,7 +394,7 @@
 
   nameToUnicodeZapfDingbats = new NameToCharCode();
   nameToUnicodeText = new NameToCharCode();
-  toUnicodeDirs = new GooList();
+  toUnicodeDirs = new GooList<GooString*>();
   sysFonts = new SysFontList();
   psExpandSmaller = false;
   psShrinkLarger = true;
@@ -553,7 +553,7 @@
 
   delete nameToUnicodeZapfDingbats;
   delete nameToUnicodeText;
-  deleteGooList<GooString>(toUnicodeDirs);
+  deleteGooList<GooString*>(toUnicodeDirs);
   delete sysFonts;
   delete textEncoding;
 
@@ -1203,9 +1203,9 @@
   return getUnicodeMap2(textEncoding);
 }
 
-GooList *GlobalParams::getEncodingNames()
+GooList<GooString*> *GlobalParams::getEncodingNames()
 {
-  auto* const result = new GooList;
+  auto* const result = new GooList<GooString*>;
   for (const auto& unicodeMap : residentUnicodeMaps) {
     result->push_back(new GooString(unicodeMap.first));
   }
diff --git a/poppler/GlobalParams.h b/poppler/GlobalParams.h
index 365c489..0277ee2 100644
--- a/poppler/GlobalParams.h
+++ b/poppler/GlobalParams.h
@@ -46,7 +46,6 @@
 #include <mutex>
 
 class GooString;
-class GooList;
 class NameToCharCode;
 class CharCodeToUnicode;
 class CharCodeToUnicodeCache;
@@ -145,7 +144,7 @@
   CMap *getCMap(const GooString *collection, GooString *cMapName, Stream *stream = nullptr);
   UnicodeMap *getTextEncoding();
 
-  GooList *getEncodingNames();
+  GooList<GooString*> *getEncodingNames();
 
   //----- functions to set parameters
   void addFontFile(GooString *fontName, GooString *path);
@@ -195,7 +194,7 @@
   std::unordered_map<std::string, std::string> unicodeMaps;
   // list of CMap dirs, indexed by collection
   std::unordered_multimap<std::string, std::string> cMapDirs;
-  GooList *toUnicodeDirs;		// list of ToUnicode CMap dirs [GooString]
+  GooList<GooString*> *toUnicodeDirs;		// list of ToUnicode CMap dirs
   bool baseFontsInitialized;
 #ifdef _WIN32
   // windows font substitutes (for CID fonts)
diff --git a/poppler/JBIG2Stream.cc b/poppler/JBIG2Stream.cc
index 2b9d2ac..5424c06 100644
--- a/poppler/JBIG2Stream.cc
+++ b/poppler/JBIG2Stream.cc
@@ -1244,7 +1244,7 @@
 
 void JBIG2Stream::reset() {
   // read the globals stream
-  globalSegments = new GooList();
+  globalSegments = new GooList<JBIG2Segment*>();
   if (globalsStream.isStream()) {
     segments = globalSegments;
     curStr = globalsStream.getStream();
@@ -1257,7 +1257,7 @@
   }
 
   // read the main stream
-  segments = new GooList();
+  segments = new GooList<JBIG2Segment*>();
   curStr = str;
   curStr->reset();
   arithDecoder->setStream(curStr);
@@ -1279,11 +1279,11 @@
     pageBitmap = nullptr;
   }
   if (segments) {
-    deleteGooList<JBIG2Segment>(segments);
+    deleteGooList<JBIG2Segment*>(segments);
     segments = nullptr;
   }
   if (globalSegments) {
-    deleteGooList<JBIG2Segment>(globalSegments);
+    deleteGooList<JBIG2Segment*>(globalSegments);
     globalSegments = nullptr;
   }
   dataPtr = dataEnd = nullptr;
@@ -1556,7 +1556,7 @@
   JBIG2HuffmanTable *huffDHTable, *huffDWTable;
   JBIG2HuffmanTable *huffBMSizeTable, *huffAggInstTable;
   JBIG2Segment *seg;
-  GooList *codeTables;
+  GooList<JBIG2Segment*> *codeTables;
   JBIG2SymbolDict *inputSymbolDict;
   unsigned int flags, sdTemplate, sdrTemplate, huff, refAgg;
   unsigned int huffDH, huffDW, huffBMSize, huffAggInst;
@@ -1627,7 +1627,7 @@
   }
 
   // get referenced segments: input symbol dictionaries and code tables
-  codeTables = new GooList();
+  codeTables = new GooList<JBIG2Segment*>();
   numInputSyms = 0;
   for (i = 0; i < nRefSegs; ++i) {
     // This is need by bug 12014, returning false makes it not crash
@@ -2019,7 +2019,7 @@
   JBIG2HuffmanTable *huffRDWTable, *huffRDHTable;
   JBIG2HuffmanTable *huffRDXTable, *huffRDYTable, *huffRSizeTable;
   JBIG2Segment *seg;
-  GooList *codeTables;
+  GooList<JBIG2Segment*> *codeTables;
   JBIG2SymbolDict *symbolDict;
   JBIG2Bitmap **syms;
   unsigned int w, h, x, y, segInfoFlags, extCombOp;
@@ -2083,7 +2083,7 @@
   }
 
   // get symbol dictionaries and tables
-  codeTables = new GooList();
+  codeTables = new GooList<JBIG2Segment*>();
   numSyms = 0;
   for (i = 0; i < nRefSegs; ++i) {
     if ((seg = findSegment(refSegs[i]))) {
diff --git a/poppler/JBIG2Stream.h b/poppler/JBIG2Stream.h
index ab746c9..f410134 100644
--- a/poppler/JBIG2Stream.h
+++ b/poppler/JBIG2Stream.h
@@ -28,7 +28,6 @@
 #include "Object.h"
 #include "Stream.h"
 
-class GooList;
 class JBIG2Segment;
 class JBIG2Bitmap;
 class JArithmeticDecoder;
@@ -134,8 +133,8 @@
   unsigned int pageDefPixel;
   JBIG2Bitmap *pageBitmap;
   unsigned int defCombOp;
-  GooList *segments;		// [JBIG2Segment]
-  GooList *globalSegments;	// [JBIG2Segment]
+  GooList<JBIG2Segment*> *segments;
+  GooList<JBIG2Segment*> *globalSegments;
   Stream *curStr;
   unsigned char *dataPtr;
   unsigned char *dataEnd;
diff --git a/poppler/Link.cc b/poppler/Link.cc
index 4ee8b78..ffe0ebd 100644
--- a/poppler/Link.cc
+++ b/poppler/Link.cc
@@ -54,7 +54,7 @@
 
 LinkAction::~LinkAction() {
   if (nextActionList)
-    deleteGooList<LinkAction>(nextActionList);
+    deleteGooList<LinkAction*>(nextActionList);
 }
 
 LinkAction *LinkAction::parseDest(const Object *obj) {
@@ -158,7 +158,7 @@
 
   // parse the next actions
   const Object nextObj = obj->dictLookup("Next");
-  GooList *actionList = nullptr;
+  GooList<LinkAction*> *actionList = nullptr;
   if (nextObj.isDict()) {
 
     // Prevent circles in the tree by checking the ref against used refs in
@@ -172,13 +172,13 @@
         }
     }
 
-    actionList = new GooList();
+    actionList = new GooList<LinkAction*>();
     actionList->reserve(1);
     actionList->push_back(parseAction(&nextObj, nullptr, seenNextActions));
   } else if (nextObj.isArray()) {
     const Array *a = nextObj.getArray();
     const int n = a->getLength();
-    actionList = new GooList();
+    actionList = new GooList<LinkAction*>();
     actionList->reserve(n);
     for (int i = 0; i < n; ++i) {
       const Object obj3 = a->get(i);
@@ -206,11 +206,11 @@
   return action;
 }
 
-const GooList *LinkAction::nextActions() const {
+const GooList<LinkAction*> *LinkAction::nextActions() const {
   return nextActionList;
 }
 
-void LinkAction::setNextActions(GooList *actions) {
+void LinkAction::setNextActions(GooList<LinkAction*> *actions) {
   delete nextActionList;
   nextActionList = actions;
 }
@@ -824,7 +824,7 @@
 // LinkOCGState
 //------------------------------------------------------------------------
 LinkOCGState::LinkOCGState(const Object *obj) {
-  stateList = new GooList();
+  stateList = new GooList<StateList*>();
   preserveRB = true;
 
   Object obj1 = obj->dictLookup("State");
@@ -839,7 +839,7 @@
 
 	const char *name = obj2.getName();
 	stList = new StateList();
-	stList->list = new GooList();
+	stList->list = new GooList<Ref*>();
 	if (!strcmp (name, "ON")) {
 	  stList->st = On;
 	} else if (!strcmp (name, "OFF")) {
@@ -882,12 +882,12 @@
 
 LinkOCGState::~LinkOCGState() {
   if (stateList)
-    deleteGooList<StateList>(stateList);
+    deleteGooList<StateList*>(stateList);
 }
 
 LinkOCGState::StateList::~StateList() {
   if (list)
-    deleteGooList<Ref>(list);
+    deleteGooList<Ref*>(list);
 }
 
 //------------------------------------------------------------------------
diff --git a/poppler/Link.h b/poppler/Link.h
index 5fea9a6..e7830fa 100644
--- a/poppler/Link.h
+++ b/poppler/Link.h
@@ -29,12 +29,12 @@
 #ifndef LINK_H
 #define LINK_H
 
+#include "goo/GooList.h"
 #include "Object.h"
 #include <memory>
 #include <set>
 
 class GooString;
-class GooList;
 class Array;
 class Dict;
 class Sound;
@@ -85,15 +85,15 @@
 
   // A List of the next actions to execute in order.
   // The list contains pointer to LinkAction objects.
-  const GooList *nextActions() const;
+  const GooList<LinkAction*> *nextActions() const;
 
   // Sets the next action list. Takes ownership of the actions.
-  void setNextActions(GooList *actions);
+  void setNextActions(GooList<LinkAction*> *actions);
 
 private:
   static LinkAction *parseAction(const Object *obj, const GooString *baseURI, std::set<int> *seenNextActions);
 
-  GooList *nextActionList;
+  GooList<LinkAction*> *nextActionList;
 };
 
 //------------------------------------------------------------------------
@@ -452,14 +452,14 @@
     StateList(const StateList &) = delete;
     StateList& operator=(const StateList &) = delete;
     State st;
-    GooList *list;
+    GooList<Ref*> *list;
   };
 
-  const GooList *getStateList() const { return stateList; }
+  const GooList<StateList*> *getStateList() const { return stateList; }
   bool getPreserveRB() const { return preserveRB; }
 
 private:
-  GooList *stateList;
+  GooList<StateList*> *stateList;
   bool preserveRB;
 };
 
diff --git a/poppler/OptionalContent.cc b/poppler/OptionalContent.cc
index 76832e3..50f9432 100644
--- a/poppler/OptionalContent.cc
+++ b/poppler/OptionalContent.cc
@@ -432,24 +432,23 @@
 
 void OCDisplayNode::addChild(OCDisplayNode *child) {
   if (!children) {
-    children = new GooList();
+    children = new GooList<OCDisplayNode*>();
   }
   children->push_back(child);
 }
 
-void OCDisplayNode::addChildren(GooList *childrenA) {
+void OCDisplayNode::addChildren(GooList<OCDisplayNode*> *childrenA) {
   if (!children) {
-    children = new GooList();
+    children = new GooList<OCDisplayNode*>();
   }
   children->reserve(children->size() + childrenA->size());
   children->insert(children->end(), childrenA->begin(), childrenA->end());
   delete childrenA;
 }
 
-GooList *OCDisplayNode::takeChildren() {
-  GooList *childrenA;
+GooList<OCDisplayNode*> *OCDisplayNode::takeChildren() {
+  GooList<OCDisplayNode*> *childrenA = children;
 
-  childrenA = children;
   children = nullptr;
   return childrenA;
 }
@@ -457,7 +456,7 @@
 OCDisplayNode::~OCDisplayNode() {
   delete name;
   if (children) {
-    deleteGooList<OCDisplayNode>(children);
+    deleteGooList<OCDisplayNode*>(children);
   }
 }
 
diff --git a/poppler/OptionalContent.h b/poppler/OptionalContent.h
index 309d1e6..1c060f0 100644
--- a/poppler/OptionalContent.h
+++ b/poppler/OptionalContent.h
@@ -14,13 +14,13 @@
 #ifndef OPTIONALCONTENT_H
 #define OPTIONALCONTENT_H
 
+#include "goo/GooList.h"
 #include "Object.h"
 #include "CharTypes.h"
 #include <unordered_map>
 #include <memory>
 
 class GooString;
-class GooList;
 class XRef;
 
 class OptionalContentGroup;
@@ -135,12 +135,12 @@
   OCDisplayNode(const GooString *nameA);
   OCDisplayNode(OptionalContentGroup *ocgA);
   void addChild(OCDisplayNode *child);
-  void addChildren(GooList *childrenA);
-  GooList *takeChildren();
+  void addChildren(GooList<OCDisplayNode*> *childrenA);
+  GooList<OCDisplayNode*> *takeChildren();
 
   GooString *name;		// display name (may be nullptr)
   OptionalContentGroup *ocg;	// nullptr for display labels
-  GooList *children;		// nullptr if there are no children
+  GooList<OCDisplayNode*> *children;		// nullptr if there are no children
 				//   [OCDisplayNode]
 };
 
diff --git a/poppler/Outline.cc b/poppler/Outline.cc
index cf61fed..bc7fe12 100644
--- a/poppler/Outline.cc
+++ b/poppler/Outline.cc
@@ -50,7 +50,7 @@
 
 Outline::~Outline() {
   if (items) {
-    deleteGooList<OutlineItem>(items);
+    deleteGooList<OutlineItem*>(items);
   }
 }
 
@@ -108,8 +108,8 @@
   }
 }
 
-GooList *OutlineItem::readItemList(OutlineItem *parent, const Object *firstItemRef, XRef *xrefA) {
-  GooList *items = new GooList();
+GooList<OutlineItem*> *OutlineItem::readItemList(OutlineItem *parent, const Object *firstItemRef, XRef *xrefA) {
+  auto items = new GooList<OutlineItem*>();
 
   char* alreadyRead = (char *)gmalloc(xrefA->getNumObjects());
   memset(alreadyRead, 0, xrefA->getNumObjects());
@@ -153,7 +153,7 @@
 
 void OutlineItem::close() {
   if (kids) {
-    deleteGooList<OutlineItem>(kids);
+    deleteGooList<OutlineItem*>(kids);
     kids = nullptr;
   }
 }
diff --git a/poppler/Outline.h b/poppler/Outline.h
index b7d34e1..edd5c87 100644
--- a/poppler/Outline.h
+++ b/poppler/Outline.h
@@ -26,11 +26,12 @@
 
 #include "Object.h"
 #include "CharTypes.h"
+#include "goo/GooList.h"
 
 class GooString;
-class GooList;
 class XRef;
 class LinkAction;
+class OutlineItem;
 
 //------------------------------------------------------------------------
 
@@ -43,12 +44,11 @@
   Outline(const Outline &) = delete;
   Outline& operator=(const Outline &) = delete;
 
-  const GooList *getItems() const { return items; }
+  const GooList<OutlineItem*> *getItems() const { return items; }
 
 private:
 
-  GooList *items;		// NULL if document has no outline,
-				// otherwise, a list of OutlineItem
+  GooList<OutlineItem*> *items; // nullptr if document has no outline,
 };
 
 //------------------------------------------------------------------------
@@ -62,7 +62,7 @@
   OutlineItem(const OutlineItem &) = delete;
   OutlineItem& operator=(const OutlineItem &) = delete;
 
-  static GooList *readItemList(OutlineItem *parent, const Object *firstItemRef, XRef *xrefA);
+  static GooList<OutlineItem*> *readItemList(OutlineItem *parent, const Object *firstItemRef, XRef *xrefA);
 
   void open();
   void close();
@@ -72,7 +72,7 @@
   const LinkAction *getAction() const { return action; }
   bool isOpen() const { return startsOpen; }
   bool hasKids() const { return firstRef.isRef(); }
-  const GooList *getKids() const { return kids; }
+  const GooList<OutlineItem*> *getKids() const { return kids; }
 
 private:
 
@@ -86,8 +86,7 @@
   Object lastRef;
   Object nextRef;
   bool startsOpen;
-  GooList *kids;	// NULL if this item is closed or has no kids,
-			// otherwise a list of OutlineItem
+  GooList<OutlineItem*> *kids;   // nullptr if this item is closed or has no kids
 };
 
 #endif
diff --git a/poppler/PDFDocFactory.cc b/poppler/PDFDocFactory.cc
index b34ab3b..9f6c275 100644
--- a/poppler/PDFDocFactory.cc
+++ b/poppler/PDFDocFactory.cc
@@ -29,12 +29,12 @@
 // PDFDocFactory
 //------------------------------------------------------------------------
 
-PDFDocFactory::PDFDocFactory(GooList *pdfDocBuilders)
+PDFDocFactory::PDFDocFactory(GooList<PDFDocBuilder*> *pdfDocBuilders)
 {
   if (pdfDocBuilders) {
     builders = pdfDocBuilders;
   } else {
-    builders = new GooList();
+    builders = new GooList<PDFDocBuilder*>();
   }
   builders->push_back(new LocalPDFDocBuilder());
   builders->push_back(new StdinPDFDocBuilder());
@@ -46,7 +46,7 @@
 PDFDocFactory::~PDFDocFactory()
 {
   if (builders) {
-    deleteGooList<PDFDocBuilder>(builders);
+    deleteGooList<PDFDocBuilder*>(builders);
   }
 }
 
diff --git a/poppler/PDFDocFactory.h b/poppler/PDFDocFactory.h
index 6dba0be..fa735bf 100644
--- a/poppler/PDFDocFactory.h
+++ b/poppler/PDFDocFactory.h
@@ -14,7 +14,6 @@
 
 #include "PDFDoc.h"
 
-class GooList;
 class GooString;
 class PDFDocBuilder;
 
@@ -34,7 +33,7 @@
 
 public:
 
-  PDFDocFactory(GooList *pdfDocBuilders = nullptr);
+  PDFDocFactory(GooList<PDFDocBuilder*> *pdfDocBuilders = nullptr);
   ~PDFDocFactory();
 
   PDFDocFactory(const PDFDocFactory &) = delete;
@@ -51,7 +50,7 @@
 
 private:
 
-  GooList *builders;
+  GooList<PDFDocBuilder*> *builders;
 
 };
 
diff --git a/poppler/PSOutputDev.cc b/poppler/PSOutputDev.cc
index 6a4713b..9c51b6f 100644
--- a/poppler/PSOutputDev.cc
+++ b/poppler/PSOutputDev.cc
@@ -1325,7 +1325,7 @@
     paperMatch = false;
   }
   Page *page;
-  paperSizes = new GooList();
+  paperSizes = new GooList<PSOutPaperSize*>();
   for (size_t pgi = 0; pgi < pages.size(); ++pgi) {
     const int pg = pages[pgi];
     page = catalog->getPage(pg);
@@ -1478,7 +1478,7 @@
 #endif
   }
   if (paperSizes) {
-    deleteGooList<PSOutPaperSize>(paperSizes);
+    deleteGooList<PSOutPaperSize*>(paperSizes);
   }
   if (embFontList) {
     delete embFontList;
diff --git a/poppler/PSOutputDev.h b/poppler/PSOutputDev.h
index 0e8b911..8ce7613 100644
--- a/poppler/PSOutputDev.h
+++ b/poppler/PSOutputDev.h
@@ -61,6 +61,7 @@
 struct PSFont8Info;
 struct PSFont16Enc;
 class PSOutCustomColor;
+class PSOutPaperSize;
 class PSOutputDev;
 
 //------------------------------------------------------------------------
@@ -497,8 +498,8 @@
   int numTilingPatterns;	// current number of nested tiling patterns
   int nextFunc;			// next unique number to use for a function
 
-  GooList *paperSizes;		// list of used paper sizes, if paperMatch
-				//   is true [PSOutPaperSize]
+  GooList<PSOutPaperSize*> *paperSizes;	// list of used paper sizes, if paperMatch
+				//   is true
   std::map<int,int> pagePaperSize; // page num to paperSize entry mapping
   double tx0, ty0;		// global translation
   double xScale0, yScale0;	// global scaling
diff --git a/poppler/TextOutputDev.cc b/poppler/TextOutputDev.cc
index 39bd920..616bfdc 100644
--- a/poppler/TextOutputDev.cc
+++ b/poppler/TextOutputDev.cc
@@ -2281,7 +2281,7 @@
   TextWord **wordArray;
   int nWords, i;
 
-  words = new GooList();
+  words = new GooList<TextWord*>();
 
   if (text->rawOrder) {
     for (word = text->rawWords; word; word = word->next) {
@@ -2373,11 +2373,11 @@
   blocks = nullptr;
   rawWords = nullptr;
   rawLastWord = nullptr;
-  fonts = new GooList();
+  fonts = new GooList<TextFontInfo*>();
   lastFindXMin = lastFindYMin = 0;
   haveLastFind = false;
-  underlines = new GooList();
-  links = new GooList();
+  underlines = new GooList<TextUnderline*>();
+  links = new GooList<TextLink*>();
   mergeCombining = true;
 }
 
@@ -2391,8 +2391,8 @@
     }
   }
   delete fonts;
-  deleteGooList<TextUnderline>(underlines);
-  deleteGooList<TextLink>(links);
+  deleteGooList<TextUnderline*>(underlines);
+  deleteGooList<TextLink*>(links);
 }
 
 void TextPage::incRefCnt() {
@@ -2446,9 +2446,9 @@
     }
     gfree(blocks);
   }
-  deleteGooList<TextFontInfo>(fonts);
-  deleteGooList<TextUnderline>(underlines);
-  deleteGooList<TextLink>(links);
+  deleteGooList<TextFontInfo*>(fonts);
+  deleteGooList<TextUnderline*>(underlines);
+  deleteGooList<TextLink*>(links);
 
   curWord = nullptr;
   charPos = 0;
@@ -2465,9 +2465,9 @@
   blocks = nullptr;
   rawWords = nullptr;
   rawLastWord = nullptr;
-  fonts = new GooList();
-  underlines = new GooList();
-  links = new GooList();
+  fonts = new GooList<TextFontInfo*>();
+  underlines = new GooList<TextUnderline*>();
+  links = new GooList<TextLink*>();
 }
 
 void TextPage::updateFont(GfxState *state) {
@@ -4412,16 +4412,16 @@
   void endPage();
 
   GooString *getText(void);
-  GooList **takeWordList(int *nLines);
+  GooList<TextWordSelection*> **takeWordList(int *nLines);
 
 private:
 
   void startLine();
   void finishLine();
 
-  GooList **lines;
+  GooList<TextWordSelection*> **lines;
   int nLines, linesSize;
-  GooList *words;
+  GooList<TextWordSelection*> *words;
   int tableId;
   TextBlock *currentBlock;
 };
@@ -4430,7 +4430,7 @@
     : TextSelectionVisitor(page)
 {
   linesSize = 256;
-  lines = (GooList **)gmallocn(linesSize, sizeof(GooList *));
+  lines = (GooList<TextWordSelection*> **)gmallocn(linesSize, sizeof(GooList<TextWordSelection*> *));
   nLines = 0;
 
   tableId = -1;
@@ -4441,21 +4441,21 @@
 TextSelectionDumper::~TextSelectionDumper()
 {
   for (int i = 0; i < nLines; i++)
-    deleteGooList<TextWordSelection>(lines[i]);
+    deleteGooList<TextWordSelection*>(lines[i]);
   gfree(lines);
 }
 
 void TextSelectionDumper::startLine()
 {
   finishLine();
-  words = new GooList();
+  words = new GooList<TextWordSelection*>();
 }
 
 void TextSelectionDumper::finishLine()
 {
   if (nLines == linesSize) {
     linesSize *= 2;
-    lines = (GooList **)grealloc(lines, linesSize * sizeof(GooList *));
+    lines = (GooList<TextWordSelection*> **)grealloc(lines, linesSize * sizeof(GooList<TextWordSelection*> *));
   }
 
   if (words && words->size() > 0)
@@ -4530,7 +4530,7 @@
   eolLen = uMap->mapUnicode(0x0a, eol, sizeof(eol));
 
   for (i = 0; i < nLines; i++) {
-    GooList *lineWords = lines[i];
+    GooList<TextWordSelection*> *lineWords = lines[i];
     for (std::size_t j = 0; j < lineWords->size(); j++) {
       TextWordSelection *sel = (TextWordSelection *)lineWords->get(j);
 
@@ -4547,9 +4547,9 @@
   return text;
 }
 
-GooList **TextSelectionDumper::takeWordList(int *nLinesOut)
+GooList<TextWordSelection*> **TextSelectionDumper::takeWordList(int *nLinesOut)
 {
-  GooList **returnValue = lines;
+  GooList<TextWordSelection*> **returnValue = lines;
 
   *nLinesOut = nLines;
   if (nLines == 0)
@@ -4579,10 +4579,10 @@
   void visitWord (TextWord *word, int begin, int end,
 			  PDFRectangle *selection) override { };
 
-  GooList *getRegion () { return list; }
+  GooList<PDFRectangle*> *getRegion () { return list; }
 
 private:
-  GooList *list;
+  GooList<PDFRectangle*> *list;
   double scale;
 };
 
@@ -4590,7 +4590,7 @@
   : TextSelectionVisitor(page),
     scale(scale)
 {
-  list = new GooList();
+  list = new GooList<PDFRectangle*>();
 }
 
 void TextSelectionSizer::visitLine (TextLine *line, 
@@ -4645,7 +4645,7 @@
   OutputDev *out;
   GfxColor *glyph_color;
   GfxState *state;
-  GooList *selectionList;
+  GooList<TextWordSelection*> *selectionList;
   Matrix ctm, ictm;
 };
 
@@ -4661,7 +4661,7 @@
 {
   PDFRectangle box(0, 0, page->pageWidth, page->pageHeight);
 
-  selectionList = new GooList();
+  selectionList = new GooList<TextWordSelection*>();
   state = new GfxState(72 * scale, 72 * scale, &box, rotation, false);
 
   state->getCTM(&ctm);
@@ -4677,7 +4677,7 @@
 
 TextSelectionPainter::~TextSelectionPainter()
 {
-  deleteGooList<TextWordSelection>(selectionList);
+  deleteGooList<TextWordSelection*>(selectionList);
   delete state;
 }
 
@@ -5121,7 +5121,7 @@
   painter.endPage();
 }
 
-GooList *TextPage::getSelectionRegion(PDFRectangle *selection,
+GooList<PDFRectangle*> *TextPage::getSelectionRegion(PDFRectangle *selection,
 				      SelectionStyle style,
 				      double scale) {
   TextSelectionSizer sizer(this, scale);
@@ -5142,7 +5142,7 @@
   return dumper.getText();
 }
 
-GooList **TextPage::getSelectionWords(PDFRectangle *selection,
+GooList<TextWordSelection*> **TextPage::getSelectionWords(PDFRectangle *selection,
                                       SelectionStyle style,
                                       int *nLines)
 {
@@ -5900,7 +5900,7 @@
   text->drawSelection(out, scale, rotation, selection, style, glyph_color, box_color);
 }
 
-GooList *TextOutputDev::getSelectionRegion(PDFRectangle *selection,
+GooList<PDFRectangle*> *TextOutputDev::getSelectionRegion(PDFRectangle *selection,
 					   SelectionStyle style,
 					   double scale) {
   return text->getSelectionRegion(selection, style, scale);
diff --git a/poppler/TextOutputDev.h b/poppler/TextOutputDev.h
index e935088..8ebc4b7 100644
--- a/poppler/TextOutputDev.h
+++ b/poppler/TextOutputDev.h
@@ -40,7 +40,6 @@
 #include "OutputDev.h"
 
 class GooString;
-class GooList;
 class Gfx;
 class GfxFont;
 class GfxState;
@@ -53,6 +52,8 @@
 class TextLineFrag;
 class TextBlock;
 class TextFlow;
+class TextLink;
+class TextUnderline;
 class TextWordList;
 class TextPage;
 class TextSelectionVisitor;
@@ -518,7 +519,7 @@
 
 private:
 
-  GooList *words;			// [TextWord]
+  GooList<TextWord*> *words;
 };
 
 #endif // TEXTOUT_WORD_LIST
@@ -636,14 +637,14 @@
 		     SelectionStyle style,
 		     GfxColor *glyph_color, GfxColor *box_color);
 
-  GooList *getSelectionRegion(PDFRectangle *selection,
+  GooList<PDFRectangle*> *getSelectionRegion(PDFRectangle *selection,
 			      SelectionStyle style,
 			      double scale);
 
   GooString *getSelectionText(PDFRectangle *selection,
 			      SelectionStyle style);
 
-  GooList **getSelectionWords(PDFRectangle *selection,
+  GooList<TextWordSelection*> **getSelectionWords(PDFRectangle *selection,
                               SelectionStyle style,
                               int *nLines);
 
@@ -708,15 +709,14 @@
 				//   rawOrder is set)
   TextWord *rawLastWord;	// last word on rawWords list
 
-  GooList *fonts;			// all font info objects used on this
-				//   page [TextFontInfo]
+  GooList<TextFontInfo*> *fonts;// all font info objects used on this page
 
   double lastFindXMin,		// coordinates of the last "find" result
          lastFindYMin;
   bool haveLastFind;
 
-  GooList *underlines;		// [TextUnderline]
-  GooList *links;		// [TextLink]
+  GooList<TextUnderline*> *underlines;
+  GooList<TextLink*> *links;
 
   int refCnt;
 
@@ -876,7 +876,7 @@
 		     SelectionStyle style,
 		     GfxColor *glyph_color, GfxColor *box_color);
 
-  GooList *getSelectionRegion(PDFRectangle *selection,
+  GooList<PDFRectangle*> *getSelectionRegion(PDFRectangle *selection,
 			      SelectionStyle style,
 			      double scale);
 
diff --git a/qt5/src/poppler-document.cc b/qt5/src/poppler-document.cc
index 92b01a5..213cde3 100644
--- a/qt5/src/poppler-document.cc
+++ b/qt5/src/poppler-document.cc
@@ -590,7 +590,7 @@
         if ( !outline )
             return nullptr;
 
-        const GooList * items = outline->getItems();
+        const GooList<OutlineItem*> * items = outline->getItems();
         if ( !items || items->size() < 1 )
             return nullptr;
 
diff --git a/qt5/src/poppler-fontinfo.cc b/qt5/src/poppler-fontinfo.cc
index 783d6da..a1c0dd8 100644
--- a/qt5/src/poppler-fontinfo.cc
+++ b/qt5/src/poppler-fontinfo.cc
@@ -127,14 +127,14 @@
 	++d->currentPage;
 
 	QList<FontInfo> fonts;
-	GooList *items = d->fontInfoScanner.scan( 1 );
+	GooList<::FontInfo*> *items = d->fontInfoScanner.scan( 1 );
 	if ( !items )
 		return fonts;
 	fonts.reserve( items->size() );
 	for ( std::size_t i = 0; i < items->size(); ++i ) {
 		fonts.append( FontInfo( FontInfoData( ( ::FontInfo* )items->get( i ) ) ) );
 	}
-	deleteGooList<::FontInfo>( items );
+	deleteGooList<::FontInfo*>( items );
 	return fonts;
 }
 
diff --git a/qt5/src/poppler-optcontent.cc b/qt5/src/poppler-optcontent.cc
index f542d25..f72981f 100644
--- a/qt5/src/poppler-optcontent.cc
+++ b/qt5/src/poppler-optcontent.cc
@@ -398,11 +398,11 @@
 
     QSet<OptContentItem *> changedItems;
 
-    const GooList *statesList = popplerLinkOCGState->getStateList();
+    const auto *statesList = popplerLinkOCGState->getStateList();
     for (std::size_t i = 0; i < statesList->size(); ++i) {
         ::LinkOCGState::StateList *stateList = (::LinkOCGState::StateList*)statesList->get(i);
 
-        GooList *refsList = stateList->list;
+        auto *refsList = stateList->list;
         for (std::size_t j = 0; j < refsList->size(); ++j) {
             Ref *ref = (Ref *)refsList->get(j);
             OptContentItem *item = d->itemFromRef(QString::number(ref->num));
diff --git a/qt5/src/poppler-page.cc b/qt5/src/poppler-page.cc
index d6f4ec3..6115b02 100644
--- a/qt5/src/poppler-page.cc
+++ b/qt5/src/poppler-page.cc
@@ -362,7 +362,7 @@
 
   if ( popplerLink )
   {
-    const GooList *nextActions = a->nextActions();
+    const GooList<::LinkAction*> *nextActions = a->nextActions();
     if ( nextActions )
     {
       QVector<Link *> links;
diff --git a/qt5/src/poppler-private.cc b/qt5/src/poppler-private.cc
index 5e8939b..d49596a 100644
--- a/qt5/src/poppler-private.cc
+++ b/qt5/src/poppler-private.cc
@@ -282,7 +282,7 @@
     }
 
 
-    void DocumentData::addTocChildren( QDomDocument * docSyn, QDomNode * parent, const GooList * items )
+    void DocumentData::addTocChildren( QDomDocument * docSyn, QDomNode * parent, const GooList<OutlineItem*> * items )
     {
         for ( std::size_t i = 0; i < items->size(); ++i )
         {
@@ -308,7 +308,7 @@
 
             // 3. recursively descend over children
             outlineItem->open();
-            const GooList * children = outlineItem->getKids();
+            const GooList<OutlineItem*> * children = outlineItem->getKids();
             if ( children )
                 addTocChildren( docSyn, &item, children );
         }
diff --git a/qt5/src/poppler-private.h b/qt5/src/poppler-private.h
index f398051..47df701 100644
--- a/qt5/src/poppler-private.h
+++ b/qt5/src/poppler-private.h
@@ -56,6 +56,7 @@
 
 class LinkDest;
 class FormWidget;
+class OutlineItem;
 
 namespace Poppler {
 
@@ -123,7 +124,7 @@
 	DocumentData(const DocumentData &) = delete;
 	DocumentData& operator=(const DocumentData &) = delete;
 	
-	void addTocChildren( QDomDocument * docSyn, QDomNode * parent, const GooList * items );
+	void addTocChildren( QDomDocument * docSyn, QDomNode * parent, const GooList<OutlineItem*> * items );
 	
 	void setPaperColor(const QColor &color)
 	{
diff --git a/splash/Splash.cc b/splash/Splash.cc
index bc71819..86b4fcd 100644
--- a/splash/Splash.cc
+++ b/splash/Splash.cc
@@ -5285,7 +5285,7 @@
 
   if(src->getSeparationList()->size() > bitmap->getSeparationList()->size()) {
     for (x = bitmap->getSeparationList()->size(); x < (int)src->getSeparationList()->size(); x++)
-      bitmap->getSeparationList()->push_back(((GfxSeparationColorSpace *)src->getSeparationList()->get(x))->copy());
+      bitmap->getSeparationList()->push_back((GfxSeparationColorSpace *)((GfxSeparationColorSpace *)src->getSeparationList()->get(x))->copy());
   }
   if (src->alpha) {
     pipeInit(&pipe, xDest, yDest, nullptr, pixel,
diff --git a/splash/SplashBitmap.cc b/splash/SplashBitmap.cc
index ada3272..8b260a0 100644
--- a/splash/SplashBitmap.cc
+++ b/splash/SplashBitmap.cc
@@ -54,7 +54,7 @@
 
 SplashBitmap::SplashBitmap(int widthA, int heightA, int rowPadA,
 			   SplashColorMode modeA, bool alphaA,
-			   bool topDown, GooList *separationListA) {
+			   bool topDown, GooList<GfxSeparationColorSpace*> *separationListA) {
   width = widthA;
   height = heightA;
   mode = modeA;
@@ -124,10 +124,10 @@
   } else {
     alpha = nullptr;
   }
-  separationList = new GooList();
+  separationList = new GooList<GfxSeparationColorSpace*>();
   if (separationListA != nullptr)
     for (std::size_t i = 0; i < separationListA->size(); i++)
-      separationList->push_back(((GfxSeparationColorSpace *) separationListA->get(i))->copy());
+      separationList->push_back((GfxSeparationColorSpace*)((GfxSeparationColorSpace *) separationListA->get(i))->copy());
 }
 
 SplashBitmap *SplashBitmap::copy(SplashBitmap *src) {
@@ -159,7 +159,7 @@
     }
   }
   gfree(alpha);
-  deleteGooList<GfxSeparationColorSpace>(separationList);
+  deleteGooList<GfxSeparationColorSpace*>(separationList);
 }
 
 
diff --git a/splash/SplashBitmap.h b/splash/SplashBitmap.h
index b824e63..4ad9b62 100644
--- a/splash/SplashBitmap.h
+++ b/splash/SplashBitmap.h
@@ -51,7 +51,7 @@
   // upside-down, i.e., with the last row first in memory.
   SplashBitmap(int widthA, int heightA, int rowPad,
 	       SplashColorMode modeA, bool alphaA,
-	       bool topDown = true, GooList *separationList = nullptr);
+	       bool topDown = true, GooList<GfxSeparationColorSpace*> *separationList = nullptr);
   static SplashBitmap *copy(SplashBitmap *src);
 
   ~SplashBitmap();
@@ -67,7 +67,7 @@
   SplashColorMode getMode() { return mode; }
   SplashColorPtr getDataPtr() { return data; }
   unsigned char *getAlphaPtr() { return alpha; }
-  GooList *getSeparationList() { return separationList; }
+  GooList<GfxSeparationColorSpace*> *getSeparationList() { return separationList; }
 
   SplashError writePNMFile(char *fileName);
   SplashError writePNMFile(FILE *f);
@@ -117,7 +117,7 @@
   SplashColorPtr data;		// pointer to row zero of the color data
   unsigned char *alpha;		// pointer to row zero of the alpha data
 				//   (always top-down)
-  GooList *separationList; // list of spot colorants and their mapping functions
+  GooList<GfxSeparationColorSpace*> *separationList; // list of spot colorants and their mapping functions
 
   friend class Splash;
 
diff --git a/utils/HtmlOutputDev.cc b/utils/HtmlOutputDev.cc
index b9f7ad0..7656f19 100644
--- a/utils/HtmlOutputDev.cc
+++ b/utils/HtmlOutputDev.cc
@@ -279,7 +279,7 @@
   yxCur1 = yxCur2 = nullptr;
   fonts=new HtmlFontAccu();
   links=new HtmlLinks();
-  imgList=new GooList();
+  imgList=new GooList<HtmlImage*>();
   pageWidth=0;
   pageHeight=0;
   fontsPageMarker = 0;
@@ -292,7 +292,7 @@
   delete DocName;
   delete fonts;
   delete links;
-  deleteGooList<HtmlImage>(imgList);
+  deleteGooList<HtmlImage*>(imgList);
 }
 
 void HtmlPage::updateFont(GfxState *state) {
@@ -1099,7 +1099,7 @@
   needClose = false;
   pages = new HtmlPage(rawOrder);
   
-  glMetaVars = new GooList();
+  glMetaVars = new GooList<HtmlMetaVar*>();
   glMetaVars->push_back(new HtmlMetaVar("generator", "pdftohtml 0.36"));
   if( author ) glMetaVars->push_back(new HtmlMetaVar("author", author));
   if( keywords ) glMetaVars->push_back(new HtmlMetaVar("keywords", keywords));
@@ -1199,7 +1199,7 @@
     delete Docname;
     delete docTitle;
 
-    deleteGooList<HtmlMetaVar>(glMetaVars);
+    deleteGooList<HtmlMetaVar*>(glMetaVars);
 
     if (fContentsFrame){
       fputs("</body>\n</html>\n",fContentsFrame);  
@@ -1687,7 +1687,7 @@
 	if (!outline)
 		return false;
 
-	const GooList *outlines = outline->getItems();
+	const GooList<OutlineItem*> *outlines = outline->getItems();
 	if (!outlines)
 		return false;
   
@@ -1744,7 +1744,7 @@
 	return true;
 }
 
-bool HtmlOutputDev::newHtmlOutlineLevel(FILE *output, const GooList *outlines, int level)
+bool HtmlOutputDev::newHtmlOutlineLevel(FILE *output, const GooList<OutlineItem*> *outlines, int level)
 {
 	bool atLeastOne = false;
 
@@ -1812,7 +1812,7 @@
 	return atLeastOne;
 }
 
-void HtmlOutputDev::newXmlOutlineLevel(FILE *output, const GooList *outlines)
+void HtmlOutputDev::newXmlOutlineLevel(FILE *output, const GooList<OutlineItem*> *outlines)
 {
     fputs("<outline>\n", output);
 
diff --git a/utils/HtmlOutputDev.h b/utils/HtmlOutputDev.h
index c097091..e5e34d2 100644
--- a/utils/HtmlOutputDev.h
+++ b/utils/HtmlOutputDev.h
@@ -51,6 +51,7 @@
 
 class GfxState;
 class GooString;
+class HtmlImage;
 class PDFDoc;
 class OutlineItem;
 //------------------------------------------------------------------------
@@ -186,7 +187,7 @@
   int fontsPageMarker; 
   HtmlFontAccu *fonts;
   HtmlLinks *links; 
-  GooList   *imgList;
+  GooList<HtmlImage*> *imgList;
   
   GooString *DocName;
   int pageWidth;
@@ -321,8 +322,8 @@
   GooString* getLinkDest(AnnotLink *link);
   void dumpMetaVars(FILE *);
   void doFrame(int firstPage);
-  bool newHtmlOutlineLevel(FILE *output, const GooList *outlines, int level = 1);
-  void newXmlOutlineLevel(FILE *output, const GooList *outlines);
+  bool newHtmlOutlineLevel(FILE *output, const GooList<OutlineItem*> *outlines, int level = 1);
+  void newXmlOutlineLevel(FILE *output, const GooList<OutlineItem*> *outlines);
   int getOutlinePageNum(OutlineItem *item);
   void drawJpegImage(GfxState *state, Stream *str);
   void drawPngImage(GfxState *state, Stream *str, int width, int height,
@@ -344,7 +345,7 @@
   int maxPageHeight;
   GooString *Docname;
   GooString *docTitle;
-  GooList *glMetaVars;
+  GooList<HtmlMetaVar*> *glMetaVars;
   Catalog *catalog;
   Page *docPage;
   std::vector<std::string> backgroundImages;
diff --git a/utils/pdffonts.cc b/utils/pdffonts.cc
index f0fcf5b..9317ca1 100644
--- a/utils/pdffonts.cc
+++ b/utils/pdffonts.cc
@@ -164,7 +164,7 @@
   // get the fonts
   {
     FontInfoScanner scanner(doc, firstPage - 1);
-    GooList *fonts = scanner.scan(lastPage - firstPage + 1);
+    GooList<FontInfo*> *fonts = scanner.scan(lastPage - firstPage + 1);
 
     if (showSubst) {
       // print the font substitutions
diff --git a/utils/printencodings.cc b/utils/printencodings.cc
index 1a6d5e2..6c37ab1 100644
--- a/utils/printencodings.cc
+++ b/utils/printencodings.cc
@@ -26,7 +26,7 @@
 
 void printEncodings()
 {
-  GooList *encNames = globalParams->getEncodingNames();
+  GooList<GooString*> *encNames = globalParams->getEncodingNames();
 
   std::sort(encNames->begin(), encNames->end(), [](void *lhs, void *rhs) {
     return static_cast<GooString *>(lhs)->cmp(static_cast<GooString *>(rhs)) < 0;