diff --git a/src/starsphere/EinsteinRadioAdapter.cpp b/src/starsphere/EinsteinRadioAdapter.cpp
index 2c163c994b314436244a4470ee4639ed05c43bf6..3c609c36c7323581d49ed112c1c6475f8d608f40 100644
--- a/src/starsphere/EinsteinRadioAdapter.cpp
+++ b/src/starsphere/EinsteinRadioAdapter.cpp
@@ -19,9 +19,8 @@
  ***************************************************************************/
 
 #include "EinsteinRadioAdapter.h"
-#include "Libxml2Adapter.h"
 
-#include <cstdlib>
+#include <sstream>
 
 const string EinsteinRadioAdapter::SharedMemoryIdentifier = "EinsteinRadio";
 
@@ -29,7 +28,7 @@ EinsteinRadioAdapter::EinsteinRadioAdapter(BOINCClientAdapter *boincClient) :
 	m_WUTemplatePowerSpectrum(POWERSPECTRUM_BINS, 0)
 {
 	this->boincClient = boincClient;
-	m_xmlIFace = new Libxml2Adapter();
+	m_xmlReader = NULL;
 
 	m_WUSkyPosRightAscension = 0.0;
 	m_WUSkyPosDeclination = 0.0;
@@ -39,7 +38,8 @@ EinsteinRadioAdapter::EinsteinRadioAdapter(BOINCClientAdapter *boincClient) :
 
 EinsteinRadioAdapter::~EinsteinRadioAdapter()
 {
-	if(m_xmlIFace) delete m_xmlIFace;
+	if(m_xmlReader) xmlFreeTextReader(m_xmlReader);
+    xmlCleanupParser();
 }
 
 void EinsteinRadioAdapter::refresh()
@@ -50,58 +50,68 @@ void EinsteinRadioAdapter::refresh()
 
 void EinsteinRadioAdapter::parseApplicationInformation()
 {
-	string spectrumString;
-
 	// get updated application information
 	string info = boincClient->applicationInformation();
 
 	// do we have any data?
 	if(info.length() > 0) {
-		string temp;
-
-		// TODO: SAX-style xmlReader could be an alternative to this (wrt performance)!
-
-		// parse data into members
-		m_xmlIFace->setXmlDocument(info, "http://einstein.phys.uwm.edu");
-		temp = m_xmlIFace->getSingleNodeContentByXPath("/graphics_info/skypos_rac");
-		m_WUSkyPosRightAscension = strtod(temp.c_str(), NULL);
-		temp = m_xmlIFace->getSingleNodeContentByXPath("/graphics_info/skypos_dec");
-		m_WUSkyPosDeclination = strtod(temp.c_str(), NULL);
-		temp = m_xmlIFace->getSingleNodeContentByXPath("/graphics_info/dispersion");
-		m_WUDispersionMeasure = strtod(temp.c_str(), NULL);
-		temp = m_xmlIFace->getSingleNodeContentByXPath("/graphics_info/orb_radius");
-		m_WUTemplateOrbitalRadius = strtod(temp.c_str(), NULL);
-		temp = m_xmlIFace->getSingleNodeContentByXPath("/graphics_info/orb_period");
-		m_WUTemplateOrbitalPeriod = strtod(temp.c_str(), NULL);
-		temp = m_xmlIFace->getSingleNodeContentByXPath("/graphics_info/orb_phase");
-		m_WUTemplateOrbitalPhase = strtod(temp.c_str(), NULL);
-		spectrumString = m_xmlIFace->getSingleNodeContentByXPath("/graphics_info/power_spectrum");
-		temp = m_xmlIFace->getSingleNodeContentByXPath("/graphics_info/fraction_done");
-		m_WUFractionDone = strtod(temp.c_str(), NULL);
-		temp = m_xmlIFace->getSingleNodeContentByXPath("/graphics_info/cpu_time");
-		m_WUCPUTime = strtod(temp.c_str(), NULL);
-
-		// TODO: make sure parsing worked flawlessly (only spectrum is checked below!)
+		int result = 0;
+
+		// prepare conversion stream
+		stringstream converter;
+		converter.precision(3);
+		converter.exceptions(ios_base::badbit | ios_base::failbit);
+
+		if(!m_xmlReader) {
+			// set up SAX style XML reader (create instance)
+			m_xmlReader = xmlReaderForMemory(info.c_str(),
+											 info.length(),
+											 "http://einstein.phys.uwm.edu",
+											 "UTF-8",
+											 0);
+			if(!m_xmlReader) {
+				cerr << "Error creating XML reader for shared memory data!" << endl;
+				return;
+			}
+		}
+		else {
+			// set up SAX style XML reader (reusing existing instance)
+			if(xmlReaderNewMemory(m_xmlReader,
+								  info.c_str(),
+								  info.length(),
+								  "http://einstein.phys.uwm.edu",
+								  "UTF-8",
+								  0))
+			{
+				cerr << "Error updating XML reader for shared memory data!" << endl;
+				return;
+			}
+		}
+
+		// parse XML fragment and process nodes
+        result = xmlTextReaderRead(m_xmlReader);
+        while (result == 1) {
+        	processXmlNode(m_xmlReader, converter);
+            result = xmlTextReaderRead(m_xmlReader);
+        }
 
 		// convert radians to degrees
 		m_WUSkyPosRightAscension *= 180/PI;
 		m_WUSkyPosDeclination *= 180/PI;
 
 		// deserialize power spectrum data
-		if(spectrumString.length() == POWERSPECTRUM_BIN_BYTES) {
+		if(m_WUTemplatePowerSpectrumString.length() == POWERSPECTRUM_BIN_BYTES) {
 			int spectrumBinValue;
-			// prepare hex to int conversion stream
-			istringstream spectrumBinStream;
-			spectrumBinStream.exceptions(ios_base::badbit | ios_base::failbit);
+;
 			// iterate over all bins
 			for(int i = 0, j = 0; i < POWERSPECTRUM_BIN_BYTES; i += 2, ++j) {
 				try {
-					spectrumBinStream.str(spectrumString.substr(i, 2));
+					converter.clear();
+					converter.str(m_WUTemplatePowerSpectrumString.substr(i, 2));
 					// convert hex bin value to integer
-					spectrumBinStream >> hex >> spectrumBinValue;
+					converter >> hex >> spectrumBinValue;
 					// store bin power value
 					m_WUTemplatePowerSpectrum.at(j) = (unsigned char) spectrumBinValue;
-					spectrumBinStream.clear();
 				}
 				catch(ios_base::failure) {
 					cerr << "Error processing power spectrum shared memory data!" << endl;
@@ -116,6 +126,75 @@ void EinsteinRadioAdapter::parseApplicationInformation()
 	}
 }
 
+void EinsteinRadioAdapter::processXmlNode(const xmlTextReaderPtr xmlReader, stringstream& converter)
+{
+	// we only parse element nodes
+    if(xmlTextReaderNodeType(xmlReader) != XML_READER_TYPE_ELEMENT) return;
+
+    // buffers (will be deallocated automatically)
+    const xmlChar *nodeName = NULL, *nodeValue = NULL;
+
+    // get element node's name
+    nodeName = xmlTextReaderConstLocalName(xmlReader);
+
+    if (nodeName == NULL) {
+		cerr << "Error parsing XML node (invalid name)" << endl;
+		return;
+    }
+
+	// move to node's text content (child node) or return if unavailable
+	if(! (xmlTextReaderRead(m_xmlReader) && xmlTextReaderHasValue(xmlReader))) {
+		return;
+	}
+
+	// get text node's value
+	nodeValue = xmlTextReaderConstValue(xmlReader);
+
+	if (nodeValue == NULL) {
+		cerr << "Error parsing XML node (invalid value)" << endl;
+		return;
+	}
+
+    try {
+        // prepare converter stream
+        converter.clear();
+        converter.str("");
+        converter << nodeValue;
+
+		// assign node value to respective data member
+		if(xmlStrEqual(nodeName, BAD_CAST("skypos_rac"))) {
+			converter >> fixed >> m_WUSkyPosRightAscension;
+		}
+		else if(xmlStrEqual(nodeName, BAD_CAST("skypos_dec"))) {
+			converter >> fixed >> m_WUSkyPosDeclination;
+		}
+		else if(xmlStrEqual(nodeName, BAD_CAST("dispersion"))) {
+			converter >> fixed >> m_WUDispersionMeasure;
+		}
+		else if(xmlStrEqual(nodeName, BAD_CAST("orb_radius"))) {
+			converter >> fixed >> m_WUTemplateOrbitalRadius;
+		}
+		else if(xmlStrEqual(nodeName, BAD_CAST("orb_period"))) {
+			converter >> fixed >> m_WUTemplateOrbitalPeriod;
+		}
+		else if(xmlStrEqual(nodeName, BAD_CAST("orb_phase"))) {
+			converter >> fixed >> m_WUTemplateOrbitalPhase;
+		}
+		else if(xmlStrEqual(nodeName, BAD_CAST("power_spectrum"))) {
+			converter >> m_WUTemplatePowerSpectrumString;
+		}
+		else if(xmlStrEqual(nodeName, BAD_CAST("fraction_done"))) {
+			converter >> fixed >> m_WUFractionDone;
+		}
+		else if(xmlStrEqual(nodeName, BAD_CAST("cpu_time"))) {
+			converter >> fixed >> m_WUCPUTime;
+		}
+    }
+    catch(ios_base::failure) {
+    	cerr << "Error converting XML reader node content!" << endl;
+    }
+}
+
 double EinsteinRadioAdapter::wuSkyPosRightAscension() const
 {
 	return m_WUSkyPosRightAscension;
diff --git a/src/starsphere/EinsteinRadioAdapter.h b/src/starsphere/EinsteinRadioAdapter.h
index 3970126380a7bd7181da0cf6c080cef4a1a7e830..a5330983ba5890fc1a130e1ad16910903f3d03b5 100644
--- a/src/starsphere/EinsteinRadioAdapter.h
+++ b/src/starsphere/EinsteinRadioAdapter.h
@@ -25,8 +25,9 @@
 #include <sstream>
 #include <iomanip>
 
+#include <libxml/xmlreader.h>
+
 #include "BOINCClientAdapter.h"
-#include "XMLProcessorInterface.h"
 
 using namespace std;
 
@@ -150,11 +151,25 @@ private:
 	 */
 	void parseApplicationInformation();
 
+	/**
+	 * \brief Processes single element nodes found by the XML parser
+	 *
+	 * This method can sort of resembles the callback method used in conjunction with SAX parsers.
+	 * It's called to process single XML nodes (in our case element nodes only) encountered
+	 * during XML document (tree) traversal.
+	 *
+	 * \param xmlReader The pointer to the current xmlReader instance
+	 * \param converter Reference to an existing string stream for value/type conversion
+	 *
+	 * \see parseApplicationInformation()
+	 */
+	void processXmlNode(const xmlTextReaderPtr xmlReader, stringstream& converter);
+
 	/// Pointer to the (parent) BOINC client adapter
 	BOINCClientAdapter *boincClient;
 
-	/// Pointer to the XML processor
-	XMLProcessorInterface* m_xmlIFace;
+	/// Pointer to the XML reader (SAX style)
+	xmlTextReaderPtr m_xmlReader;
 
 	/// Right ascension of the currently searched sky position (in degrees)
 	double m_WUSkyPosRightAscension;
@@ -174,7 +189,10 @@ private:
 	/// Initial orbital phase of the currently active template
 	double m_WUTemplateOrbitalPhase;
 
-	/// Power spectrum of the currently active template
+	/// Power spectrum of the currently active template (string)
+	string m_WUTemplatePowerSpectrumString;
+
+	/// Power spectrum of the currently active template (values)
 	vector<unsigned char> m_WUTemplatePowerSpectrum;
 
 	/// The completion fraction of the active work unit