diff --git a/DDReconstruction/CMakeLists.txt b/DDReconstruction/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..0b7321230d3c4f22f67ba083c922cf74cf551bb7
--- /dev/null
+++ b/DDReconstruction/CMakeLists.txt
@@ -0,0 +1,72 @@
+cmake_minimum_required(VERSION 2.8.3 FATAL_ERROR)
+
+#---------------------------
+set( PackageName DDReconstruction )
+#---------------------------
+
+project(${PackageName})
+
+# project version
+SET( ${PackageName}_VERSION_MAJOR 0 )
+SET( ${PackageName}_VERSION_MINOR 0 )
+SET( ${PackageName}_VERSION_PATCH 1 )
+
+SET( ${PackageName}_VERSION "${${PackageName}_VERSION_MAJOR}.${${PackageName}_VERSION_MINOR}" )
+SET( ${PackageName}_SOVERSION "${${PackageName}_VERSION_MAJOR}.${${PackageName}_VERSION_MINOR}" )
+
+set(CMAKE_MODULE_PATH  ${CMAKE_MODULE_PATH}  ${CMAKE_SOURCE_DIR}/cmake ) 
+set(LIBRARY_OUTPUT_PATH    ${PROJECT_BINARY_DIR}/lib)
+set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
+
+#------------- set the default installation directory to be the source directory
+
+IF(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
+  SET( CMAKE_INSTALL_PREFIX ${CMAKE_SOURCE_DIR} CACHE PATH  
+    "install prefix path  - overwrite with -D CMAKE_INSTALL_PREFIX = ..." 
+    FORCE )
+  MESSAGE(STATUS "CMAKE_INSTALL_PREFIX is ${CMAKE_INSTALL_PREFIX} - overwrite with -D CMAKE_INSTALL_PREFIX" )
+ENDIF(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
+
+
+#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+find_package( DD4hep ) 
+
+set(CMAKE_MODULE_PATH  ${CMAKE_MODULE_PATH}  ${DD4hep_ROOT}/cmake ) 
+include( DD4hep )
+
+find_package( ROOT REQUIRED )
+#find_package( ROOT REQUIRED COMPONENTS Geom Reflex)
+#set( ROOT_COMPONENT_LIBRARIES Geom Reflex)
+
+#-------------------------------------------------------------
+# add additional packages here
+
+
+include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/include
+    ${DD4hep_INCLUDE_DIRS}
+    ${ROOT_INCLUDE_DIR} )
+
+file(GLOB sources src/*.cpp)
+
+add_library(DDReconstruction SHARED ${sources})
+
+target_link_libraries(DDReconstruction ${DD4hep_LIBRARIES} ${ROOT_LIBRARIES} ${ROOT_COMPONENT_LIBRARIES})
+
+add_executable(IDDecoderTest src/IDDecoderTest.cpp ${sources})
+
+target_link_libraries(IDDecoderTest ${PackageName} ${DD4hep_LIBRARIES} DDReconstruction ${ROOT_LIBRARIES} ${ROOT_COMPONENT_LIBRARIES})
+
+#SET(CMAKE_CXX_FLAGS "-Wall -Wextra -pedantic -Wno-long-long")
+#SET_TARGET_PROPERTIES( DDReconstruction PROPERTIES VERSION ${DD4hep_VERSION} SOVERSION ${DD4hep_SOVERSION})
+
+install(DIRECTORY include/DDReconstruction
+  DESTINATION include
+  PATTERN ".svn" EXCLUDE )
+
+install(TARGETS DDReconstruction
+  RUNTIME DESTINATION bin
+  LIBRARY DESTINATION lib
+  )
+# to do: add corresponding uninstall...
+#-------------------------------------------------------
diff --git a/DDReconstruction/include/DDReconstruction/API/IDDecoder.h b/DDReconstruction/include/DDReconstruction/API/IDDecoder.h
new file mode 100644
index 0000000000000000000000000000000000000000..fa9374b79585b73bbe3c9850d65a1de0533b3fc6
--- /dev/null
+++ b/DDReconstruction/include/DDReconstruction/API/IDDecoder.h
@@ -0,0 +1,114 @@
+/*
+ * IDDecoder.h
+ *
+ *  Created on: Dec 12, 2013
+ *      Author: Christian Grefe, CERN
+ */
+
+#ifndef IDDECODER_H_
+#define IDDECODER_H_
+
+#include "DD4hep/Readout.h"
+#include "DD4hep/VolumeManager.h"
+
+#include "DDSegmentation/Segmentation.h"
+
+#include <set>
+#include <string>
+
+namespace DD4hep {
+
+class IDDecoder {
+public:
+	/**
+	 * Default constructor using the name of the corresponding readout collection
+	 */
+	IDDecoder(const std::string& collectionName);
+
+	/**
+	 * Default constructor using a readout object
+	 */
+	IDDecoder(const Geometry::Readout& readout);
+
+	/**
+	 * Destructor
+	 */
+	virtual ~IDDecoder();
+
+	/**
+	 * Returns the cell ID from the local position in the given volume ID.
+	 */
+	CellID cellIDFromLocal(const Geometry::Position& local, const VolumeID volumeID) const;
+
+	/**
+	 * Returns the global cell ID from a given global position
+	 */
+	CellID cellID(const Geometry::Position& global) const;
+
+	/**
+	 * Returns the global position from a given cell ID
+	 */
+	Geometry::Position position(const CellID& cellID) const;
+
+	/*
+	 * Returns the local position from a given cell ID
+	 */
+	Geometry::Position localPosition(const CellID& cellID) const;
+
+	/*
+	 * Returns the volume ID of a given cell ID
+	 */
+	VolumeID volumeID(const CellID& cellID) const;
+
+	/*
+	 * Returns the volume ID of a given global position
+	 */
+	VolumeID volumeID(const Geometry::Position& global) const;
+
+	/*
+	 * Returns the placement for a given cell ID
+	 */
+	Geometry::PlacedVolume placement(const CellID& cellID) const;
+
+	/*
+	 * Returns the placement for a given global position
+	 */
+	Geometry::PlacedVolume placement(const Geometry::Position& global) const;
+
+	/*
+	 * Returns the subdetector for a given cell ID
+	 */
+	Geometry::DetElement subDetector(const CellID& cellID) const;
+
+	/*
+	 * Returns the subdetector for a given global position
+	 */
+	Geometry::DetElement subDetector(const Geometry::Position& global) const;
+
+	/*
+	 * Returns the closest detector element in the hierarchy for a given cell ID
+	 */
+	Geometry::DetElement detectorElement(const CellID& cellID) const;
+
+	/*
+	 * Returns the closest detector element in the hierarchy for a given global position
+	 */
+	Geometry::DetElement detectorElement(const Geometry::Position& global) const;
+
+	/*
+	 * Calculates the neighbours of the given cell ID and adds them to the list of neighbours
+	 */
+	void neighbours(const CellID& cellID, std::set<CellID>& neighbours) const;
+
+	/*
+	 * Checks if the given cell IDs are neighbours
+	 */
+	bool areNeighbours(const CellID& cellID, const CellID& otherCellID) const;
+
+protected:
+	Geometry::Readout _readout;
+	Geometry::VolumeManager _volumeManager;
+};
+
+} /* namespace DD4hep */
+#endif /* IDDECODER_H_ */
diff --git a/DDReconstruction/src/IDDecoder.cpp b/DDReconstruction/src/IDDecoder.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..83aecc17414853e4648bdaac42452f4f035a41df
--- /dev/null
+++ b/DDReconstruction/src/IDDecoder.cpp
@@ -0,0 +1,173 @@
+/*
+ * IDDecoder.cpp
+ *
+ *  Created on: Dec 12, 2013
+ *      Author: Christian Grefe, CERN
+ */
+
+#include "DDReconstruction/API/IDDecoder.h"
+#include "DD4hep/LCDD.h"
+#include "DD4hep/VolumeManager.h"
+
+namespace DD4hep {
+
+using Geometry::DetElement;
+using Geometry::LCDD;
+using Geometry::PlacedVolume;
+using Geometry::Position;
+using Geometry::Readout;
+using Geometry::VolumeManager;
+using std::set;
+
+/**
+ * Default constructor using the name of the corresponding readout collection
+ */
+IDDecoder::IDDecoder(const std::string& collectionName) {
+	LCDD& lcdd = LCDD::getInstance();
+	_readout = lcdd.readout(collectionName);
+	_volumeManager = lcdd.volumeManager();
+	if (not _volumeManager.isValid()) {
+		_volumeManager = VolumeManager(lcdd, "volman", lcdd.world(), Readout(), VolumeManager::TREE);
+	}
+}
+
+/**
+ * Default constructor using a readout object
+ */
+IDDecoder::IDDecoder(const Readout& readout) {
+	LCDD& lcdd = LCDD::getInstance();
+	_readout = readout;
+	_volumeManager = lcdd.volumeManager();
+	if (not _volumeManager.isValid()) {
+		_volumeManager = VolumeManager(lcdd, "volman", lcdd.world(), Readout(), VolumeManager::TREE);
+	}
+}
+
+/**
+ * Destructor
+ */
+IDDecoder::~IDDecoder() {
+}
+
+/**
+ * Returns the cell ID from the local position in the given volume ID.
+ */
+CellID IDDecoder::cellIDFromLocal(const Position& local, const VolumeID volumeID) const {
+	double l[3];
+	double g[3];
+	local.GetCoordinates(l);
+	const TGeoMatrix& localToGlobal = _volumeManager.worldTransformation(volumeID);
+	localToGlobal.LocalToMaster(l, g);
+	Position global(g[0], g[1], g[2]);
+	return _readout.segmentation().cellID(local, global, volumeID);
+}
+
+/**
+ * Returns the global cell ID from a given global position
+ */
+CellID IDDecoder::cellID(const Position& global) const {
+	VolumeID volID = volumeID(global);
+	double l[3];
+	double g[3];
+	global.GetCoordinates(g);
+	const TGeoMatrix& localToGlobal = _volumeManager.worldTransformation(volID);
+	localToGlobal.MasterToLocal(g, l);
+	Position local(l[0], l[1], l[2]);
+	return _readout.segmentation().cellID(local, global, volID);
+}
+
+/**
+ * Returns the global position from a given cell ID
+ */
+Position IDDecoder::position(const CellID& cellID) const {
+	double l[3];
+	double g[3];
+	Position local = _readout.segmentation().position(cellID);
+	std::cout << "Local: " << local << std::endl;
+	local.GetCoordinates(l);
+	const TGeoMatrix& localToGlobal = _volumeManager.worldTransformation(cellID);
+	localToGlobal.LocalToMaster(l, g);
+	return Position(g[0], g[1], g[2]);
+}
+
+/*
+ * Returns the local position from a given cell ID
+ */
+Position IDDecoder::localPosition(const CellID& cellID) const {
+	return _readout.segmentation().position(cellID);
+}
+
+/*
+ * Returns the volume ID of a given cell ID
+ */
+VolumeID IDDecoder::volumeID(const CellID& cellID) const {
+	return _readout.segmentation()->volumeID(cellID);
+}
+
+/*
+ * Returns the volume ID of a given global position
+ */
+VolumeID IDDecoder::volumeID(const Position& position) const {
+	// FIXME: Need to navigate volumes to find enclosing volume and extract its volume ID
+	return 0;
+}
+
+/*
+ * Returns the placement for a given cell ID
+ */
+PlacedVolume IDDecoder::placement(const CellID& cellID) const {
+	return _volumeManager.lookupPlacement(cellID);
+}
+
+/*
+ * Returns the placement for a given global position
+ */
+PlacedVolume IDDecoder::placement(const Position& position) const {
+	return placement(volumeID(position));
+}
+
+/*
+ * Returns the subdetector for a given cell ID
+ */
+DetElement IDDecoder::subDetector(const CellID& cellID) const {
+	return _volumeManager.lookupDetector(cellID);
+}
+
+/*
+ * Returns the subdetector for a given global position
+ */
+DetElement IDDecoder::subDetector(const Position& position) const {
+	return subDetector(volumeID(position));
+}
+
+/*
+ * Returns the closest detector element in the hierarchy for a given cell ID
+ */
+DetElement IDDecoder::detectorElement(const CellID& cellID) const {
+	return _volumeManager.lookupDetElement(cellID);
+}
+
+/*
+ * Returns the closest detector element in the hierarchy for a given global position
+ */
+DetElement IDDecoder::detectorElement(const Position& position) const {
+	return detectorElement(volumeID(position));
+}
+
+/*
+ * Calculates the neighbours of the given cell ID and adds them to the list of neighbours
+ */
+void IDDecoder::neighbours(const CellID& cellID, set<CellID>& neighbours) const {
+	_readout.segmentation()->neighbours(cellID, neighbours);
+}
+
+/*
+ * Checks if the given cell IDs are neighbours
+ */
+bool IDDecoder::areNeighbours(const CellID& cellID, const CellID& otherCellID) const {
+	set<CellID> neighbours;
+	_readout.segmentation()->neighbours(cellID, neighbours);
+	return neighbours.count(otherCellID) != 0;
+}
+
+} /* namespace DD4hep */
diff --git a/DDReconstruction/src/IDDecoderTest.cpp b/DDReconstruction/src/IDDecoderTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..09ecb76c7392466262bd8e783f01161a10549270
--- /dev/null
+++ b/DDReconstruction/src/IDDecoderTest.cpp
@@ -0,0 +1,43 @@
+/*
+ * SegmentationTest.cpp
+ *
+ *  Created on: Aug 28, 2013
+ *      Author: Christian Grefe, CERN
+ */
+
+#include "DD4hep/LCDD.h"
+#include "DD4hep/VolumeManager.h"
+
+#include "DDReconstruction/API/IDDecoder.h"
+
+//#include <set>
+//#include <string>
+
+using namespace std;
+using namespace DD4hep;
+using namespace Geometry;
+
+int main(int argc, char** argv) {
+	LCDD& lcdd = LCDD::getInstance();
+	lcdd.fromCompact(argv[1]);
+
+	string collectionName = "MuonBarrelHits";
+	Readout r = lcdd.readout(collectionName);
+	BitField64& d = *(r.segmentation()->decoder());
+
+	d.reset();
+	d["system"] = 10;
+	d["barrel"] = 0;
+	d["layer"] = 18;
+	d["module"] = 8;
+	//d["slice"] = 11;
+	//d["x"] = -32;
+	//d["y"] = 25;
+
+	CellID cellID = d.getValue();
+
+	cout << "CellID: " << cellID << endl;
+	IDDecoder id(collectionName);
+	cout << id.detectorElement(cellID).name() << endl;
+	cout << id.position(cellID) << endl;
+};