private void initOutputToRegisters() {
		// It seems like we can take in account last opNOPs bit
		//   to check if there is a specific destination.
		ORNode dst_ctrl[] = new ORNode[3];
		for (int i = 0; i < dst_ctrl.length; i++) {
			dst_ctrl[i] = new ORNode();
			dst_ctrl[i].connectSrc(opNOPs[BITNESS-1], 0, 0)
					   .connectSrc(opNOPs[3+i], 0, 1);
		}
		// Also 000XX111 pattern (rotations) should set A as destination.
		ORNode dst_ctrl_rot[] = new ORNode[3];
		MultiNOT rev_high_3bit = new MultiNOT(3);
		comb_rot_ctrl = new ANDNode[5];
		for (int i = 0; i < 3; i++) {
			rev_high_3bit.connectSrc(opNOPs[BITNESS-1-i], 0, i);
			comb_rot_ctrl[i] = new ANDNode();
			comb_rot_ctrl[i].connectSrc(opNOPs[i], 0, 0);
			comb_rot_ctrl[i].connectSrc(rev_high_3bit, i, 1);
		}
		comb_rot_ctrl[3] = new ANDNode();
		comb_rot_ctrl[3].connectSrc(comb_rot_ctrl[0], 0, 0);
		comb_rot_ctrl[3].connectSrc(comb_rot_ctrl[1], 0, 1);
		comb_rot_ctrl[4] = new ANDNode();
		comb_rot_ctrl[4].connectSrc(comb_rot_ctrl[2], 0, 0);
		comb_rot_ctrl[4].connectSrc(comb_rot_ctrl[3], 0, 1);
		for (int i = 0; i < dst_ctrl_rot.length; i++) {
			dst_ctrl_rot[i] = new ORNode();
			dst_ctrl_rot[i].connectSrc(dst_ctrl[i], 0, 0)
			   			   .connectSrc(comb_rot_ctrl[4], 0, 1);
		}
		// Special case: CMA command 00101111, DST = A.
		MultiNOT revs = new MultiNOT(3);
		revs.connectSrc(opNOPs[7], 0, 0);
		revs.connectSrc(opNOPs[6], 0, 1);
		revs.connectSrc(opNOPs[4], 0, 2);
		AllNode is_cma = new AllNode(BITNESS);
		is_cma.connectSrc(opNOPs[0], 0, 0);
		is_cma.connectSrc(opNOPs[1], 0, 1);
		is_cma.connectSrc(opNOPs[2], 0, 2);
		is_cma.connectSrc(opNOPs[3], 0, 3);
		is_cma.connectSrc(revs, 0, 4);
		is_cma.connectSrc(opNOPs[5], 0, 5);
		is_cma.connectSrc(revs, 1, 6);
		is_cma.connectSrc(revs, 2, 7);
		MultiOR cma_ctrl = new MultiOR(3);
		cma_ctrl.connectSrc(dst_ctrl_rot[0], 0, 0);
		cma_ctrl.connectSrc(dst_ctrl_rot[1], 0, 1);
		cma_ctrl.connectSrc(dst_ctrl_rot[2], 0, 2);
		cma_ctrl.connectSrc(is_cma, 0, 3);
		cma_ctrl.connectSrc(is_cma, 0, 4);
		cma_ctrl.connectSrc(is_cma, 0, 5);
		// Also for some of load operations, we should use A as DST. 
		MultiOR is_a_dst = new MultiOR(3);
		for (int i = 0; i < 3; i++) {
			is_a_dst.connectSrc(is_mem_load, 0, i+3);
			is_a_dst.connectSrc(cma_ctrl, i, i);
		}
		/* For store operations memory should be a source. */
		Node ctrl_mem[] = new Node[3];
		ctrl_mem[0] = new ANDNode();
		NOTNode neg_is_mem_store = new NOTNode();
		neg_is_mem_store.connectSrc(is_mem_store, 0, 0);
		ctrl_mem[0].connectSrc(neg_is_mem_store, 0, 0);
		ctrl_mem[0].connectSrc(is_a_dst, 0, 1);
		ctrl_mem[1] = new ORNode();
		ctrl_mem[1].connectSrc(is_mem_store, 0, 0);
		ctrl_mem[1].connectSrc(is_a_dst, 1, 1);
		ctrl_mem[2] = new ORNode();
		ctrl_mem[2].connectSrc(is_mem_store, 0, 0);
		ctrl_mem[2].connectSrc(is_a_dst, 2, 1);
		
		
		ANDNode comb_alu = new ANDNode();
		comb_alu.connectSrc(is_alu_on, 0, 0);
		comb_alu.connectSrc(clock, 0, 1);
		out_demux = new DeMux[(1<<3) - 1];
		out_demux[0] = new DeMux();
		out_demux[0].connectSrc(comb_alu, 0, 0);
		out_demux[0].connectSrc(ctrl_mem[0], 0, 1);
		for (int i = 1; i < out_demux.length; i++) {
			out_demux[i] = new DeMux();
			// heap-like organization of indexes
			out_demux[(i-1)/2].connectDst((i+1)%2, out_demux[i], 0);
			// Adding small magic number to prevent rounding errors.
			int level = (int)Math.floor(Math.log(i+1)/Math.log(2) + 1e-10);
			out_demux[i].connectSrc(ctrl_mem[level], 0, 1);
		}
		
		// connecting registers
		// 000
		B.connectSrc(out_demux[out_demux.length-1], 1, BITNESS);
		// 100
		H.connectSrc(out_demux[out_demux.length-1], 0, BITNESS);
		// 010
		D.connectSrc(out_demux[out_demux.length-2], 1, BITNESS);
		// 110
		mem.connectSrc(out_demux[out_demux.length-2], 0, 3*BITNESS);
		// 001
		C.connectSrc(out_demux[out_demux.length-3], 1, BITNESS);
		// 101
		L.connectSrc(out_demux[out_demux.length-3], 0, BITNESS);
		// 011
		E.connectSrc(out_demux[out_demux.length-4], 1, BITNESS);
		// 111
		A.connectSrc(out_demux[out_demux.length-4], 0, BITNESS);
		// flags
		// enable flags for comparisons [1x111SSS]
		Node is_cmp = new AllNode(4);
		is_cmp.connectSrc(opNOPs[7], 0, 0);
		is_cmp.connectSrc(opNOPs[5], 0, 1);
		is_cmp.connectSrc(opNOPs[4], 0, 2);
		is_cmp.connectSrc(opNOPs[3], 0, 3);
		ORNode set_flags = new ORNode();
		set_flags.connectSrc(is_cmp, 0, 0);
		set_flags.connectSrc(comb_alu, 0, 1);
		// also enable flags for CPC & STC ops
		Node is_c_op = new AllNode(7);
		Node rev_7bit = new NOTNode();
		rev_7bit.connectSrc(opNOPs[7], 0, 0);
		Node rev_6bit = new NOTNode();
		rev_6bit.connectSrc(opNOPs[6], 0, 0);
		is_c_op.connectSrc(rev_7bit, 0, 0);
		is_c_op.connectSrc(rev_6bit, 0, 1);
		is_c_op.connectSrc(opNOPs[5], 0, 2);
		is_c_op.connectSrc(opNOPs[4], 0, 3);
		is_c_op.connectSrc(opNOPs[2], 0, 4);
		is_c_op.connectSrc(opNOPs[1], 0, 5);
		is_c_op.connectSrc(opNOPs[0], 0, 6);
		ORNode set_flags_enh = new ORNode();
		set_flags_enh.connectSrc(set_flags, 0, 0);
		set_flags_enh.connectSrc(is_c_op, 0, 1);
		F.connectSrc(set_flags_enh, 0, BITNESS);
		
		// connect ALU output
		for (int i = 0; i < BITNESS; i++) {
			A.connectSrc(alu, i, i);
			B.connectSrc(alu, i, i);
			C.connectSrc(alu, i, i);
			D.connectSrc(alu, i, i);
			E.connectSrc(alu, i, i);
			H.connectSrc(alu, i, i);
			L.connectSrc(alu, i, i);
			mem.connectSrc(alu, i, i+2*BITNESS);
			// for initialization
			A.connectSrc(zero, 0, i);
			B.connectSrc(zero, 0, i);
			C.connectSrc(zero, 0, i);
			D.connectSrc(zero, 0, i);
			E.connectSrc(zero, 0, i);
			H.connectSrc(zero, 0, i);
			L.connectSrc(zero, 0, i);
			F.connectSrc(zero, 0, i);
			PC.connectSrc(zero, 0, i);
			PC.connectSrc(zero, 0, i + BITNESS);
		}
		// memory addressing
		MultiMux addr_sel = new MultiMux(2*BITNESS);
		NOTNode neg_bit5 = new NOTNode();
		neg_bit5.connectSrc(opNOPs[5], 0, 0);
		ANDNode is_reg_pair = new ANDNode();
		is_reg_pair.connectSrc(neg_bit5, 0, 0);
		is_reg_pair.connectSrc(is_mem_store, 0, 1);
		addr_sel.connectSrc(is_reg_pair, 0, 4*BITNESS);
		for (int i = 0; i < BITNESS; i++) {
			addr_sel.connectSrc(reg_pair_sel, i, i);
			addr_sel.connectSrc(reg_pair_sel, i+BITNESS, i+BITNESS);
			addr_sel.connectSrc(inNOPs_A[i], 0, i+2*BITNESS);
			addr_sel.connectSrc(inNOPs_B[i], 0, i+3*BITNESS);
			mem.connectSrc(addr_sel, i, i);
			mem.connectSrc(addr_sel, i+BITNESS, i+BITNESS);
		}
		// TODO prevent flags change for mov, inc, dec etc.
		Mux not_c_flag_val = new Mux();
		not_c_flag_val.connectSrc(F, C_FLAG, 0);
		not_c_flag_val.connectSrc(opNOPs[3], 0, 1);
		not_c_flag_val.connectSrc(opNOPs[3], 0, 2);
		Node c_flag_val = new NOTNode();
		c_flag_val.connectSrc(not_c_flag_val, 0, 0);
		Mux c_flag_src = new Mux();
		c_flag_src.connectSrc(c_flag_val, 0, 0);
		c_flag_src.connectSrc(alu, BITNESS+ALU.C_FLAG_SHIFT, 1);
		c_flag_src.connectSrc(is_c_op, 0, 2);
		F.connectSrc(c_flag_src, 0, C_FLAG);
		Mux z_flag_src = new Mux();
		z_flag_src.connectSrc(F, Z_FLAG, 0);
		z_flag_src.connectSrc(alu, BITNESS+ALU.Z_FLAG_SHIFT, 1);
		z_flag_src.connectSrc(is_c_op, 0, 2);
		F.connectSrc(z_flag_src, 0, Z_FLAG);
		Mux s_flag_src = new Mux();
		s_flag_src.connectSrc(F, S_FLAG, 0);
		s_flag_src.connectSrc(alu, BITNESS+ALU.S_FLAG_SHIFT, 1);
		s_flag_src.connectSrc(is_c_op, 0, 2);
		F.connectSrc(s_flag_src, 0, S_FLAG);
		Mux p_flag_src = new Mux();
		p_flag_src.connectSrc(F, P_FLAG, 0);
		p_flag_src.connectSrc(alu, BITNESS+ALU.P_FLAG_SHIFT, 1);
		p_flag_src.connectSrc(is_c_op, 0, 2);
		F.connectSrc(p_flag_src, 0, P_FLAG);
		// TODO implement A-flag (H-flag)
		F.connectSrc(clock, 0, H_FLAG);
		F.connectSrc(clock, 0, I_FLAG);
		F.connectSrc(clock, 0, F3_FLAG);
		F.connectSrc(clock, 0, F1_FLAG);
		
		// for initialization
		A.connectSrc(zero, 0, BITNESS);
		B.connectSrc(zero, 0, BITNESS);
		C.connectSrc(zero, 0, BITNESS);
		D.connectSrc(zero, 0, BITNESS);
		E.connectSrc(zero, 0, BITNESS);
		H.connectSrc(zero, 0, BITNESS);
		L.connectSrc(zero, 0, BITNESS);
		F.connectSrc(zero, 0, BITNESS);
		PC.connectSrc(zero, 0, 2*BITNESS);
	}