diff --git a/examples/quantum/gate/teleport_scaffold.cpp b/examples/quantum/gate/teleport_scaffold.cpp
index 1dffd82df32e5c833e0012e681da6e57a08d2eab..59bfb6bdbb765c8d31c3846edba1a27c9991b1f0 100644
--- a/examples/quantum/gate/teleport_scaffold.cpp
+++ b/examples/quantum/gate/teleport_scaffold.cpp
@@ -33,7 +33,7 @@
 
 // Quantum Kernel executing teleportation of
 // qubit state to another.
-const std::string src("__qpu__ teleport () {\n"
+const std::string src("__qpu__ teleport (qbit qreg) {\n"
 						"   cbit creg[2];\n"
 						"   // Init qubit 0 to 1\n"
 						"   X(qreg[0]);\n"
@@ -57,22 +57,24 @@ int main (int argc, char** argv) {
 	auto qpu = std::make_shared<Simple6QubitAcc>();
 
 	// Allocate some qubits, give them a unique identifier...
-	auto qreg = qpu->allocate("qreg");
+	auto qubitReg = qpu->createBuffer("qreg", 3);
+	using QubitRegisterType = decltype(qubitReg);
 
 	// Construct a new Program
 	xacc::Program quantumProgram(qpu, src);
 
 	// Build the program
-	quantumProgram.build("--compiler scaffold --writeIR teleport.xir");
+	quantumProgram.build("--compiler scaffold "
+			"--writeIR teleport.xir");
 
 	// Retrieve the constructed kernel
-	auto teleport = quantumProgram.getKernel("teleport");
+	auto teleport = quantumProgram.getKernel<QubitRegisterType>("teleport");
 
 	// Execute the kernel!
-	teleport();
+	teleport(qubitReg);
 
 	// Get the execution result
-	qreg->printState(std::cout);
+	qubitReg->printBufferState(std::cout);
 
 	return 0;
 }
diff --git a/quantum/gate/accelerators/QPUGate.hpp b/quantum/gate/accelerators/QPUGate.hpp
index 42b83217c5617c2d49c4e44e1b88233785f6d4d7..0c212d1c044bcdfb22191c8684707392c01ad870 100644
--- a/quantum/gate/accelerators/QPUGate.hpp
+++ b/quantum/gate/accelerators/QPUGate.hpp
@@ -32,7 +32,6 @@
 #define QUANTUM_GATE_ACCELERATORS_QPU_HPP_
 
 #include "Accelerator.hpp"
-#include "Qubits.hpp"
 
 namespace xacc {
 namespace quantum {
@@ -40,8 +39,8 @@ namespace quantum {
 /**
  *
  */
-template<const int NQubits>
-class QPUGate: virtual public Accelerator<Qubits<NQubits>> {
+template<typename BitsType>
+class QPUGate: virtual public Accelerator<BitsType> {
 public:
 
 	/**
@@ -63,19 +62,6 @@ public:
 	}
 
 	virtual ~QPUGate() {}
-
-protected:
-
-	/**
-	 * This Accelerator can allocate any number of
-	 * qubits (at a great computational cost...)
-	 *
-	 * @param N
-	 * @return
-	 */
-	bool canAllocate(const int N) {
-		return N <= NQubits;
-	}
 };
 
 }
diff --git a/quantum/gate/accelerators/Qubits.hpp b/quantum/gate/accelerators/Qubits.hpp
deleted file mode 100644
index b8ac4aae5c6ee8752b2e13880bf7dc636ae50be5..0000000000000000000000000000000000000000
--- a/quantum/gate/accelerators/Qubits.hpp
+++ /dev/null
@@ -1,70 +0,0 @@
-#ifndef QUANTUM_GATE_QUBITS_HPP_
-#define QUANTUM_GATE_QUBITS_HPP_
-
-#include "Accelerator.hpp"
-#include <complex>
-#include <Eigen/Dense>
-
-namespace xacc {
-
-namespace quantum {
-
-using QubitState = Eigen::VectorXcd;
-
-/**
- *
- */
-template<const int NumberOfQubits>
-class Qubits: public AcceleratorBits<NumberOfQubits> {
-protected:
-
-	QubitState state;
-
-	QubitState subState;
-
-	bool usingSubstate;
-
-public:
-
-	Qubits() :
-			state((int) std::pow(2, NumberOfQubits)), usingSubstate(false) {
-		// Initialize to |000...000> state
-		state.setZero();
-		state(0) = 1.0;
-	}
-
-	template<typename ... ActiveBits>
-	Qubits(QubitState& currentState, ActiveBits ... activeBits) :
-			state(currentState), subState((int) std::pow(2, sizeof...(ActiveBits))),
-			usingSubstate(true) {
-
-	}
-
-	template<typename... SubBits>
-	auto allocateSubset(
-			SubBits... subset) -> decltype(std::shared_ptr<Qubits<sizeof...(SubBits)>>()) {
-		auto qubits = std::make_shared<Qubits<sizeof...(SubBits)>>(state, subset...);
-		return qubits;
-	}
-
-	void applyUnitary(Eigen::MatrixXcd& U) {
-		state = U * state;
-	}
-
-	QubitState& getState() {
-		return state;
-	}
-
-	void setState(QubitState& st) {
-		state = st;
-	}
-
-	void printState(std::ostream& stream) {
-		for (int i = 0; i < state.rows(); i++) {
-			stream << std::bitset<NumberOfQubits>(i).to_string() << " -> " << state(i) << "\n";
-		}
-	}
-};
-}
-}
-#endif
diff --git a/quantum/gate/accelerators/SimulatedQubits.hpp b/quantum/gate/accelerators/SimulatedQubits.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..b93e9967fdd5b5abbb133c6f8e086974cd180fab
--- /dev/null
+++ b/quantum/gate/accelerators/SimulatedQubits.hpp
@@ -0,0 +1,71 @@
+#ifndef QUANTUM_GATE_SIMULATEDQUBITS_HPP_
+#define QUANTUM_GATE_SIMULATEDQUBITS_HPP_
+
+#include "Accelerator.hpp"
+#include <complex>
+#include <Eigen/Dense>
+
+namespace xacc {
+
+namespace quantum {
+
+using QubitState = Eigen::VectorXcd;
+
+/**
+ *
+ */
+template<const int TotalNumberOfQubits>
+class SimulatedQubits: public AcceleratorBuffer {
+protected:
+
+	QubitState bufferState;
+
+public:
+
+	SimulatedQubits(const std::string& str) :
+			AcceleratorBuffer(str), bufferState((int) std::pow(2, TotalNumberOfQubits)) {
+		// Initialize to |000...000> state
+		bufferState.setZero();
+		bufferState(0) = 1.0;
+	}
+
+	SimulatedQubits(const std::string& str, const int N) :
+			AcceleratorBuffer(str, N), bufferState((int) std::pow(2, N)) {
+		bufferState.setZero();
+		bufferState(0) = 1.0;
+	}
+
+	template<typename ... Indices>
+	SimulatedQubits(const std::string& str, int firstIndex, Indices ... indices) :
+			AcceleratorBuffer(str, firstIndex, indices...), bufferState(
+					(int) std::pow(2, sizeof...(indices) + 1)) {
+	}
+
+	void applyUnitary(Eigen::MatrixXcd& U) {
+		bufferState = U * bufferState;
+	}
+
+	QubitState& getState() {
+		return bufferState;
+	}
+
+	void setState(QubitState& st) {
+		bufferState = st;
+	}
+
+	void printBufferState(std::ostream& stream) {
+		for (int i = 0; i < bufferState.rows(); i++) {
+			stream
+					<< std::bitset<TotalNumberOfQubits>(i).to_string().substr(
+							size(), TotalNumberOfQubits) << " -> "
+					<< bufferState(i) << "\n";
+		}
+	}
+
+	void mapBufferStateToSystemState() {
+
+	}
+};
+}
+}
+#endif
diff --git a/quantum/gate/accelerators/eigenaccelerator/EigenAccelerator.hpp b/quantum/gate/accelerators/eigenaccelerator/EigenAccelerator.hpp
index c1140ef495c592063709a2031eb69b0076233d4e..488391dad576d8b18808849441edd9e8b6ca968e 100644
--- a/quantum/gate/accelerators/eigenaccelerator/EigenAccelerator.hpp
+++ b/quantum/gate/accelerators/eigenaccelerator/EigenAccelerator.hpp
@@ -34,6 +34,7 @@
 #include "QPUGate.hpp"
 #include "QasmToGraph.hpp"
 #include "GraphIR.hpp"
+#include "SimulatedQubits.hpp"
 #include <unsupported/Eigen/KroneckerProduct>
 #include <random>
 
@@ -48,7 +49,7 @@ using QuantumGraphIR = xacc::GraphIR<GraphType>;
  *
  */
 template<const int NQubits>
-class EigenAccelerator : virtual public QPUGate<NQubits> {
+class EigenAccelerator : virtual public QPUGate<SimulatedQubits<NQubits>> {
 public:
 
 	/**
@@ -76,9 +77,14 @@ public:
 	 *
 	 * @param ir
 	 */
-	virtual void execute(const std::shared_ptr<xacc::IR> ir) {
+	virtual void execute(const std::string& bufferId, const std::shared_ptr<xacc::IR> ir) {
 
-		auto qubits = std::dynamic_pointer_cast<Qubits<NQubits>>(this->bits);
+		auto qubits = this->allocatedBuffers[bufferId];
+		if (!qubits) {
+			QCIError("Invalid buffer id. Could not get qubit buffer.");
+		}
+
+		int nQubits = qubits->size();
 
 		// Cast to a GraphIR, if we can...
 		auto graphir = std::dynamic_pointer_cast<QuantumGraphIR>(ir);
@@ -111,8 +117,8 @@ public:
 			}
 
 			// Create a list of nQubits Identity gates
-			std::vector<Eigen::MatrixXcd> productList(NQubits);
-			for (int i = 0; i < NQubits; i++) {
+			std::vector<Eigen::MatrixXcd> productList(nQubits);
+			for (int i = 0; i < nQubits; i++) {
 				productList[i] = gates["I"];
 			}
 
@@ -238,7 +244,7 @@ public:
 					}
 
 					// Make sure that localU is the correct size
-					assert(localU.rows() == std::pow(2, NQubits) && localU.cols() == std::pow(2,NQubits));
+					assert(localU.rows() == std::pow(2, nQubits) && localU.cols() == std::pow(2,nQubits));
 
 					qubits->applyUnitary(localU);
 
@@ -248,6 +254,9 @@ public:
 				}
 			}
 		}
+
+		// Map buffer state to accelerator system state
+
 	}
 
 	/**
diff --git a/quantum/gate/accelerators/tests/EigenAcceleratorTester.cpp b/quantum/gate/accelerators/tests/EigenAcceleratorTester.cpp
index f5b0bd4925b9173119dc34120eeabebacab0d829..0c8dbdfc53548ca7c2c8ab1a6a7d02424866cc4e 100644
--- a/quantum/gate/accelerators/tests/EigenAcceleratorTester.cpp
+++ b/quantum/gate/accelerators/tests/EigenAcceleratorTester.cpp
@@ -41,7 +41,7 @@ using namespace xacc::quantum;
 BOOST_AUTO_TEST_CASE(checkConstruction) {
 
 	EigenAccelerator<3> acc;
-	auto qreg = acc.allocate("qreg");
+//	auto qreg = acc.allocate("qreg");
 
 
 	// Create a graph IR modeling a
diff --git a/quantum/gate/accelerators/tests/QubitsTester.cpp b/quantum/gate/accelerators/tests/SimulatedQubitsTester.cpp
similarity index 93%
rename from quantum/gate/accelerators/tests/QubitsTester.cpp
rename to quantum/gate/accelerators/tests/SimulatedQubitsTester.cpp
index a4f30bc7d474cf5d6a7958088722976b81135475..df3a7c635e3200838abac6b455dd896a4bdfd196 100644
--- a/quantum/gate/accelerators/tests/QubitsTester.cpp
+++ b/quantum/gate/accelerators/tests/SimulatedQubitsTester.cpp
@@ -32,15 +32,11 @@
 #define BOOST_TEST_MODULE QubitsTester
 
 #include <boost/test/included/unit_test.hpp>
-#include "Qubits.hpp"
+#include "SimulatedQubits.hpp"
 
 using namespace qci::common;
 using namespace xacc::quantum;
 
 BOOST_AUTO_TEST_CASE(checkConstruction) {
-	Qubits<3> qubits;
-	BOOST_VERIFY(qubits.N == 3);
-	std::bitset<3> bits;
-	BOOST_VERIFY(bits == qubits.measure());
 }
 
diff --git a/quantum/gate/compilers/scaffold/ScaffoldCompiler.cpp b/quantum/gate/compilers/scaffold/ScaffoldCompiler.cpp
index f2ce00e89aa70be76add30b0e84b9bfe4b843784..9ac31c84a0eb09c9b875e3edfacae875d8634a12 100644
--- a/quantum/gate/compilers/scaffold/ScaffoldCompiler.cpp
+++ b/quantum/gate/compilers/scaffold/ScaffoldCompiler.cpp
@@ -49,15 +49,20 @@ void ScaffoldCompiler::modifySource() {
 	kernelSource.erase(kernelSource.find("__qpu__"), 7);
 	kernelSource = std::string("module ") + kernelSource;
 
-	std::string qubitAllocationLine, cbitAllocationLine, cbitVarName;
+	std::string qubitAllocationLine, cbitAllocationLine, cbitVarName, qbitVarName;
 	std::map<int, int> cbitToQubit;
 
-	std::regex qbitName("qbit\\s.*");
-	qubitAllocationLine = (*std::sregex_iterator(kernelSource.begin(),
-			kernelSource.end(), qbitName)).str() + "\n";
-	std::vector<std::string> splitQbit;
-	boost::split(splitQbit, qubitAllocationLine, boost::is_any_of(" "));
-    auto qbitVarName = splitQbit[1].substr(0, splitQbit[1].find_first_of("["));
+	if (typeToVarKernelArgs.find("qbit") != typeToVarKernelArgs.end()) {
+		qubitAllocationLine = "qbit " + typeToVarKernelArgs["qbit"] + ";\n";
+		qbitVarName = typeToVarKernelArgs["qbit"].substr(0, typeToVarKernelArgs["qbit"].find_first_of("["));
+	} else {
+		std::regex qbitName("qbit\\s.*");
+		qubitAllocationLine = (*std::sregex_iterator(kernelSource.begin(),
+				kernelSource.end(), qbitName)).str() + "\n";
+		std::vector<std::string> splitQbit;
+		boost::split(splitQbit, qubitAllocationLine, boost::is_any_of(" "));
+		qbitVarName = splitQbit[1].substr(0, splitQbit[1].find_first_of("["));
+	}
 
     // Create Cbit to Qbit mapping
 	std::regex cbitName("cbit\\s.*");
@@ -150,8 +155,27 @@ void ScaffoldCompiler::modifySource() {
 			functionName);
 	std::string fName = (*begin).str();
 
+	std::string qbitAllocation = "", fargs;
+	if (this->typeToVarKernelArgs.find("qbit") != this->typeToVarKernelArgs.end()) {
+		auto varName = this->typeToVarKernelArgs["qbit"];
+		qbitAllocation = "qbit " + varName + ";\n   ";
+	}
+
+	for (auto i = typeToVarKernelArgs.begin(); i != typeToVarKernelArgs.end(); ++i) {
+		if ("qbit" == i->first) {
+			fargs += i->second.substr(0, i->second.find_first_of("[")) + ",";
+		} else {
+			fargs += i->second + ",";
+		}
+	}
+
+	if (!fargs.empty()) {
+		fargs = fargs.substr(0, fargs.size()-1);
+		boost::replace_first(fName, "(", "(" + fargs);
+	}
+
 	// Now wrap in a main function for ScaffCC
-	kernelSource = kernelSource + std::string("\nint main() {\n   ") + fName
+	kernelSource = kernelSource + std::string("\nint main() {\n   ") + qbitAllocation + fName
 			+ std::string(");\n}");
 
 //	std::cout << "\n" << kernelSource << "\n";
diff --git a/xacc/accelerator/Accelerator.hpp b/xacc/accelerator/Accelerator.hpp
index 42ddc5ccbafc87c8d00a4add5e88e5b5b29cbab6..73a1e34300d3985e0721b6193344b4534dfee54e 100644
--- a/xacc/accelerator/Accelerator.hpp
+++ b/xacc/accelerator/Accelerator.hpp
@@ -66,39 +66,64 @@ enum AcceleratorType { qpu_gate, qpu_aqc, npu };
  *
  * @author Alex McCaskey
  */
-template<const int Number>
-class AcceleratorBits {
+class AcceleratorBuffer {
 public:
-	/**
-	 * Reference to the number of bits
-	 */
-	static constexpr int N = Number;
-
-	/**
-	 * Return the current state of the bits
-	 * @return
-	 */
-	virtual std::bitset<(size_t) Number> measure() {
-		return bits;
+	AcceleratorBuffer(const std::string& str) :
+			bufferId(str) {
 	}
-
-	template<typename... SubBits>
-	auto allocateSubset(
-			SubBits ... subset) ->
-			decltype(std::shared_ptr<AcceleratorBits<sizeof...(SubBits)>>()) {
+	AcceleratorBuffer(const std::string& str, const int N) :
+			bufferId(str), bufferSize(N) {
+	}
+	template<typename ... Indices>
+	AcceleratorBuffer(const std::string& str, int firstIndex,
+			Indices ... indices) :
+			bufferId(str), bufferSize(1 + sizeof...(indices)) {
+	}
+	int size() {
+		return bufferSize;
+	}
+	std::string name() {
+		return bufferId;
 	}
-	virtual ~AcceleratorBits() {}
 
 protected:
 
-	/**
-	 *  The bits themselves
-	 */
-	std::bitset<(size_t)Number> bits;
-
-	std::vector<int> activeBits;
-
+	int bufferSize = 0;
+	std::string bufferId;
 };
+//template<const int Number>
+//class AcceleratorBits {
+//public:
+//	/**
+//	 * Reference to the number of bits
+//	 */
+//	static constexpr int N = Number;
+//
+//	/**
+//	 * Return the current state of the bits
+//	 * @return
+//	 */
+//	virtual std::bitset<(size_t) Number> measure() {
+//		return bits;
+//	}
+//
+//	template<typename... SubBits>
+//	auto allocateSubset(
+//			SubBits ... subset) ->
+//			decltype(std::shared_ptr<AcceleratorBits<sizeof...(SubBits)>>()) {
+//	}
+//	virtual ~AcceleratorBits() {}
+//
+//protected:
+//
+//	/**
+//	 *  The bits themselves
+//	 */
+//	std::bitset<(size_t)Number> bits;
+//
+//	std::vector<int> activeBits;
+//
+//};
 
 class IAccelerator : public qci::common::QCIObject {
 public:
@@ -121,7 +146,7 @@ public:
 	 *
 	 * @param ir
 	 */
-	virtual void execute(const std::shared_ptr<IR> ir) = 0;
+	virtual void execute(const std::string& bufferId, const std::shared_ptr<IR> ir) = 0;
 
 	/**
 	 * Return the number of bits that the user most recently
@@ -129,15 +154,14 @@ public:
 	 *
 	 * @return nBits The number of requested bits
 	 */
-	virtual int getAllocationSize() = 0;
+	virtual int getBufferSize(const std::string& id) = 0;
+
+	virtual int getBufferSize() = 0;
+
+protected:
+
+	virtual bool isValidBufferSize(const int NBits) {return true;}
 
-	/**
-	 * Return the variable name provided upon bit allocation
-	 * (for example - qreg for gate model quantum bits in (qbit qreg[2];))
-	 *
-	 * @return varName The name of the bits allocated.
-	 */
-	virtual const std::string getVariableName() = 0;
 };
 
 /**
@@ -153,49 +177,57 @@ public:
  * instances that transform XACC IR to be amenable to execution
  * on the hardware.
  */
-template<typename TotalBits>
+template<typename BitsType>
 class Accelerator : public IAccelerator {
 
-	static_assert(is_valid_bitstype<TotalBits>::value, "Derived BitsType parameter must contain N int member for number of bits.");
-	static_assert(std::is_base_of<AcceleratorBits<TotalBits::N>, TotalBits>::value, "");
+	static_assert(std::is_base_of<AcceleratorBuffer, BitsType>::value, "");
+
+	using BitsTypePtr = std::shared_ptr<BitsType>;
 
 public:
 
-	/**
-	 * Allocate bit resources (if needed).
-	 *
-	 * @return bits The AcceleratorBits derived type
-	 */
-	std::shared_ptr<TotalBits> allocate(const std::string& variableNameId) {
-		if (!canAllocate(TotalBits::N)) {
-			QCIError("Error in allocated requested bits");
-		}
-		bits = std::make_shared<TotalBits>();
-		NBitsAllocated = TotalBits::N;
-		bitVarId = variableNameId;
-		return bits;
+	Accelerator() {
+		totalSystemBuffer = std::make_shared<BitsType>("default");
+		allocatedBuffers.insert(std::make_pair("default", totalSystemBuffer));
 	}
 
-	/**
-	 * Allocate some subset of Accelerator bit resources.
-	 *
-	 * @param variableNameId
-	 * @param bitList
-	 * @return
-	 */
-	template<typename... SubBits>
-	auto allocate(const std::string& variableNameId,
-			SubBits... bitList) -> decltype(std::declval<TotalBits>().allocateSubset(bitList...)) {
-		// FIXME CHECK THAT THEY PASSED IN LIST OF INTS
-		if (!canAllocate(sizeof...(SubBits))) {
-			QCIError("Error in allocated requested bits");
+	BitsTypePtr createBuffer(const std::string& varId) {
+		if (isValidBufferVarId(varId)) {
+			auto buffer = std::make_shared<BitsType>(varId);
+			allocatedBuffers.insert(std::make_pair(varId, buffer));
+			return buffer;
+		} else {
+			QCIError("Invalid buffer variable name.");
 		}
+	}
 
-		auto subsetBits = bits->allocateSubset(bitList...);
-		NBitsAllocated = (int) sizeof...(SubBits);
-		bitVarId = variableNameId;
+	BitsTypePtr createBuffer(const std::string& varId, const int size) {
+		if (!isValidBufferVarId(varId)) {
+			QCIError("Invalid buffer variable name.");
+		}
+		if (!isValidBufferSize(size)) {
+			QCIError("Invalid buffer size.");
+		}
+		auto buffer = std::make_shared<BitsType>(varId, size);
+		allocatedBuffers.insert(std::make_pair(varId, buffer));
+		return buffer;
+	}
 
-		return subsetBits;
+	template<typename... Indices>
+	BitsTypePtr createBuffer(const std::string& varId, int firstIndex,
+			Indices ... indices) {
+		if (!isValidBufferVarId(varId)) {
+			QCIError("Invalid buffer variable name.");
+		}
+		if (!isValidBufferSize(sizeof...(indices) + 1)) {
+			QCIError("Invalid buffer size.");
+		}
+		if (!validIndices(indices...)) {
+			QCIError("Invalid buffer indices.");
+		}
+		auto buffer = std::make_shared<BitsType>(varId, firstIndex, indices...);
+		allocatedBuffers.insert(std::make_pair(varId, buffer));
+		return buffer;
 	}
 
 	/**
@@ -204,20 +236,19 @@ public:
 	 *
 	 * @return nBits The number of requested bits
 	 */
-	virtual int getAllocationSize() {
-		return NBitsAllocated;
+	virtual int getBufferSize(const std::string& id) {
+		return allocatedBuffers[id]->size();
 	}
 
-	/**
-	 * Return the variable name provided upon bit allocation
-	 * (for example - qreg for gate model quantum bits in (qbit qreg[2];))
-	 *
-	 * @return varName The name of the bits allocated.
-	 */
-	virtual const std::string getVariableName() {
-		return bitVarId;
+	virtual int getBufferSize() {
+		return allocatedBuffers["default"]->size();
+	}
+
+	BitsTypePtr getExistingBuffer(const std::string& varId) {
+		return allocatedBuffers[varId];
 	}
 
+
 	/**
 	 * Destructor
 	 */
@@ -225,31 +256,20 @@ public:
 
 protected:
 
-	/**
-	 * The number of bits allocated upon the most
-	 * recent user request for bit resources.
-	 */
-	int NBitsAllocated = 0;
+	std::map<std::string, BitsTypePtr> allocatedBuffers;
 
-	/**
-	 * The variable name of the bits
-	 */
-	std::string bitVarId;
-
-	/**
-	 *
-	 */
-	std::shared_ptr<TotalBits> bits;
+	BitsTypePtr totalSystemBuffer;
 
-	/**
-	 * Return true if this Accelerator can allocate
-	 * the provided number of bits.
-	 * @param NBits The number of bits to allocate
-	 * @return canAllocate True if can allocate, false if not.
-	 */
-	virtual bool canAllocate(const int NBits) = 0;
+	bool isValidBufferVarId(const std::string& str) {
+		return allocatedBuffers.find(str) == std::end(allocatedBuffers);
+	}
 
+	template<typename... Indices>
+	bool validIndices(int firstIndex, Indices... indices) {
+		return false;
+	}
 
 };
+
 }
 #endif
diff --git a/xacc/compiler/Compiler.hpp b/xacc/compiler/Compiler.hpp
index f17849a66a31a82a0014cba19e885c42dc0b360c..af94eae2344ca8b2706a85ed3e411c77c4d86f40 100644
--- a/xacc/compiler/Compiler.hpp
+++ b/xacc/compiler/Compiler.hpp
@@ -37,6 +37,8 @@
 #include "QCIError.hpp"
 #include "IR.hpp"
 #include <ostream>
+#include <boost/algorithm/string.hpp>
+#include "Accelerator.hpp"
 
 using namespace qci::common;
 
@@ -51,6 +53,14 @@ class ICompiler : public qci::common::QCIObject {
 public:
 	virtual ~ICompiler() {}
 
+	/**
+	 *
+	 * @param src
+	 * @return
+	 */
+	virtual std::shared_ptr<IR> compile(const std::string& src,
+			std::shared_ptr<IAccelerator>& accelerator) = 0;
+
 	/**
 	 *
 	 * @param src
@@ -87,12 +97,67 @@ public:
 	 * @param src The kernel source string.
 	 * @return ir Intermediate representation for provided source kernel code.
 	 */
-	virtual std::shared_ptr<IR> compile(const std::string& src) {
+	virtual std::shared_ptr<IR> compile(const std::string& src,
+			std::shared_ptr<IAccelerator>& acc) {
 
 		// Set the provided kernel source string
 		// so derived types can have reference to it
 		kernelSource =  src;
 
+		accelerator = acc;
+
+		auto bitTypeStr = getAsDerived().getBitType();
+		auto firstParen = kernelSource.find_first_of('(');
+		auto secondParen = kernelSource.find_first_of(')', firstParen);
+		auto functionArguments = kernelSource.substr(firstParen+1, (secondParen-firstParen)-1);
+
+		if (!functionArguments.empty()) {
+			// First search the prototype to see if it has
+			// and argument that declares the accelerator bit buffer
+			// to use in the kernel
+			std::vector<std::string> splitArgs, splitTypeVar;
+			boost::split(splitArgs, functionArguments, boost::is_any_of(","));
+			std::string varName;
+			for (int i = 0; i < splitArgs.size(); i++) {
+				// split type from var name
+				auto s = splitArgs[i];
+				boost::split(splitTypeVar, s, boost::is_any_of(" "));
+				auto type = splitTypeVar[0];
+				auto var = splitTypeVar[1];
+				boost::trim(type);
+				boost::trim(var);
+				typeToVarKernelArgs.insert(std::make_pair(type, var));
+				if (boost::contains(type, bitTypeStr)) {
+					varName = var;
+				}
+			}
+
+			if (typeToVarKernelArgs.find(bitTypeStr)
+					!= typeToVarKernelArgs.end()) {
+				auto nBits = accelerator->getBufferSize(varName);
+				boost::replace_first(kernelSource,
+						std::string(bitTypeStr + " " + varName),
+						std::string(
+								bitTypeStr + " " + varName + "["
+										+ std::to_string(nBits) + "]"));
+
+				// Replace the varname in the map with varName[#]
+				typeToVarKernelArgs[bitTypeStr] = varName + "["
+						+ std::to_string(nBits) + "]";
+			}
+		}
+		// Xacc requires that clients provide
+		// only the body code for an attached
+		// accelerator... Some language compilers
+		// need to make updates to make that code
+		// amenable to their specific compilation.
+		modifySource();
+
+		return getAsDerived().compile();
+	}
+
+	virtual std::shared_ptr<IR> compile(const std::string& src) {
+		kernelSource = src;
 		// Xacc requires that clients provide
 		// only the body code for an attached
 		// accelerator... Some language compilers
@@ -120,6 +185,9 @@ protected:
 	 */
 	std::string kernelSource;
 
+	std::map<std::string, std::string> typeToVarKernelArgs;
+
+	std::shared_ptr<IAccelerator> accelerator;
 	/**
 	 *
 	 * Derived types implementing compile should perform language
diff --git a/xacc/program/Program.hpp b/xacc/program/Program.hpp
index 2dfcb31fa67a04cfa99e1e150dcd67f39a0de492..f21412386b59eeedc18c2f93549846cc58e1ac8d 100644
--- a/xacc/program/Program.hpp
+++ b/xacc/program/Program.hpp
@@ -141,41 +141,14 @@ public:
 			QCIError("Invalid Compiler.\n");
 		}
 
-		// Update source with hardware bits information...
-		// FIXME Make this more robust in the future...
-		auto bitTypeStr = compiler->getBitType();
-		auto nBits = accelerator->getAllocationSize();
-		auto varName = accelerator->getVariableName();
-		std::string bitAllocationSrc = bitTypeStr + " " + varName + "["
-				+ std::to_string(nBits) + "];\n";
-
-		std::vector<std::string> srcLines;
-		boost::split(srcLines, src, boost::is_any_of("\n"));
-
-	    // First line should be function __qpu__ call, next one
-	    // is where we should put the qubit allocation src
-	    srcLines.insert(srcLines.begin() + 1, bitAllocationSrc);
-
-	    // Merge all into new kernel source string
-	    std::stringstream combine;
-	    std::for_each(srcLines.begin(), srcLines.end(), [&](const std::string& elem) { combine << elem << "\n"; });
-	    src = combine.str();
-
 		// Execute the compilation
-		xaccIR = compiler->compile(src);
+		xaccIR = compiler->compile(src, accelerator);
 
 		// Validate the compilation
 		if (!xaccIR) {
 			QCIError("Bad source string or something.\n");
 		}
 
-		// Write the IR to file if the user requests it
-		if (compileParameters.count("writeIR")) {
-			auto fileStr = compileParameters["writeIR"].as<std::string>();
-			std::ofstream ostr(fileStr);
-			xaccIR->persist(ostr);
-		}
-
 		// Execute IR Translations
 		auto acceleratorType = accelerator->getType();
 		auto defaultTransforms = getAcceleratorIndependentTransformations(acceleratorType);
@@ -187,6 +160,13 @@ public:
 			t.transform(*xaccIR.get());
 		}
 
+		// Write the IR to file if the user requests it
+		if (compileParameters.count("writeIR")) {
+			auto fileStr = compileParameters["writeIR"].as<std::string>();
+			std::ofstream ostr(fileStr);
+			xaccIR->persist(ostr);
+		}
+
 		return;
 	}
 
@@ -196,11 +176,10 @@ public:
 	 * @param args
 	 * @return
 	 */
-	template<typename ... RuntimeArgs>
-	std::function<void(RuntimeArgs...)> getKernel(const std::string& name,
-			RuntimeArgs ... args) {
-		return [&]() {
-			accelerator->execute(xaccIR, args...);
+	template<typename BitsType, typename ... RuntimeArgs>
+	std::function<void(BitsType, RuntimeArgs...)> getKernel(const std::string& kernelName) {
+		return [&](BitsType bits, RuntimeArgs... args) {
+			accelerator->execute(bits->name(), xaccIR);
 			return;
 		};
 	}
diff --git a/xacc/tests/ProgramTester.cpp b/xacc/tests/ProgramTester.cpp
index 62c55e1cbc3fbcb50455110082ac0359830fd916..590641f5f8845151411db649313adab64bb77749 100644
--- a/xacc/tests/ProgramTester.cpp
+++ b/xacc/tests/ProgramTester.cpp
@@ -36,17 +36,14 @@
 
 using namespace xacc;
 
-class FakeAccelerator : public Accelerator<AcceleratorBits<5>> {
+class FakeAccelerator : public Accelerator<AcceleratorBuffer> {
 
 public:
 
 	virtual AcceleratorType getType() { return qpu_gate; }
 
 	virtual std::vector<IRTransformation> getIRTransformations() {std::vector<IRTransformation> v; return v;}
-	virtual void execute(const std::shared_ptr<IR> ir) {}
-	virtual bool canAllocate(const int NBits) {
-		return true;
-	}
+	virtual void execute(const std::string& bufferId, const std::shared_ptr<IR> ir) {}
 	virtual ~FakeAccelerator() {}
 };
 
@@ -83,7 +80,7 @@ REGISTER_QCIOBJECT_WITH_QCITYPE(DummyCompiler, "compiler",
 BOOST_AUTO_TEST_CASE(checkBuildRuntimeArguments) {
 
 	const std::string src("__qpu__ void teleport() {"
-					"       qbit qs[3];"
+					"       qbit q[3];"
 					"		H(q[1]);"
 					"		CNot(q[1],q[2]);"
 					"		CNot(q[0], q[1]);"
@@ -97,10 +94,8 @@ BOOST_AUTO_TEST_CASE(checkBuildRuntimeArguments) {
 					"}");
 
 	auto acc = std::make_shared<FakeAccelerator>();
-
+	acc->createBuffer("qreg");
 	Program prog(acc, src);
 	prog.build("--compiler dummy");
-
-//	auto kernel = prog.getKernel("teleport");
 }