diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
index f62a9813f..4c759a319 100644
--- a/cmake/CMakeLists.txt
+++ b/cmake/CMakeLists.txt
@@ -310,7 +310,8 @@ if(WASM_BUILD)
 else()
     # @todo review this, shouldn't this be all possible header-only now?
     # ... or rewritten using C++17 features?
-    set(BOOST_COMPONENTS system program_options regex thread date_time iostreams)
+    # set(BOOST_COMPONENTS system program_options regex thread date_time iostreams)
+    set(BOOST_COMPONENTS program_options regex thread date_time iostreams)
 endif()
 
 if(USE_MMAP)
diff --git a/src/ifcgeom/Iterator.cpp b/src/ifcgeom/Iterator.cpp
index 31f7427ce..5224bc9a6 100644
--- a/src/ifcgeom/Iterator.cpp
+++ b/src/ifcgeom/Iterator.cpp
@@ -46,10 +46,17 @@ bool IfcGeom::Iterator::initialize() {
 			if (!res.item) {
 				continue;
 			}
-			std::transform(task.products.begin(), task.products.end(), std::back_inserter(res.products), [this, &res](const express::Base& prod) {
+			for (auto& prod : task.products) {
 				auto prod_item = converter_->mapping()->map(prod);
-				return std::make_pair(prod, ifcopenshell::geometry::taxonomy::cast<ifcopenshell::geometry::taxonomy::geom_item>(prod_item)->matrix);
-			});
+				if (!prod_item) {
+					continue;
+				}
+				auto gi = ifcopenshell::geometry::taxonomy::cast<ifcopenshell::geometry::taxonomy::geom_item>(prod_item);
+				if (!gi) {
+					continue;
+				}
+				res.products.push_back(std::make_pair(prod, gi->matrix));
+			}
 		}
 		tasks_.push_back(res);
 	}
@@ -349,13 +356,27 @@ void IfcGeom::Iterator::create_element_(ifcopenshell::geometry::Converter* kerne
 		if (!rep->item) {
 			return;
 		}
-		std::transform(rep->products_2.begin(), rep->products_2.end(), std::back_inserter(rep->products), [this, &rep, kernel](const express::Base& prod) {
+		for (auto& prod : rep->products_2) {
 			auto prod_item = kernel->mapping()->map(prod);
-			return std::make_pair(prod, ifcopenshell::geometry::taxonomy::cast<ifcopenshell::geometry::taxonomy::geom_item>(prod_item)->matrix);
-		});
+			if (!prod_item) {
+				Logger::Notice("create_element_: map(product #" + std::to_string(prod.id()) + ") returned null");
+				continue;
+			}
+			auto gi = ifcopenshell::geometry::taxonomy::cast<ifcopenshell::geometry::taxonomy::geom_item>(prod_item);
+			if (!gi) {
+				Logger::Notice("create_element_: cast<geom_item> failed for product #" + std::to_string(prod.id()));
+				continue;
+			}
+			rep->products.push_back(std::make_pair(prod, gi->matrix));
+		}
 	} else {
 	}
 
+	if (rep->products.empty()) {
+		Logger::Notice("create_element_: products empty after mapping");
+		return;
+	}
+
 	auto product_node = rep->products.front();
 	const express::Base product = product_node.first;
 	const auto& place = product_node.second;
diff --git a/src/ifcgeom/mapping/mapping.cpp b/src/ifcgeom/mapping/mapping.cpp
index d8b3e43d7..be0250dd9 100644
--- a/src/ifcgeom/mapping/mapping.cpp
+++ b/src/ifcgeom/mapping/mapping.cpp
@@ -228,9 +228,10 @@ void mapping::get_representations(std::vector<geometry_conversion_task>& tasks,
     int task_index = 0;
     
     for (auto representation : representations) {
+      try {
         IfcSchema::IfcRepresentationMap rmap;
         std::vector<IfcSchema::IfcProduct> ifcproducts = filter_products(products_represented_by(representation, rmap, false), filters);
-        
+
         if (ifcproducts.empty()) {
             continue;
         }
@@ -286,6 +287,9 @@ void mapping::get_representations(std::vector<geometry_conversion_task>& tasks,
             task.products.insert(task.products.end(), ifcproducts.begin(), ifcproducts.end());
             tasks.emplace_back(task);
         }
+      } catch (const std::exception& e) {
+        Logger::Error("get_representations: exception processing rep #" + std::to_string(representation.id()) + ": " + e.what());
+      }
     }
 }
 
diff --git a/src/ifcparse/FileReader.cpp b/src/ifcparse/FileReader.cpp
index f5fa47f61..590b7244f 100644
--- a/src/ifcparse/FileReader.cpp
+++ b/src/ifcparse/FileReader.cpp
@@ -67,6 +67,11 @@ FullBufferImpl::FullBufferImpl(const std::string& fn) {
     fclose(stream);
 }
 
+FullBufferImpl::FullBufferImpl(void* data, size_t length)
+    : buf_(static_cast<char*>(data), static_cast<char*>(data) + length)
+    , size_(length) {
+}
+
 size_t FullBufferImpl::size() const { return size_; }
 
 char FullBufferImpl::get(size_t pos) const {
diff --git a/src/ifcparse/FileReader.h b/src/ifcparse/FileReader.h
index 0bbd9601a..5ebd21bec 100644
--- a/src/ifcparse/FileReader.h
+++ b/src/ifcparse/FileReader.h
@@ -103,6 +103,15 @@ public:
         }
     }
 
+    FileReader(void* data, size_t length)
+        : cursor_(0) {
+        if constexpr (std::is_same_v<Impl, FullBufferImpl>) {
+            impl_ = std::make_shared<Impl>(data, length);
+        } else {
+            static_assert(file_reader_dependent_false_v<Impl>, "This FileReader constructor is not supported for the selected backend");
+        }
+    }
+
     FileReader(const std::string& fn, size_t page_size, size_t page_capacity)
         : cursor_(0) {
         if constexpr (std::is_same_v<Impl, PagedFileImpl>) {
@@ -192,6 +201,7 @@ private:
 class IFC_PARSE_API FullBufferImpl {
 public:
     explicit FullBufferImpl(const std::string& fn);
+    FullBufferImpl(void* data, size_t length);
 
     size_t size() const;
     char get(size_t pos) const;
diff --git a/src/ifcparse/IfcParse.cpp b/src/ifcparse/IfcParse.cpp
index 99a792d3f..0a62a64d6 100644
--- a/src/ifcparse/IfcParse.cpp
+++ b/src/ifcparse/IfcParse.cpp
@@ -1551,8 +1551,11 @@ IfcParse::InstanceStreamer<Reader>::InstanceStreamer(IfcParse::IfcFile* f)
 
     if constexpr (std::is_same_v<Reader, FileReader<PushedSequentialImpl>>) {
         owned_stream_ = std::make_unique<Reader>(caller_fed_tag{});
+    } else if constexpr (std::is_same_v<Reader, FileReader<FullBufferImpl>>) {
+        // Empty buffer; caller is expected to use stream_from_string or similar
+        owned_stream_ = std::make_unique<Reader>(nullptr, (size_t)0);
     } else {
-        static_assert(file_reader_dependent_false_v<Reader>, "Default InstanceStreamer requires a pushed sequential reader");
+        static_assert(file_reader_dependent_false_v<Reader>, "Default InstanceStreamer requires a pushed sequential or full buffer reader");
     }
 
     stream_ = owned_stream_.get();
@@ -1603,8 +1606,10 @@ IfcParse::InstanceStreamer<Reader>::InstanceStreamer(void* data, int length, Ifc
 
     if constexpr (std::is_same_v<Reader, FileReader<PushedSequentialImpl>>) {
         owned_stream_ = std::make_unique<Reader>(std::string((char*)data, length), caller_fed_tag{});
+    } else if constexpr (std::is_same_v<Reader, FileReader<FullBufferImpl>>) {
+        owned_stream_ = std::make_unique<Reader>(data, (size_t)length);
     } else {
-        static_assert(file_reader_dependent_false_v<Reader>, "Buffer-based InstanceStreamer requires a pushed sequential reader");
+        static_assert(file_reader_dependent_false_v<Reader>, "Buffer-based InstanceStreamer requires a pushed sequential or full buffer reader");
     }
 
     stream_ = owned_stream_.get();
@@ -1741,6 +1746,44 @@ std::optional<std::tuple<size_t, const IfcParse::declaration*, std::shared_ptr<I
     return return_value;
 }
 
+// FullBufferImpl: all constructors now supported
+template IfcParse::InstanceStreamer<FileReader<FullBufferImpl>>::InstanceStreamer(IfcParse::IfcFile*);
+template IfcParse::InstanceStreamer<FileReader<FullBufferImpl>>::InstanceStreamer(const std::string&, bool, IfcParse::IfcFile*);
+template IfcParse::InstanceStreamer<FileReader<FullBufferImpl>>::InstanceStreamer(void*, int, IfcParse::IfcFile*);
+template IfcParse::InstanceStreamer<FileReader<FullBufferImpl>>::InstanceStreamer(FileReader<FullBufferImpl>*, IfcParse::IfcFile*);
+template IfcSpfHeader& IfcParse::InstanceStreamer<FileReader<FullBufferImpl>>::ensure_header();
+template void IfcParse::InstanceStreamer<FileReader<FullBufferImpl>>::initialize_header();
+template bool IfcParse::InstanceStreamer<FileReader<FullBufferImpl>>::hasSemicolon() const;
+template size_t IfcParse::InstanceStreamer<FileReader<FullBufferImpl>>::semicolonCount() const;
+template void IfcParse::InstanceStreamer<FileReader<FullBufferImpl>>::pushPage(const std::string&);
+template void IfcParse::InstanceStreamer<FileReader<FullBufferImpl>>::bypassTypes(const std::set<std::string>&);
+template std::optional<std::tuple<size_t, const IfcParse::declaration*, std::shared_ptr<InstanceData>>> IfcParse::InstanceStreamer<FileReader<FullBufferImpl>>::readInstance();
+
+// PushedSequentialImpl: default, buffer-based, and stream-based constructors
+template IfcParse::InstanceStreamer<FileReader<PushedSequentialImpl>>::InstanceStreamer(IfcParse::IfcFile*);
+template IfcParse::InstanceStreamer<FileReader<PushedSequentialImpl>>::InstanceStreamer(void*, int, IfcParse::IfcFile*);
+template IfcParse::InstanceStreamer<FileReader<PushedSequentialImpl>>::InstanceStreamer(FileReader<PushedSequentialImpl>*, IfcParse::IfcFile*);
+template IfcSpfHeader& IfcParse::InstanceStreamer<FileReader<PushedSequentialImpl>>::ensure_header();
+template void IfcParse::InstanceStreamer<FileReader<PushedSequentialImpl>>::initialize_header();
+template bool IfcParse::InstanceStreamer<FileReader<PushedSequentialImpl>>::hasSemicolon() const;
+template size_t IfcParse::InstanceStreamer<FileReader<PushedSequentialImpl>>::semicolonCount() const;
+template void IfcParse::InstanceStreamer<FileReader<PushedSequentialImpl>>::pushPage(const std::string&);
+template void IfcParse::InstanceStreamer<FileReader<PushedSequentialImpl>>::bypassTypes(const std::set<std::string>&);
+template std::optional<std::tuple<size_t, const IfcParse::declaration*, std::shared_ptr<InstanceData>>> IfcParse::InstanceStreamer<FileReader<PushedSequentialImpl>>::readInstance();
+
+#ifdef USE_MMAP
+// MMapFileReader: only path-based and stream-based constructors
+template IfcParse::InstanceStreamer<MMapFileReader>::InstanceStreamer(const std::string&, bool, IfcParse::IfcFile*);
+template IfcParse::InstanceStreamer<MMapFileReader>::InstanceStreamer(MMapFileReader*, IfcParse::IfcFile*);
+template IfcSpfHeader& IfcParse::InstanceStreamer<MMapFileReader>::ensure_header();
+template void IfcParse::InstanceStreamer<MMapFileReader>::initialize_header();
+template bool IfcParse::InstanceStreamer<MMapFileReader>::hasSemicolon() const;
+template size_t IfcParse::InstanceStreamer<MMapFileReader>::semicolonCount() const;
+template void IfcParse::InstanceStreamer<MMapFileReader>::pushPage(const std::string&);
+template void IfcParse::InstanceStreamer<MMapFileReader>::bypassTypes(const std::set<std::string>&);
+template std::optional<std::tuple<size_t, const IfcParse::declaration*, std::shared_ptr<InstanceData>>> IfcParse::InstanceStreamer<MMapFileReader>::readInstance();
+#endif
+
 template <typename Reader>
 void IfcParse::impl::in_memory_file_storage::read_from_stream(Reader* s, const IfcParse::schema_definition*& schema, unsigned int& max_id, const std::set<std::string>& typed_to_bypass) {
     init_locale();
@@ -1853,7 +1896,7 @@ void IfcParse::impl::in_memory_file_storage::read_from_stream(Reader* s, const I
                     auto& storage = byid_[p.first.name_];
                     auto attr_index = p.first.index_;
                     
-                    if (storage->has_attribute_value<express::Base>(attr_index)) {
+                    if (storage->template has_attribute_value<express::Base>(attr_index)) {
                         express::Base inst = storage->get_attribute_value(attr_index);
                         if (!inst.declaration().as_entity()) {
                             // Probably a case of IfcPropertySetDefinitionSet, divert storage of reference to the simply type instance
@@ -1862,7 +1905,7 @@ void IfcParse::impl::in_memory_file_storage::read_from_stream(Reader* s, const I
                         }
                     }
 
-                    if (storage->has_attribute_value<Blank>(attr_index)) {
+                    if (storage->template has_attribute_value<Blank>(attr_index)) {
                         storage->set_attribute_value(attr_index, express::Base(it->second));
                     } else {
                         Logger::Error("Duplicate definition for instance reference");
@@ -1893,7 +1936,7 @@ void IfcParse::impl::in_memory_file_storage::read_from_stream(Reader* s, const I
             auto& storage = byid_[p.first.name_];
             auto attr_index = p.first.index_;
             
-            if (storage->has_attribute_value<express::Base>(attr_index)) {
+            if (storage->template has_attribute_value<express::Base>(attr_index)) {
                 express::Base inst = storage->get_attribute_value(attr_index);
                 if (!inst.declaration().as_entity()) {
                     // Probably a case of IfcPropertySetDefinitionSet, divert storage of reference to the simply type instance
@@ -1902,7 +1945,7 @@ void IfcParse::impl::in_memory_file_storage::read_from_stream(Reader* s, const I
                 }
             }
 
-            if (storage->has_attribute_value<Blank>(attr_index)) {
+            if (storage->template has_attribute_value<Blank>(attr_index)) {
                 storage->set_attribute_value(attr_index, instances);
             } else {
                 Logger::Error("Duplicate definition for instance reference");
@@ -1931,7 +1974,7 @@ void IfcParse::impl::in_memory_file_storage::read_from_stream(Reader* s, const I
             auto& storage = byid_[p.first.name_];
             auto attr_index = p.first.index_;
             
-            if (storage->has_attribute_value<express::Base>(attr_index)) {
+            if (storage->template has_attribute_value<express::Base>(attr_index)) {
                 express::Base inst = storage->get_attribute_value(attr_index);
                 if (!inst.declaration().as_entity()) {
                     // Probably a case of IfcPropertySetDefinitionSet, divert storage of reference to the simply type instance
@@ -1940,7 +1983,7 @@ void IfcParse::impl::in_memory_file_storage::read_from_stream(Reader* s, const I
                 }
             }
 
-            if (storage->has_attribute_value<Blank>(attr_index)) {
+            if (storage->template has_attribute_value<Blank>(attr_index)) {
                 storage->set_attribute_value(attr_index, instances);
             } else {
                 Logger::Error("Duplicate definition for instance reference");
diff --git a/src/ifcparse/storage.h b/src/ifcparse/storage.h
index 41680d6c9..6f0c8054b 100644
--- a/src/ifcparse/storage.h
+++ b/src/ifcparse/storage.h
@@ -31,6 +31,7 @@ namespace rocksdb {
 #include <iterator>
 #include <type_traits>
 #include <iostream>
+#include <deque>
 #include <vector>
 #include <list>
 #include <set>
@@ -250,7 +251,7 @@ namespace IfcParse {
     };
 
     struct parse_context_pool {
-        std::vector<parse_context> nodes_;
+        std::deque<parse_context> nodes_;
         uint32_t used_ = 0;
 
         void reset() { used_ = 0; }
