From 7fd15b67afa5abd20c0982bdd6bcb7191831bf73 Mon Sep 17 00:00:00 2001
From: Martin Braun <martin.braun@kit.edu>
Date: Fri, 15 Mar 2013 02:12:20 -0700
Subject: Squash/rebased martin/ofdm-master onto trial merge branch

Conflicts:
	gr-blocks/include/blocks/CMakeLists.txt
---
 gr-blocks/include/blocks/CMakeLists.txt | 2 ++
 1 file changed, 2 insertions(+)

(limited to 'gr-blocks/include/blocks/CMakeLists.txt')

diff --git a/gr-blocks/include/blocks/CMakeLists.txt b/gr-blocks/include/blocks/CMakeLists.txt
index c7b3cb918e..10e132ed92 100644
--- a/gr-blocks/include/blocks/CMakeLists.txt
+++ b/gr-blocks/include/blocks/CMakeLists.txt
@@ -155,6 +155,7 @@ install(FILES
     peak_detector2_fb.h
     probe_rate.h
     regenerate_bb.h
+    repack_bits_bb.h 
     repeat.h
     rms_cf.h
     rms_ff.h
@@ -174,6 +175,7 @@ install(FILES
     throttle.h
     transcendental.h
     tuntap_pdu.h
+    tagged_stream_mux.h
     uchar_to_float.h
     udp_sink.h
     udp_source.h
-- 
cgit v1.2.3


From a792bb88f3c3caa347506503de973aafaf78e0af Mon Sep 17 00:00:00 2001
From: Tom Rondeau <trondeau@vt.edu>
Date: Sat, 16 Mar 2013 19:30:59 -0400
Subject: blocks: moving copy, endian_swap, head, skiphead,
 vector_source/sink/insert to gr-blocks.

---
 gr-blocks/grc/blocks_block_tree.xml           |   7 +
 gr-blocks/grc/blocks_copy.xml                 |  75 +++++
 gr-blocks/grc/blocks_endian_swap.xml          |  41 +++
 gr-blocks/grc/blocks_head.xml                 |  65 ++++
 gr-blocks/grc/blocks_skiphead.xml             |  65 ++++
 gr-blocks/grc/blocks_vector_insert_x.xml      |  80 +++++
 gr-blocks/grc/blocks_vector_sink_x.xml        |  54 +++
 gr-blocks/grc/blocks_vector_source_x.xml      |  85 +++++
 gr-blocks/include/blocks/CMakeLists.txt       |  11 +
 gr-blocks/include/blocks/annotator_1to1.h     |  60 ++++
 gr-blocks/include/blocks/annotator_alltoall.h |  61 ++++
 gr-blocks/include/blocks/annotator_raw.h      |  57 ++++
 gr-blocks/include/blocks/copy.h               |  54 +++
 gr-blocks/include/blocks/endian_swap.h        |  50 +++
 gr-blocks/include/blocks/head.h               |  55 ++++
 gr-blocks/include/blocks/rotator.h            |  63 ++++
 gr-blocks/include/blocks/skiphead.h           |  53 +++
 gr-blocks/include/blocks/vector_insert_X.h.t  |  54 +++
 gr-blocks/include/blocks/vector_sink_X.h.t    |  54 +++
 gr-blocks/include/blocks/vector_source_X.h.t  |  56 ++++
 gr-blocks/lib/CMakeLists.txt                  |  17 +-
 gr-blocks/lib/annotator_1to1_impl.cc          | 113 +++++++
 gr-blocks/lib/annotator_1to1_impl.h           |  56 ++++
 gr-blocks/lib/annotator_alltoall_impl.cc      | 117 +++++++
 gr-blocks/lib/annotator_alltoall_impl.h       |  56 ++++
 gr-blocks/lib/annotator_raw_impl.cc           | 112 +++++++
 gr-blocks/lib/annotator_raw_impl.h            |  54 +++
 gr-blocks/lib/copy_impl.cc                    |  82 +++++
 gr-blocks/lib/copy_impl.h                     |  55 ++++
 gr-blocks/lib/endian_swap_impl.cc             | 110 +++++++
 gr-blocks/lib/endian_swap_impl.h              |  48 +++
 gr-blocks/lib/head_impl.cc                    |  75 +++++
 gr-blocks/lib/head_impl.h                     |  52 +++
 gr-blocks/lib/qa_block_tags.cc                | 451 ++++++++++++++++++++++++++
 gr-blocks/lib/qa_block_tags.h                 |  50 +++
 gr-blocks/lib/qa_blocks.cc                    |   4 +
 gr-blocks/lib/qa_rotator.cc                   |  75 +++++
 gr-blocks/lib/qa_rotator.h                    |  39 +++
 gr-blocks/lib/skiphead_impl.cc                |  93 ++++++
 gr-blocks/lib/skiphead_impl.h                 |  50 +++
 gr-blocks/lib/vector_insert_X_impl.cc.t       | 109 +++++++
 gr-blocks/lib/vector_insert_X_impl.h.t        |  58 ++++
 gr-blocks/lib/vector_sink_X_impl.cc.t         |  83 +++++
 gr-blocks/lib/vector_sink_X_impl.h.t          |  56 ++++
 gr-blocks/lib/vector_source_X_impl.cc.t       | 144 ++++++++
 gr-blocks/lib/vector_source_X_impl.h.t        |  62 ++++
 gr-blocks/python/qa_copy.py                   |  58 ++++
 gr-blocks/python/qa_endian_swap.py            |  66 ++++
 gr-blocks/python/qa_head.py                   |  47 +++
 gr-blocks/python/qa_skiphead.py               | 103 ++++++
 gr-blocks/python/qa_vector_insert.py          |  59 ++++
 gr-blocks/python/qa_vector_sink_source.py     |  66 ++++
 gr-blocks/swig/blocks_swig.i                  |  57 ++++
 53 files changed, 3776 insertions(+), 1 deletion(-)
 create mode 100644 gr-blocks/grc/blocks_copy.xml
 create mode 100644 gr-blocks/grc/blocks_endian_swap.xml
 create mode 100644 gr-blocks/grc/blocks_head.xml
 create mode 100644 gr-blocks/grc/blocks_skiphead.xml
 create mode 100644 gr-blocks/grc/blocks_vector_insert_x.xml
 create mode 100644 gr-blocks/grc/blocks_vector_sink_x.xml
 create mode 100644 gr-blocks/grc/blocks_vector_source_x.xml
 create mode 100644 gr-blocks/include/blocks/annotator_1to1.h
 create mode 100644 gr-blocks/include/blocks/annotator_alltoall.h
 create mode 100644 gr-blocks/include/blocks/annotator_raw.h
 create mode 100644 gr-blocks/include/blocks/copy.h
 create mode 100644 gr-blocks/include/blocks/endian_swap.h
 create mode 100644 gr-blocks/include/blocks/head.h
 create mode 100644 gr-blocks/include/blocks/rotator.h
 create mode 100644 gr-blocks/include/blocks/skiphead.h
 create mode 100644 gr-blocks/include/blocks/vector_insert_X.h.t
 create mode 100644 gr-blocks/include/blocks/vector_sink_X.h.t
 create mode 100644 gr-blocks/include/blocks/vector_source_X.h.t
 create mode 100644 gr-blocks/lib/annotator_1to1_impl.cc
 create mode 100644 gr-blocks/lib/annotator_1to1_impl.h
 create mode 100644 gr-blocks/lib/annotator_alltoall_impl.cc
 create mode 100644 gr-blocks/lib/annotator_alltoall_impl.h
 create mode 100644 gr-blocks/lib/annotator_raw_impl.cc
 create mode 100644 gr-blocks/lib/annotator_raw_impl.h
 create mode 100644 gr-blocks/lib/copy_impl.cc
 create mode 100644 gr-blocks/lib/copy_impl.h
 create mode 100644 gr-blocks/lib/endian_swap_impl.cc
 create mode 100644 gr-blocks/lib/endian_swap_impl.h
 create mode 100644 gr-blocks/lib/head_impl.cc
 create mode 100644 gr-blocks/lib/head_impl.h
 create mode 100644 gr-blocks/lib/qa_block_tags.cc
 create mode 100644 gr-blocks/lib/qa_block_tags.h
 create mode 100644 gr-blocks/lib/qa_rotator.cc
 create mode 100644 gr-blocks/lib/qa_rotator.h
 create mode 100644 gr-blocks/lib/skiphead_impl.cc
 create mode 100644 gr-blocks/lib/skiphead_impl.h
 create mode 100644 gr-blocks/lib/vector_insert_X_impl.cc.t
 create mode 100644 gr-blocks/lib/vector_insert_X_impl.h.t
 create mode 100644 gr-blocks/lib/vector_sink_X_impl.cc.t
 create mode 100644 gr-blocks/lib/vector_sink_X_impl.h.t
 create mode 100644 gr-blocks/lib/vector_source_X_impl.cc.t
 create mode 100644 gr-blocks/lib/vector_source_X_impl.h.t
 create mode 100755 gr-blocks/python/qa_copy.py
 create mode 100644 gr-blocks/python/qa_endian_swap.py
 create mode 100755 gr-blocks/python/qa_head.py
 create mode 100755 gr-blocks/python/qa_skiphead.py
 create mode 100755 gr-blocks/python/qa_vector_insert.py
 create mode 100755 gr-blocks/python/qa_vector_sink_source.py

(limited to 'gr-blocks/include/blocks/CMakeLists.txt')

diff --git a/gr-blocks/grc/blocks_block_tree.xml b/gr-blocks/grc/blocks_block_tree.xml
index 512252cda6..618539354b 100644
--- a/gr-blocks/grc/blocks_block_tree.xml
+++ b/gr-blocks/grc/blocks_block_tree.xml
@@ -38,6 +38,8 @@
 		<block>blocks_message_burst_source</block>
 		<block>blocks_udp_source</block>
 		<block>blocks_wavfile_source</block>
+		<block>blocks_vector_source_x</block>
+		<block>blocks_vector_insert_x</block>
 	</cat>
 	<cat>
 	        <name>Sinks (New)</name>
@@ -50,6 +52,7 @@
 		<block>blocks_tagged_file_sink</block>
 		<block>blocks_udp_sink</block>
 		<block>blocks_wavfile_sink</block>
+		<block>blocks_vector_sink_x</block>
 	</cat>
 	<cat>
 		<name>Math Operations (New) </name>
@@ -121,6 +124,7 @@
 		<block>blocks_stretch_ff</block>
                 <block>blocks_threshold_ff</block>
                 <block>blocks_burst_tagger</block>
+                <block>blocks_endian_swap</block>
 	</cat>
 	<cat>
 	        <name>Misc Conversions (New) </name>
@@ -133,6 +137,9 @@
 	        <name>Misc (New) </name>
                 <block>blocks_throttle</block>
                 <block>blocks_probe_rate</block>
+		<block>blocks_head</block>
+		<block>blocks_skiphead</block>
+                <block>blocks_copy</block>
 	</cat>
 	<cat>
 	        <name>Networking</name>
diff --git a/gr-blocks/grc/blocks_copy.xml b/gr-blocks/grc/blocks_copy.xml
new file mode 100644
index 0000000000..55c4b343d3
--- /dev/null
+++ b/gr-blocks/grc/blocks_copy.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##Copy
+###################################################
+ -->
+<block>
+	<name>Copy</name>
+	<key>blocks_copy</key>
+	<import>from gnuradio import blocks</import>
+	<make>blocks.copy($type.size*$vlen)
+self.$(id).set_enabled($enabled)</make>
+	<callback>set_enabled($enabled)</callback>
+	<param>
+		<name>Type</name>
+		<key>type</key>
+		<type>enum</type>
+		<option>
+			<name>Complex</name>
+			<key>complex</key>
+			<opt>size:gr.sizeof_gr_complex</opt>
+		</option>
+		<option>
+			<name>Float</name>
+			<key>float</key>
+			<opt>size:gr.sizeof_float</opt>
+		</option>
+		<option>
+			<name>Int</name>
+			<key>int</key>
+			<opt>size:gr.sizeof_int</opt>
+		</option>
+		<option>
+			<name>Short</name>
+			<key>short</key>
+			<opt>size:gr.sizeof_short</opt>
+		</option>
+		<option>
+			<name>Byte</name>
+			<key>byte</key>
+			<opt>size:gr.sizeof_char</opt>
+		</option>
+	</param>
+	<param>
+		<name>Enabled</name>
+		<key>enabled</key>
+		<value>True</value>
+		<type>bool</type>
+		<option>
+			<name>Enabled</name>
+			<key>True</key>
+		</option>
+		<option>
+			<name>Disabled</name>
+			<key>False</key>
+		</option>
+	</param>
+	<param>
+		<name>Vec Length</name>
+		<key>vlen</key>
+		<value>1</value>
+		<type>int</type>
+	</param>
+	<check>$vlen &gt; 0</check>
+	<sink>
+		<name>in</name>
+		<type>$type</type>
+		<vlen>$vlen</vlen>
+	</sink>
+	<source>
+		<name>out</name>
+		<type>$type</type>
+		<vlen>$vlen</vlen>
+	</source>
+</block>
diff --git a/gr-blocks/grc/blocks_endian_swap.xml b/gr-blocks/grc/blocks_endian_swap.xml
new file mode 100644
index 0000000000..5fea420664
--- /dev/null
+++ b/gr-blocks/grc/blocks_endian_swap.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##Add Block:
+##	all types, 1 output, 2 to inf inputs
+###################################################
+ -->
+<block>
+	<name>Endian Swap</name>
+	<key>blocks_endian_swap</key>
+	<import>from gnuradio import blocks</import>
+	<make>blocks.endian_swap($type.size)</make>
+	<param>
+		<name>IO Type</name>
+		<key>type</key>
+		<type>enum</type>
+		<option>
+			<name>Complex</name>
+			<key>complex</key>
+			<opt>size:8</opt>
+		</option>
+		<option>
+			<name>Int</name>
+			<key>s32</key>
+			<opt>size:4</opt>
+		</option>
+		<option>
+			<name>Short</name>
+			<key>s16</key>
+			<opt>size:2</opt>
+		</option>
+	</param>
+	<sink>
+		<name>in</name>
+		<type>$type</type>
+	</sink>
+	<source>
+		<name>out</name>
+		<type>$type</type>
+	</source>
+</block>
diff --git a/gr-blocks/grc/blocks_head.xml b/gr-blocks/grc/blocks_head.xml
new file mode 100644
index 0000000000..8b6e67820c
--- /dev/null
+++ b/gr-blocks/grc/blocks_head.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##Head
+###################################################
+ -->
+<block>
+	<name>Head</name>
+	<key>blocks_head</key>
+	<import>from gnuradio import blocks</import>
+	<make>blocks.head($type.size*$vlen, $num_items)</make>
+	<param>
+		<name>Type</name>
+		<key>type</key>
+		<type>enum</type>
+		<option>
+			<name>Complex</name>
+			<key>complex</key>
+			<opt>size:gr.sizeof_gr_complex</opt>
+		</option>
+		<option>
+			<name>Float</name>
+			<key>float</key>
+			<opt>size:gr.sizeof_float</opt>
+		</option>
+		<option>
+			<name>Int</name>
+			<key>int</key>
+			<opt>size:gr.sizeof_int</opt>
+		</option>
+		<option>
+			<name>Short</name>
+			<key>short</key>
+			<opt>size:gr.sizeof_short</opt>
+		</option>
+		<option>
+			<name>Byte</name>
+			<key>byte</key>
+			<opt>size:gr.sizeof_char</opt>
+		</option>
+	</param>
+	<param>
+		<name>Num Items</name>
+		<key>num_items</key>
+		<value>1024</value>
+		<type>int</type>
+	</param>
+	<param>
+		<name>Vec Length</name>
+		<key>vlen</key>
+		<value>1</value>
+		<type>int</type>
+	</param>
+	<check>$vlen &gt; 0</check>
+	<sink>
+		<name>in</name>
+		<type>$type</type>
+		<vlen>$vlen</vlen>
+	</sink>
+	<source>
+		<name>out</name>
+		<type>$type</type>
+		<vlen>$vlen</vlen>
+	</source>
+</block>
diff --git a/gr-blocks/grc/blocks_skiphead.xml b/gr-blocks/grc/blocks_skiphead.xml
new file mode 100644
index 0000000000..7d90862830
--- /dev/null
+++ b/gr-blocks/grc/blocks_skiphead.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##Skip Head
+###################################################
+ -->
+<block>
+	<name>Skip Head</name>
+	<key>blocks_skiphead</key>
+	<import>from gnuradio import blocks</import>
+	<make>blocks.skiphead($type.size*$vlen, $num_items)</make>
+	<param>
+		<name>Type</name>
+		<key>type</key>
+		<type>enum</type>
+		<option>
+			<name>Complex</name>
+			<key>complex</key>
+			<opt>size:gr.sizeof_gr_complex</opt>
+		</option>
+		<option>
+			<name>Float</name>
+			<key>float</key>
+			<opt>size:gr.sizeof_float</opt>
+		</option>
+		<option>
+			<name>Int</name>
+			<key>int</key>
+			<opt>size:gr.sizeof_int</opt>
+		</option>
+		<option>
+			<name>Short</name>
+			<key>short</key>
+			<opt>size:gr.sizeof_short</opt>
+		</option>
+		<option>
+			<name>Byte</name>
+			<key>byte</key>
+			<opt>size:gr.sizeof_char</opt>
+		</option>
+	</param>
+	<param>
+		<name>Num Items</name>
+		<key>num_items</key>
+		<value>1024</value>
+		<type>int</type>
+	</param>
+	<param>
+		<name>Vec Length</name>
+		<key>vlen</key>
+		<value>1</value>
+		<type>int</type>
+	</param>
+	<check>$vlen &gt; 0</check>
+	<sink>
+		<name>in</name>
+		<type>$type</type>
+		<vlen>$vlen</vlen>
+	</sink>
+	<source>
+		<name>out</name>
+		<type>$type</type>
+		<vlen>$vlen</vlen>
+	</source>
+</block>
diff --git a/gr-blocks/grc/blocks_vector_insert_x.xml b/gr-blocks/grc/blocks_vector_insert_x.xml
new file mode 100644
index 0000000000..2bc7ada2e6
--- /dev/null
+++ b/gr-blocks/grc/blocks_vector_insert_x.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##Vector Source
+###################################################
+ -->
+<block>
+	<name>Vector Insert</name>
+	<key>blocks_vector_insert_x</key>
+	<import>from gnuradio import blocks</import>
+	<make>blocks.vector_insert_$(type.fcn)($vector, $period, $offset)</make>
+	<param>
+		<name>Output Type</name>
+		<key>type</key>
+		<type>enum</type>
+		<option>
+			<name>Byte</name>
+			<key>byte</key>
+			<opt>fcn:b</opt>
+			<opt>vec_type:int_vector</opt>
+		</option>
+		<option>
+			<name>Complex</name>
+			<key>complex</key>
+			<opt>fcn:c</opt>
+			<opt>vec_type:complex_vector</opt>
+		</option>
+		<option>
+			<name>Float</name>
+			<key>float</key>
+			<opt>fcn:f</opt>
+			<opt>vec_type:real_vector</opt>
+		</option>
+		<option>
+			<name>Int</name>
+			<key>int</key>
+			<opt>fcn:i</opt>
+			<opt>vec_type:int_vector</opt>
+		</option>
+		<option>
+			<name>Short</name>
+			<key>short</key>
+			<opt>fcn:s</opt>
+			<opt>vec_type:int_vector</opt>
+		</option>
+	</param>
+	<param>
+		<name>Vector</name>
+		<key>vector</key>
+		<value>0, 0, 0</value>
+		<type>$type.vec_type</type>
+	</param>
+	<param>
+		<name>Periodicity</name>
+		<key>period</key>
+		<value>100</value>
+		<type>int</type>
+	</param>
+	<param>
+		<name>Offset</name>
+		<key>offset</key>
+		<value>0</value>
+		<type>int</type>
+	</param>
+	<sink>
+		<name>in</name>
+		<type>$type</type>
+	</sink>
+	<source>
+		<name>out</name>
+		<type>$type</type>
+	</source>
+
+    <doc>
+        Periodicity, the length of the periodicity at which the vector should be inserted at the output.
+        (i.e. one vector for every N output items)
+
+        Offset sepcifies where in the cycle period we should begin at.
+    </doc>
+</block>
diff --git a/gr-blocks/grc/blocks_vector_sink_x.xml b/gr-blocks/grc/blocks_vector_sink_x.xml
new file mode 100644
index 0000000000..7f51731975
--- /dev/null
+++ b/gr-blocks/grc/blocks_vector_sink_x.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##Vector sink
+###################################################
+ -->
+<block>
+	<name>Vector Sink</name>
+	<key>blocks_vector_sink_x</key>
+	<import>from gnuradio import blocks</import>
+	<make>blocks.vector_sink_$(type.fcn)($vlen)</make>
+	<param>
+		<name>Input Type</name>
+		<key>type</key>
+		<type>enum</type>
+		<option>
+			<name>Complex</name>
+			<key>complex</key>
+			<opt>fcn:c</opt>
+		</option>
+		<option>
+			<name>Float</name>
+			<key>float</key>
+			<opt>fcn:f</opt>
+		</option>
+		<option>
+			<name>Int</name>
+			<key>int</key>
+			<opt>fcn:i</opt>
+		</option>
+		<option>
+			<name>Short</name>
+			<key>short</key>
+			<opt>fcn:s</opt>
+		</option>
+		<option>
+			<name>Byte</name>
+			<key>byte</key>
+			<opt>fcn:b</opt>
+		</option>
+	</param>
+	<param>
+		<name>Vec Length</name>
+		<key>vlen</key>
+		<value>1</value>
+		<type>int</type>
+	</param>
+	<check>$vlen &gt; 0</check>
+	<sink>
+		<name>in</name>
+		<type>$type</type>
+		<vlen>$vlen</vlen>
+	</sink>
+</block>
diff --git a/gr-blocks/grc/blocks_vector_source_x.xml b/gr-blocks/grc/blocks_vector_source_x.xml
new file mode 100644
index 0000000000..5221c4f3eb
--- /dev/null
+++ b/gr-blocks/grc/blocks_vector_source_x.xml
@@ -0,0 +1,85 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##Vector Source
+###################################################
+ -->
+<block>
+	<name>Vector Source</name>
+	<key>blocks_vector_source_x</key>
+	<import>from gnuradio import blocks</import>
+	<make>blocks.vector_source_$(type.fcn)($vector, $repeat, $vlen, $tags)</make>
+	<param>
+		<name>Output Type</name>
+		<key>type</key>
+		<type>enum</type>
+		<option>
+			<name>Complex</name>
+			<key>complex</key>
+			<opt>fcn:c</opt>
+			<opt>vec_type:complex_vector</opt>
+		</option>
+		<option>
+			<name>Float</name>
+			<key>float</key>
+			<opt>fcn:f</opt>
+			<opt>vec_type:real_vector</opt>
+		</option>
+		<option>
+			<name>Int</name>
+			<key>int</key>
+			<opt>fcn:i</opt>
+			<opt>vec_type:int_vector</opt>
+		</option>
+		<option>
+			<name>Short</name>
+			<key>short</key>
+			<opt>fcn:s</opt>
+			<opt>vec_type:int_vector</opt>
+		</option>
+		<option>
+			<name>Byte</name>
+			<key>byte</key>
+			<opt>fcn:b</opt>
+			<opt>vec_type:int_vector</opt>
+		</option>
+	</param>
+	<param>
+		<name>Vector</name>
+		<key>vector</key>
+		<value>[0, 0, 0]</value>
+		<type>raw</type>
+	</param>
+	<param>
+		<name>Tags</name>
+		<key>tags</key>
+		<value>[]</value>
+		<type>raw</type>
+	</param>
+	<param>
+		<name>Repeat</name>
+		<key>repeat</key>
+		<value>True</value>
+		<type>enum</type>
+		<option>
+			<name>Yes</name>
+			<key>True</key>
+		</option>
+		<option>
+			<name>No</name>
+			<key>False</key>
+		</option>
+	</param>
+	<param>
+		<name>Vec Length</name>
+		<key>vlen</key>
+		<value>1</value>
+		<type>int</type>
+	</param>
+	<check>$vlen &gt; 0</check>
+	<source>
+		<name>out</name>
+		<type>$type</type>
+		<vlen>$vlen</vlen>
+	</source>
+</block>
diff --git a/gr-blocks/include/blocks/CMakeLists.txt b/gr-blocks/include/blocks/CMakeLists.txt
index 10e132ed92..a7cc1e0a31 100644
--- a/gr-blocks/include/blocks/CMakeLists.txt
+++ b/gr-blocks/include/blocks/CMakeLists.txt
@@ -88,6 +88,9 @@ expand_h(sub_XX             ss ii ff cc)
 expand_h(xor_XX             bb ss ii)
 expand_h(packed_to_unpacked_XX bb ss ii)
 expand_h(unpacked_to_packed_XX bb ss ii)
+expand_h(vector_insert_X    b s i f c)
+expand_h(vector_sink_X      b s i f c)
+expand_h(vector_source_X    b s i f c)
 
 add_custom_target(blocks_generated_includes DEPENDS
     ${generated_includes}
@@ -106,10 +109,14 @@ install(FILES
     fxpt_nco.h
     fxpt_vco.h
     log2_const.h
+    rotator.h
     nco.h
     vco.h
     wavfile.h
     add_ff.h
+    annotator_1to1.h
+    annotator_alltoall.h
+    annotator_raw.h
     bin_statistics_f.h
     burst_tagger.h
     char_to_float.h
@@ -122,8 +129,10 @@ install(FILES
     complex_to_mag_squared.h
     complex_to_arg.h
     conjugate_cc.h
+    copy.h
     deinterleave.h
     delay.h
+    endian_swap.h
     file_source.h
     file_meta_sink.h
     file_meta_source.h
@@ -132,6 +141,7 @@ install(FILES
     float_to_int.h
     float_to_short.h
     float_to_uchar.h
+    head.h
     int_to_float.h
     interleave.h
     interleaved_short_to_complex.h
@@ -161,6 +171,7 @@ install(FILES
     rms_ff.h
     short_to_char.h
     short_to_float.h
+    skiphead.h
     socket_pdu.h
     stream_mux.h
     stream_to_streams.h
diff --git a/gr-blocks/include/blocks/annotator_1to1.h b/gr-blocks/include/blocks/annotator_1to1.h
new file mode 100644
index 0000000000..6cc8db6eef
--- /dev/null
+++ b/gr-blocks/include/blocks/annotator_1to1.h
@@ -0,0 +1,60 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010,2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_ANNOTATOR_1TO1_H
+#define	INCLUDED_GR_ANNOTATOR_1TO1_H
+
+#include <blocks/api.h>
+#include <gr_sync_block.h>
+
+namespace gr {
+  namespace blocks {
+
+    /*!
+     * \brief 1-to-1 stream annotator testing block. FOR TESTING PURPOSES ONLY.
+     *
+     * This block creates tags to be sent downstream every 10,000
+     * items it sees. The tags contain the name and ID of the
+     * instantiated block, use "seq" as a key, and have a counter that
+     * increments by 1 for every tag produced that is used as the
+     * tag's value. The tags are propagated using the 1-to-1 policy.
+     *
+     * It also stores a copy of all tags it sees flow past it. These
+     * tags can be recalled externally with the data() member.
+     *
+     * This block is only meant for testing and showing how to use the tags.
+     */
+    class BLOCKS_API annotator_1to1 : virtual public gr_sync_block
+    {
+    public:
+      // gr::blocks::annotator_1to1::sptr
+      typedef boost::shared_ptr<annotator_1to1> sptr;
+
+      static sptr make(int when, size_t sizeof_stream_item);
+
+      virtual std::vector<gr_tag_t> data() const = 0;
+    };
+
+  } /* namespace blocks */
+} /* namespace gr */
+
+#endif /* INCLUDED_GR_ANNOTATOR_1TO1_H */
diff --git a/gr-blocks/include/blocks/annotator_alltoall.h b/gr-blocks/include/blocks/annotator_alltoall.h
new file mode 100644
index 0000000000..558aea69ca
--- /dev/null
+++ b/gr-blocks/include/blocks/annotator_alltoall.h
@@ -0,0 +1,61 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010,2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_ANNOTATOR_ALLTOALL_H
+#define	INCLUDED_GR_ANNOTATOR_ALLTOALL_H
+
+#include <blocks/api.h>
+#include <gr_sync_block.h>
+
+namespace gr {
+  namespace blocks {
+
+    /*!
+     * \brief All-to-all stream annotator testing block. FOR TESTING PURPOSES ONLY.
+     *
+     * This block creates tags to be sent downstream every 10,000
+     * items it sees. The tags contain the name and ID of the
+     * instantiated block, use "seq" as a key, and have a counter that
+     * increments by 1 for every tag produced that is used as the
+     * tag's value. The tags are propagated using the all-to-all
+     * policy.
+     *
+     * It also stores a copy of all tags it sees flow past it. These
+     * tags can be recalled externally with the data() member.
+     *
+     * This block is only meant for testing and showing how to use the tags.
+     */
+    class BLOCKS_API annotator_alltoall : virtual public gr_sync_block
+    {
+    public:
+      // gr::blocks::annotator_alltoall::sptr
+      typedef boost::shared_ptr<annotator_alltoall> sptr;
+
+      static sptr make(int when, size_t sizeof_stream_item);
+
+      virtual std::vector<gr_tag_t> data() const = 0;
+    };
+
+  } /* namespace blocks */
+} /* namespace gr */
+
+#endif /* INCLUDED_GR_ANNOTATOR_ALLTOALL_H */
diff --git a/gr-blocks/include/blocks/annotator_raw.h b/gr-blocks/include/blocks/annotator_raw.h
new file mode 100644
index 0000000000..e835f0bd8d
--- /dev/null
+++ b/gr-blocks/include/blocks/annotator_raw.h
@@ -0,0 +1,57 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010,2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_ANNOTATOR_RAW_H
+#define	INCLUDED_GR_ANNOTATOR_RAW_H
+
+#include <blocks/api.h>
+#include <gr_sync_block.h>
+#include <gr_tags.h>
+
+namespace gr {
+  namespace blocks {
+
+    /*!
+     * \brief raw stream annotator testing block.
+     *
+     * This block creates arbitrary tags to be sent downstream blocks
+     * to be sent are set manually via accessor methods and are sent
+     * only once.
+     *
+     * This block is intended for testing of tag related blocks
+     */
+    class BLOCKS_API annotator_raw : virtual public gr_sync_block
+    {
+    public:
+      // gr::blocks::annotator_raw::sptr
+      typedef boost::shared_ptr<annotator_raw> sptr;
+
+      static sptr make(size_t sizeof_stream_item);
+
+      // insert a tag to be added
+      void add_tag(uint64_t offset, pmt::pmt_t key, pmt::pmt_t val);
+    };
+
+  } /* namespace blocks */
+} /* namespace gr */
+
+#endif /* INCLUDED_GR_ANNOTATOR_RAW_H */
diff --git a/gr-blocks/include/blocks/copy.h b/gr-blocks/include/blocks/copy.h
new file mode 100644
index 0000000000..5ed0ea0e92
--- /dev/null
+++ b/gr-blocks/include/blocks/copy.h
@@ -0,0 +1,54 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2009,2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_COPY_H
+#define INCLUDED_GR_COPY_H
+
+#include <blocks/api.h>
+#include <gr_block.h>
+
+namespace gr {
+  namespace blocks {
+
+    /*!
+     * \brief output[i] = input[i]
+     * \ingroup misc_blk
+     *
+     * When enabled (default), this block copies its input to its
+     * output. When disabled, this block drops its input on the floor.
+     */
+    class BLOCKS_API copy : virtual public gr_block
+    {
+    public:
+      // gr::blocks::copy::sptr
+      typedef boost::shared_ptr<copy> sptr;
+
+      static sptr make(size_t itemsize);
+
+      virtual void set_enabled(bool enable) = 0;
+      virtual bool enabled() const = 0;
+    };
+
+  } /* namespace blocks */
+} /* namespace gr */
+
+#endif /* INCLUDED_GR_COPY_H */
diff --git a/gr-blocks/include/blocks/endian_swap.h b/gr-blocks/include/blocks/endian_swap.h
new file mode 100644
index 0000000000..4b5a76218e
--- /dev/null
+++ b/gr-blocks/include/blocks/endian_swap.h
@@ -0,0 +1,50 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2012,2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_ENDIAN_SWAP_H
+#define INCLUDED_GR_ENDIAN_SWAP_H
+
+#include <blocks/api.h>
+#include <gr_sync_block.h>
+
+namespace gr {
+  namespace blocks {
+
+    /*!
+     * \brief Convert stream of items into thier byte swapped version
+     *
+     * \param item_size_bytes number of bytes per item, 1=no-op, 
+     *        2=uint16_t, 4=uint32_t, 8=uint64_t
+     */
+    class BLOCKS_API endian_swap : virtual public gr_sync_block
+    {
+    public:
+      // gr::blocks::endian_swap::sptr
+      typedef boost::shared_ptr<endian_swap> sptr;
+
+      static sptr make(size_t item_size_bytes=1);
+    };
+
+  } /* namespace blocks */
+} /* namespace gr */
+
+#endif /* INCLUDED_GR_ENDIAN_SWAP_H */
diff --git a/gr-blocks/include/blocks/head.h b/gr-blocks/include/blocks/head.h
new file mode 100644
index 0000000000..cc7d3808e5
--- /dev/null
+++ b/gr-blocks/include/blocks/head.h
@@ -0,0 +1,55 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2009,2012,2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_HEAD_H
+#define INCLUDED_GR_HEAD_H
+
+#include <blocks/api.h>
+#include <gr_sync_block.h>
+#include <stddef.h>			// size_t
+
+namespace gr {
+  namespace blocks {
+
+    /*!
+     * \brief copies the first N items to the output then signals done
+     * \ingroup slicedice_blk
+     *
+     * Useful for building test cases
+     */
+    class BLOCKS_API head : virtual public gr_sync_block
+    {
+    public:
+      // gr::blocks::head::sptr
+      typedef boost::shared_ptr<head> sptr;
+
+      static sptr make(size_t sizeof_stream_item,
+                       uint64_t nitems);
+
+      virtual void reset() = 0;
+      virtual void set_length(int nitems) = 0;
+    };
+
+  } /* namespace blocks */
+} /* namespace gr */
+
+#endif /* INCLUDED_GR_HEAD_H */
diff --git a/gr-blocks/include/blocks/rotator.h b/gr-blocks/include/blocks/rotator.h
new file mode 100644
index 0000000000..96ece63574
--- /dev/null
+++ b/gr-blocks/include/blocks/rotator.h
@@ -0,0 +1,63 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2008,2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _GR_ROTATOR_H_
+#define _GR_ROTATOR_H_
+
+#include <blocks/api.h>
+#include <gr_complex.h>
+
+namespace gr {
+  namespace blocks {
+
+    class BLOCKS_API rotator 
+    {
+    private:
+      gr_complex d_phase;
+      gr_complex d_phase_incr;
+      unsigned int d_counter;
+
+    public:
+      rotator() : d_phase(1), d_phase_incr(1), d_counter(0)
+        { }
+
+      void set_phase(gr_complex phase) { d_phase = phase / abs(phase); }
+      void set_phase_incr(gr_complex incr) { d_phase_incr = incr / abs(incr); }
+
+      gr_complex rotate(gr_complex in)
+      {
+        d_counter++;
+
+        gr_complex z = in * d_phase;    // rotate in by phase
+        d_phase *= d_phase_incr;	    // incr our phase (complex mult == add phases)
+
+        if((d_counter % 512) == 0)
+          d_phase /= abs(d_phase);	    // Normalize to ensure multiplication is rotation
+
+        return z;
+      }
+    };
+
+  } /* namespace blocks */
+} /* namespace gr */
+
+#endif /* _GR_ROTATOR_H_ */
diff --git a/gr-blocks/include/blocks/skiphead.h b/gr-blocks/include/blocks/skiphead.h
new file mode 100644
index 0000000000..e6745af8ea
--- /dev/null
+++ b/gr-blocks/include/blocks/skiphead.h
@@ -0,0 +1,53 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_SKIPHEAD_H
+#define INCLUDED_GR_SKIPHEAD_H
+
+#include <blocks/api.h>
+#include <gr_sync_block.h>
+#include <stddef.h>      // size_t
+
+namespace gr {
+  namespace blocks {
+
+    /*!
+     * \brief skips the first N items, from then on copies items to the output
+     * \ingroup slicedice_blk
+     *
+     * Useful for building test cases and sources which have metadata
+     * or junk at the start
+     */
+    class BLOCKS_API skiphead : virtual public gr_block
+    {
+    public:
+      // gr::blocks::skiphead::sptr
+      typedef boost::shared_ptr<skiphead> sptr;
+
+      static sptr make(size_t itemsize,
+                       uint64_t nitems_to_skip);
+    };
+
+  } /* namespace blocks */
+} /* namespace gr */
+
+#endif /* INCLUDED_GR_SKIPHEAD_H */
diff --git a/gr-blocks/include/blocks/vector_insert_X.h.t b/gr-blocks/include/blocks/vector_insert_X.h.t
new file mode 100644
index 0000000000..aeb4a5248a
--- /dev/null
+++ b/gr-blocks/include/blocks/vector_insert_X.h.t
@@ -0,0 +1,54 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012-2013 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <blocks/api.h>
+#include <gr_block.h>
+
+namespace gr {
+  namespace blocks {
+
+    /*!
+     * \brief source of @TYPE@'s that gets its data from a vector
+     * \ingroup source_blk
+     */
+    class BLOCKS_API @NAME@ : virtual public gr_block 
+    {
+    public:
+      // gr::blocks::@NAME@::sptr
+      typedef boost::shared_ptr<@NAME@> sptr;
+
+      static sptr make(const std::vector<@TYPE@> &data,
+                       int periodicity, int offset=0);
+
+      virtual void rewind() = 0;
+      virtual void set_data(const std::vector<@TYPE@> &data) = 0;
+    };
+
+  } /* namespace blocks */
+} /* namespace gr */
+
+#endif /* @GUARD_NAME@ */
diff --git a/gr-blocks/include/blocks/vector_sink_X.h.t b/gr-blocks/include/blocks/vector_sink_X.h.t
new file mode 100644
index 0000000000..d15c795721
--- /dev/null
+++ b/gr-blocks/include/blocks/vector_sink_X.h.t
@@ -0,0 +1,54 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2008,2009,2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <blocks/api.h>
+#include <gr_sync_block.h>
+
+namespace gr {
+  namespace blocks {
+
+    /*!
+     * \brief @TYPE@ sink that writes to a vector
+     * \ingroup sink_blk
+     */
+    class BLOCKS_API @NAME@ : virtual public gr_sync_block
+    {
+    public:
+      // gr::blocks::@NAME@::sptr
+      typedef boost::shared_ptr<@NAME@> sptr;
+
+      static sptr make(int vlen = 1);
+
+      virtual void reset() = 0;
+      virtual std::vector<@TYPE@> data() const = 0;
+      virtual std::vector<gr_tag_t> tags() const = 0;
+    };
+
+  } /* namespace blocks */
+} /* namespace gr */
+
+#endif /* @GUARD_NAME@ */
diff --git a/gr-blocks/include/blocks/vector_source_X.h.t b/gr-blocks/include/blocks/vector_source_X.h.t
new file mode 100644
index 0000000000..c68b638e62
--- /dev/null
+++ b/gr-blocks/include/blocks/vector_source_X.h.t
@@ -0,0 +1,56 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2008,2012-2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <blocks/api.h>
+#include <gr_sync_block.h>
+
+namespace gr {
+  namespace blocks {
+
+    /*!
+     * \brief source of @TYPE@'s that gets its data from a vector
+     * \ingroup source_blk
+     */
+    class BLOCKS_API @NAME@ : virtual public gr_sync_block
+    {
+    public:
+      // gr::blocks::@NAME@::sptr
+      typedef boost::shared_ptr<@NAME@> sptr;
+
+      static sptr make(const std::vector<@TYPE@> &data,
+                       bool repeat=false, int vlen=1,
+                       const std::vector<gr_tag_t> &tags=std::vector<gr_tag_t>());
+
+      virtual void rewind() = 0;
+      virtual void set_data(const std::vector<@TYPE@> &data,
+                            const std::vector<gr_tag_t> &tags=std::vector<gr_tag_t>()) = 0;
+    };
+
+  } /* namespace blocks */
+} /* namespace gr */
+
+#endif /* @GUARD_NAME@ */
diff --git a/gr-blocks/lib/CMakeLists.txt b/gr-blocks/lib/CMakeLists.txt
index ee4658ae34..b0f3ef15cd 100644
--- a/gr-blocks/lib/CMakeLists.txt
+++ b/gr-blocks/lib/CMakeLists.txt
@@ -114,6 +114,9 @@ expand_cc_h_impl(sub_XX             ss ii ff cc)
 expand_cc_h_impl(xor_XX             bb ss ii)
 expand_cc_h_impl(packed_to_unpacked_XX bb ss ii)
 expand_cc_h_impl(unpacked_to_packed_XX bb ss ii)
+expand_cc_h_impl(vector_insert_X    b s i f c)
+expand_cc_h_impl(vector_sink_X      b s i f c)
+expand_cc_h_impl(vector_source_X    b s i f c)
 
 ########################################################################
 # Setup the include and linker paths
@@ -142,6 +145,9 @@ list(APPEND gr_blocks_sources
     fxpt.cc
     wavfile.cc
     add_ff_impl.cc
+    annotator_1to1_impl.cc
+    annotator_alltoall_impl.cc
+    annotator_raw_impl.cc
     bin_statistics_f_impl.cc
     burst_tagger_impl.cc
     char_to_float_impl.cc
@@ -154,8 +160,10 @@ list(APPEND gr_blocks_sources
     complex_to_mag_squared_impl.cc
     complex_to_arg_impl.cc
     conjugate_cc_impl.cc
+    copy_impl.cc
     deinterleave_impl.cc
     delay_impl.cc
+    endian_swap_impl.cc
     file_descriptor_sink_impl.cc
     file_descriptor_source_impl.cc
     file_sink_impl.cc
@@ -169,6 +177,7 @@ list(APPEND gr_blocks_sources
     float_to_short_impl.cc
     float_array_to_uchar.cc
     float_to_uchar_impl.cc
+    head_impl.cc
     int_to_float_impl.cc
     interleave_impl.cc
     interleaved_short_array_to_complex.cc
@@ -200,6 +209,7 @@ list(APPEND gr_blocks_sources
     rms_ff_impl.cc
     short_to_char_impl.cc
     short_to_float_impl.cc
+    skiphead_impl.cc
     socket_pdu_impl.cc
     stream_mux_impl.cc
     stream_pdu_base.cc
@@ -262,15 +272,19 @@ GR_LIBRARY_FOO(gnuradio-blocks RUNTIME_COMPONENT "blocks_runtime" DEVEL_COMPONEN
 if(ENABLE_TESTING)
   include(GrTest)
 
-  include_directories(${CPPUNIT_INCLUDE_DIRS})
+  include_directories(
+    ${GR_FILTER_INCLUDE_DIRS}
+    ${CPPUNIT_INCLUDE_DIRS})
   link_directories(${CPPUNIT_LIBRARY_DIRS})
 
   list(APPEND test_gr_blocks_sources
     ${CMAKE_CURRENT_SOURCE_DIR}/test_gr_blocks.cc
     ${CMAKE_CURRENT_SOURCE_DIR}/qa_blocks.cc
+    ${CMAKE_CURRENT_SOURCE_DIR}/qa_block_tags.cc
     ${CMAKE_CURRENT_SOURCE_DIR}/qa_fxpt.cc
     ${CMAKE_CURRENT_SOURCE_DIR}/qa_fxpt_nco.cc
     ${CMAKE_CURRENT_SOURCE_DIR}/qa_fxpt_vco.cc
+    ${CMAKE_CURRENT_SOURCE_DIR}/qa_rotator.cc
     )
 
   add_executable(test-gr-blocks ${test_gr_blocks_sources})
@@ -281,6 +295,7 @@ if(ENABLE_TESTING)
     test-gr-blocks
     gnuradio-core
     gnuradio-blocks
+    gnuradio-filter
     ${Boost_LIBRARIES}
     ${CPPUNIT_LIBRARIES}
   )
diff --git a/gr-blocks/lib/annotator_1to1_impl.cc b/gr-blocks/lib/annotator_1to1_impl.cc
new file mode 100644
index 0000000000..d3f4758684
--- /dev/null
+++ b/gr-blocks/lib/annotator_1to1_impl.cc
@@ -0,0 +1,113 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010,2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "annotator_1to1_impl.h"
+#include <gr_io_signature.h>
+#include <string.h>
+#include <iostream>
+#include <iomanip>
+
+namespace gr {
+  namespace blocks {
+
+    annotator_1to1::sptr
+    annotator_1to1::make(int when, size_t sizeof_stream_item)
+    {
+      return gnuradio::get_initial_sptr
+        (new annotator_1to1_impl(when, sizeof_stream_item));
+    }
+
+    annotator_1to1_impl::annotator_1to1_impl(int when, size_t sizeof_stream_item)
+      : gr_sync_block("annotator_1to1",
+                      gr_make_io_signature(1, -1, sizeof_stream_item),
+                      gr_make_io_signature(1, -1, sizeof_stream_item)),
+        d_itemsize(sizeof_stream_item), d_when((uint64_t)when)
+    {
+      set_tag_propagation_policy(TPP_ONE_TO_ONE);
+
+      d_tag_counter = 0;
+      set_relative_rate(1.0);
+    }
+
+    annotator_1to1_impl::~annotator_1to1_impl()
+    {
+    }
+
+    int
+    annotator_1to1_impl::work(int noutput_items,
+                              gr_vector_const_void_star &input_items,
+                              gr_vector_void_star &output_items)
+    {
+      const float *in = (const float*)input_items[0];
+      float *out = (float*)output_items[0];
+
+      std::stringstream str;
+      str << name() << unique_id();
+
+      uint64_t abs_N = 0;
+      int ninputs = input_items.size();
+      for(int i = 0; i < ninputs; i++) {
+        abs_N = nitems_read(i);
+
+        std::vector<gr_tag_t> all_tags;
+        get_tags_in_range(all_tags, i, abs_N, abs_N + noutput_items);
+
+        std::vector<gr_tag_t>::iterator itr;
+        for(itr = all_tags.begin(); itr != all_tags.end(); itr++) {
+          d_stored_tags.push_back(*itr);
+        }
+      }
+
+      // Storing the current noutput_items as the value to the "noutput_items" key
+      pmt::pmt_t srcid = pmt::pmt_string_to_symbol(str.str());
+      pmt::pmt_t key = pmt::pmt_string_to_symbol("seq");
+
+      // Work does nothing to the data stream; just copy all inputs to outputs
+      // Adds a new tag when the number of items read is a multiple of d_when
+      abs_N = nitems_read(0);
+      int noutputs = output_items.size();
+      for(int j = 0; j < noutput_items; j++) {
+        // the min() is a hack to make sure this doesn't segfault if
+        // there are a different number of ins and outs. This is
+        // specifically designed to test the 1-to-1 propagation policy.
+        for(int i = 0; i < std::min(noutputs, ninputs); i++) {
+          if(abs_N % d_when == 0) {
+            pmt::pmt_t value = pmt::pmt_from_uint64(d_tag_counter++);
+            add_item_tag(i, abs_N, key, value, srcid);
+          }
+
+          in  = (const float*)input_items[i];
+          out = (float*)output_items[i];
+          out[j] = in[j];
+        }
+        abs_N++;
+      }
+
+      return noutput_items;
+    }
+
+  } /* namespace blocks */
+} /* namespace gr */
diff --git a/gr-blocks/lib/annotator_1to1_impl.h b/gr-blocks/lib/annotator_1to1_impl.h
new file mode 100644
index 0000000000..3306602e2c
--- /dev/null
+++ b/gr-blocks/lib/annotator_1to1_impl.h
@@ -0,0 +1,56 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010,2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_ANNOTATOR_1TO1_IMPL_H
+#define	INCLUDED_GR_ANNOTATOR_1TO1_IMPL_H
+
+#include <blocks/annotator_1to1.h>
+
+namespace gr {
+  namespace blocks {
+
+    class annotator_1to1_impl : public annotator_1to1
+    {
+    private:
+      size_t d_itemsize;
+      uint64_t d_when;
+      uint64_t d_tag_counter;
+      std::vector<gr_tag_t> d_stored_tags;
+
+    public:
+      annotator_1to1_impl(int when, size_t sizeof_stream_item);
+      ~annotator_1to1_impl();
+
+      std::vector<gr_tag_t> data() const
+      {
+        return d_stored_tags;
+      }
+
+      int work(int noutput_items,
+               gr_vector_const_void_star &input_items,
+               gr_vector_void_star &output_items);
+    };
+
+  } /* namespace blocks */
+} /* namespace gr */
+
+#endif /* INCLUDED_GR_ANNOTATOR_1TO1_IMPL_H */
diff --git a/gr-blocks/lib/annotator_alltoall_impl.cc b/gr-blocks/lib/annotator_alltoall_impl.cc
new file mode 100644
index 0000000000..5af1a9c18e
--- /dev/null
+++ b/gr-blocks/lib/annotator_alltoall_impl.cc
@@ -0,0 +1,117 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010,2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "annotator_alltoall_impl.h"
+#include <gr_io_signature.h>
+#include <string.h>
+#include <iostream>
+#include <iomanip>
+
+namespace gr {
+  namespace blocks {
+
+    annotator_alltoall::sptr
+    annotator_alltoall::make(int when, size_t sizeof_stream_item)
+    {
+      return gnuradio::get_initial_sptr
+        (new annotator_alltoall_impl(when, sizeof_stream_item));
+    }
+
+    annotator_alltoall_impl::annotator_alltoall_impl(int when,
+                                                     size_t sizeof_stream_item)
+      : gr_sync_block("annotator_alltoall",
+                      gr_make_io_signature(1, -1, sizeof_stream_item),
+                      gr_make_io_signature(1, -1, sizeof_stream_item)),
+        d_itemsize(sizeof_stream_item), d_when((uint64_t)when)
+    {
+      set_tag_propagation_policy(TPP_ALL_TO_ALL);
+
+      d_tag_counter = 0;
+    }
+
+    annotator_alltoall_impl::~annotator_alltoall_impl()
+    {
+    }
+
+    int
+    annotator_alltoall_impl::work(int noutput_items,
+                                  gr_vector_const_void_star &input_items,
+                                  gr_vector_void_star &output_items)
+    {
+      const float *in = (const float*)input_items[0];
+      float *out = (float*)output_items[0];
+
+      std::stringstream str;
+      str << name() << unique_id();
+
+      uint64_t abs_N = 0, end_N;
+      int ninputs = input_items.size();
+      for(int i = 0; i < ninputs; i++) {
+        abs_N = nitems_read(i);
+        end_N = abs_N + (uint64_t)(noutput_items);
+
+        std::vector<gr_tag_t> all_tags;
+        get_tags_in_range(all_tags, i, abs_N, end_N);
+
+        std::vector<gr_tag_t>::iterator itr;
+        for(itr = all_tags.begin(); itr != all_tags.end(); itr++) {
+          d_stored_tags.push_back(*itr);
+        }
+      }
+
+      // Source ID and key for any tag that might get applied from this block
+      pmt::pmt_t srcid = pmt::pmt_string_to_symbol(str.str());
+      pmt::pmt_t key = pmt::pmt_string_to_symbol("seq");
+
+      // Work does nothing to the data stream; just copy all inputs to
+      // outputs Adds a new tag when the number of items read is a
+      // multiple of d_when
+      abs_N = nitems_written(0);
+      int noutputs = output_items.size();
+
+      for(int j = 0; j < noutput_items; j++) {
+        for(int i = 0; i < noutputs; i++) {
+          if(abs_N % d_when == 0) {
+            pmt::pmt_t value = pmt::pmt_from_uint64(d_tag_counter++);
+            add_item_tag(i, abs_N, key, value, srcid);
+          }
+
+          // Sum all of the inputs together for each output. Just 'cause.
+          out = (float*)output_items[i];
+          out[j] = 0;
+          for(int ins = 0; ins < ninputs; ins++) {
+            in = (const float*)input_items[ins];
+            out[j] += in[j];
+          }
+        }
+        abs_N++;
+      }
+
+      return noutput_items;
+    }
+
+  } /* namespace blocks */
+} /* namespace gr */
diff --git a/gr-blocks/lib/annotator_alltoall_impl.h b/gr-blocks/lib/annotator_alltoall_impl.h
new file mode 100644
index 0000000000..24c21948bc
--- /dev/null
+++ b/gr-blocks/lib/annotator_alltoall_impl.h
@@ -0,0 +1,56 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010,2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_ANNOTATOR_ALLTOALL_IMPL_H
+#define	INCLUDED_GR_ANNOTATOR_ALLTOALL_IMPL_H
+
+#include <blocks/annotator_alltoall.h>
+
+namespace gr {
+  namespace blocks {
+
+    class annotator_alltoall_impl : public annotator_alltoall
+    {
+    private:
+      size_t d_itemsize;
+      uint64_t d_when;
+      uint64_t d_tag_counter;
+      std::vector<gr_tag_t> d_stored_tags;
+
+    public:
+      annotator_alltoall_impl(int when, size_t sizeof_stream_item);
+      ~annotator_alltoall_impl();
+
+      std::vector<gr_tag_t> data() const
+      {
+        return d_stored_tags;
+      }
+
+      int work(int noutput_items,
+               gr_vector_const_void_star &input_items,
+               gr_vector_void_star &output_items);
+    };
+
+  } /* namespace blocks */
+} /* namespace gr */
+
+#endif /* INCLUDED_GR_ANNOTATOR_ALLTOALL_IMPL_H */
diff --git a/gr-blocks/lib/annotator_raw_impl.cc b/gr-blocks/lib/annotator_raw_impl.cc
new file mode 100644
index 0000000000..1b92523089
--- /dev/null
+++ b/gr-blocks/lib/annotator_raw_impl.cc
@@ -0,0 +1,112 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010,2013 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "annotator_raw_impl.h"
+#include <gr_io_signature.h>
+#include <string.h>
+#include <iostream>
+#include <iomanip>
+#include <stdexcept>
+
+using namespace pmt;
+
+namespace gr {
+  namespace blocks {
+
+    annotator_raw::sptr
+    annotator_raw::make(size_t sizeof_stream_item)
+    {
+      return gnuradio::get_initial_sptr
+        (new annotator_raw_impl(sizeof_stream_item));
+    }
+
+    annotator_raw_impl::annotator_raw_impl(size_t sizeof_stream_item)
+      : gr_sync_block("annotator_raw",
+                      gr_make_io_signature(1, 1, sizeof_stream_item),
+                      gr_make_io_signature(1, 1, sizeof_stream_item)),
+        d_itemsize(sizeof_stream_item)
+    {
+      set_tag_propagation_policy(TPP_ONE_TO_ONE);
+      set_relative_rate(1.0);
+    }
+
+    void annotator_raw_impl::add_tag(uint64_t offset, pmt_t key, pmt_t val)
+    {
+      gruel::scoped_lock l(d_mutex);
+
+      gr_tag_t tag;
+      tag.srcid = pmt::pmt_intern(name());
+      tag.key = key;
+      tag.value = val;
+      tag.offset = offset;
+
+      // add our new tag
+      d_queued_tags.push_back(tag);
+      // make sure our tags are in offset order
+      std::sort(d_queued_tags.begin(), d_queued_tags.end(),
+                gr_tag_t::offset_compare);
+      // make sure we are not adding an item in the past!
+      if(tag.offset > nitems_read(0)) {
+        throw std::runtime_error("annotator_raw::add_tag: item added too far in the past\n.");
+      }
+    }
+
+    annotator_raw_impl::~annotator_raw_impl()
+    {
+    }
+
+    int
+    annotator_raw_impl::work(int noutput_items,
+                             gr_vector_const_void_star &input_items,
+                             gr_vector_void_star &output_items)
+    {
+      gruel::scoped_lock l(d_mutex);
+
+      const char *in = (const char*)input_items[0];
+      char *out = (char*)output_items[0];
+
+      uint64_t start_N = nitems_read(0);
+      uint64_t end_N = start_N + (uint64_t)(noutput_items);
+   
+      // locate queued tags that fall in this range and insert them when appropriate
+      std::vector<gr_tag_t>::iterator i = d_queued_tags.begin();
+      while( i != d_queued_tags.end() ) {
+        if( (*i).offset >= start_N && (*i).offset < end_N) {
+          add_item_tag(0, (*i).offset,(*i).key, (*i).value, (*i).srcid);
+          i = d_queued_tags.erase(i);
+        } 
+        else {
+          break;
+        }
+      }
+
+      // copy data across
+      memcpy(out, in, noutput_items*d_itemsize);
+      return noutput_items;
+    }
+
+  } /* namespace blocks */
+} /* namespace gr */
diff --git a/gr-blocks/lib/annotator_raw_impl.h b/gr-blocks/lib/annotator_raw_impl.h
new file mode 100644
index 0000000000..2e349bfe33
--- /dev/null
+++ b/gr-blocks/lib/annotator_raw_impl.h
@@ -0,0 +1,54 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010,2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_ANNOTATOR_RAW_IMPL_H
+#define	INCLUDED_GR_ANNOTATOR_RAW_IMPL_H
+
+#include <blocks/annotator_raw.h>
+#include <gruel/thread.h>
+
+namespace gr {
+  namespace blocks {
+
+    class annotator_raw_impl : public annotator_raw
+    {
+    private:
+      size_t d_itemsize;
+      std::vector<gr_tag_t> d_queued_tags;
+      gruel::mutex d_mutex;
+
+    public:
+      annotator_raw_impl(size_t sizeof_stream_item);
+      ~annotator_raw_impl();
+
+      // insert a tag to be added
+      void add_tag(uint64_t offset, pmt::pmt_t key, pmt::pmt_t val);
+
+      int work(int noutput_items,
+               gr_vector_const_void_star &input_items,
+               gr_vector_void_star &output_items);
+    };
+
+  } /* namespace blocks */
+} /* namespace gr */
+
+#endif /* INCLUDED_GR_ANNOTATOR_RAW_IMPL_H */
diff --git a/gr-blocks/lib/copy_impl.cc b/gr-blocks/lib/copy_impl.cc
new file mode 100644
index 0000000000..f489b03c0c
--- /dev/null
+++ b/gr-blocks/lib/copy_impl.cc
@@ -0,0 +1,82 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2009,2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "copy_impl.h"
+#include <gr_io_signature.h>
+#include <string.h>
+
+namespace gr {
+  namespace blocks {
+
+    copy::sptr
+    copy::make(size_t itemsize)
+    {
+      return gnuradio::get_initial_sptr
+        (new copy_impl(itemsize));
+    }
+
+    copy_impl::copy_impl(size_t itemsize)
+      : gr_block("copy",
+                 gr_make_io_signature(1, 1, itemsize),
+                 gr_make_io_signature(1, 1, itemsize)),
+        d_itemsize(itemsize),
+        d_enabled(true)
+    {
+    }
+
+    copy_impl::~copy_impl()
+    {
+    }
+
+    bool
+    copy_impl::check_topology(int ninputs, int noutputs)
+    {
+      return ninputs == noutputs;
+    }
+
+    int
+    copy_impl::general_work(int noutput_items,
+                            gr_vector_int &ninput_items,
+                            gr_vector_const_void_star &input_items,
+                            gr_vector_void_star &output_items)
+    {
+      const uint8_t *in = (const uint8_t*)input_items[0];
+      uint8_t *out = (uint8_t*)output_items[0];
+
+      int n = std::min<int>(ninput_items[0], noutput_items);
+      int j = 0;
+
+      if(d_enabled) {
+        memcpy(out, in, n*d_itemsize);
+        j = n;
+      }
+
+      consume_each(n);
+      return j;
+    }
+
+  } /* namespace blocks */
+} /* namespace gr */
diff --git a/gr-blocks/lib/copy_impl.h b/gr-blocks/lib/copy_impl.h
new file mode 100644
index 0000000000..f462ffebdc
--- /dev/null
+++ b/gr-blocks/lib/copy_impl.h
@@ -0,0 +1,55 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2009,2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_COPY_IMPL_H
+#define INCLUDED_GR_COPY_IMPL_H
+
+#include <blocks/copy.h>
+
+namespace gr {
+  namespace blocks {
+
+    class copy_impl : public copy
+    {
+    private:
+      size_t d_itemsize;
+      bool d_enabled;
+
+    public:
+      copy_impl(size_t itemsize);
+      ~copy_impl();
+
+      bool check_topology(int ninputs, int noutputs);
+
+      void set_enabled(bool enable) { d_enabled = enable; }
+      bool enabled() const { return d_enabled;}
+
+      int general_work(int noutput_items,
+                       gr_vector_int &ninput_items,
+                       gr_vector_const_void_star &input_items,
+                       gr_vector_void_star &output_items);
+    };
+
+  } /* namespace blocks */
+} /* namespace gr */
+
+#endif /* INCLUDED_GR_COPY_IMPL_H */
diff --git a/gr-blocks/lib/endian_swap_impl.cc b/gr-blocks/lib/endian_swap_impl.cc
new file mode 100644
index 0000000000..7e67c30147
--- /dev/null
+++ b/gr-blocks/lib/endian_swap_impl.cc
@@ -0,0 +1,110 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010,2012,2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "endian_swap_impl.h"
+#include <gr_io_signature.h>
+#include <volk/volk.h>
+
+namespace gr {
+  namespace blocks {
+
+    endian_swap::sptr
+    endian_swap::make(size_t item_size_bytes)
+    {
+      return gnuradio::get_initial_sptr
+        (new endian_swap_impl(item_size_bytes));
+    }
+
+    endian_swap_impl::endian_swap_impl (size_t item_size_bytes)
+      : gr_sync_block("endian_swap_impl",
+                      gr_make_io_signature(1, 1, item_size_bytes),
+                      gr_make_io_signature(1, 1, item_size_bytes))
+    {
+      const int alignment_multiple = volk_get_alignment();
+      set_alignment(std::max(1, alignment_multiple));
+    }
+
+    endian_swap_impl::~endian_swap_impl()
+    {
+    }
+
+    int
+    endian_swap_impl::work(int noutput_items,
+                           gr_vector_const_void_star &input_items,
+                           gr_vector_void_star &output_items)
+    {
+      const char *in = (const char*)input_items[0];
+      char *out = (char*)output_items[0];
+
+      int nbytes(output_signature()->sizeof_stream_item(0));
+      if(is_unaligned()) {
+        switch(nbytes){
+        case 1:
+          memcpy(out,in,noutput_items);
+          break;
+        case 2:
+          memcpy(out,in,2*noutput_items);
+          volk_16u_byteswap_u((uint16_t*)out,noutput_items);
+          break;
+        case 4:
+          memcpy(out,in,4*noutput_items);
+          volk_32u_byteswap_u((uint32_t*)out,noutput_items);
+          break;
+        case 8:
+          memcpy(out,in,8*noutput_items);
+          volk_64u_byteswap_u((uint64_t*)out,noutput_items);
+          break;
+        default:
+          throw std::runtime_error("itemsize is not valid for endian_swap!");
+        } 
+      }
+      else {
+        switch(nbytes) {
+        case 1:
+          memcpy(out,in,noutput_items);
+          break;
+        case 2:
+          memcpy(out,in,2*noutput_items);
+          volk_16u_byteswap_a((uint16_t*)out,noutput_items);
+          break;
+        case 4:
+          memcpy(out,in,4*noutput_items);
+          volk_32u_byteswap_a((uint32_t*)out,noutput_items);
+          break;
+        case 8:
+          memcpy(out,in,8*noutput_items);
+          volk_64u_byteswap_a((uint64_t*)out,noutput_items);
+          break;
+        default:
+          throw std::runtime_error("itemsize is not valid for endian_swap!");
+        }
+      }
+
+      return noutput_items;
+    }
+
+  } /* namespace blocks */
+} /* namespace gr */
diff --git a/gr-blocks/lib/endian_swap_impl.h b/gr-blocks/lib/endian_swap_impl.h
new file mode 100644
index 0000000000..517df44f17
--- /dev/null
+++ b/gr-blocks/lib/endian_swap_impl.h
@@ -0,0 +1,48 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2012,2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_ENDIAN_SWAP_IMPL_H
+#define INCLUDED_GR_ENDIAN_SWAP_IMPL_H
+
+#include <blocks/endian_swap.h>
+
+namespace gr {
+  namespace blocks {
+
+    class endian_swap_impl : public endian_swap
+    {
+    private:
+      size_t item_size_bytes;
+
+    public:
+      endian_swap_impl(size_t item_size_bytes);
+      ~endian_swap_impl();
+
+      int work(int noutput_items,
+               gr_vector_const_void_star &input_items,
+               gr_vector_void_star &output_items);
+    };
+
+  } /* namespace blocks */
+} /* namespace gr */
+
+#endif /* INCLUDED_GR_ENDIAN_SWAP_IMPL_H */
diff --git a/gr-blocks/lib/head_impl.cc b/gr-blocks/lib/head_impl.cc
new file mode 100644
index 0000000000..7dfa36607c
--- /dev/null
+++ b/gr-blocks/lib/head_impl.cc
@@ -0,0 +1,75 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2009,2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "head_impl.h"
+#include <gr_io_signature.h>
+#include <string.h>
+
+namespace gr {
+  namespace blocks {
+
+    head::sptr
+    head::make(size_t sizeof_stream_item, uint64_t nitems)
+    {
+      return gnuradio::get_initial_sptr
+        (new head_impl(sizeof_stream_item, nitems));
+    }
+
+    head_impl::head_impl(size_t sizeof_stream_item, uint64_t nitems)
+      : gr_sync_block("head",
+                      gr_make_io_signature(1, 1, sizeof_stream_item),
+                      gr_make_io_signature(1, 1, sizeof_stream_item)),
+        d_nitems(nitems), d_ncopied_items(0)
+    {
+    }
+
+    head_impl::~head_impl()
+    {
+    }
+
+    int
+    head_impl::work(int noutput_items,
+                    gr_vector_const_void_star &input_items,
+		    gr_vector_void_star &output_items)
+    {
+      if(d_ncopied_items >= d_nitems)
+        return -1;			// Done!
+
+      unsigned n = std::min(d_nitems - d_ncopied_items,
+                            (uint64_t)noutput_items);
+
+      if(n == 0)
+        return 0;
+
+      memcpy(output_items[0], input_items[0],
+             n * input_signature()->sizeof_stream_item (0));
+      d_ncopied_items += n;
+
+      return n;
+    }
+
+  } /* namespace blocks */
+} /* namespace gr */
diff --git a/gr-blocks/lib/head_impl.h b/gr-blocks/lib/head_impl.h
new file mode 100644
index 0000000000..a56acfbb27
--- /dev/null
+++ b/gr-blocks/lib/head_impl.h
@@ -0,0 +1,52 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2009,2012,2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_HEAD_IMPL_H
+#define INCLUDED_GR_HEAD_IMPL_H
+
+#include <blocks/head.h>
+
+namespace gr {
+  namespace blocks {
+
+    class head_impl : public head
+    {
+    private:
+      uint64_t d_nitems;
+      uint64_t d_ncopied_items;
+
+    public:
+      head_impl(size_t sizeof_stream_item, uint64_t nitems);
+      ~head_impl();
+
+      void reset() { d_ncopied_items = 0; }
+      void set_length(int nitems) { d_nitems = nitems; }
+
+      int work(int noutput_items,
+               gr_vector_const_void_star &input_items,
+               gr_vector_void_star &output_items);
+    };
+
+  } /* namespace blocks */
+} /* namespace gr */
+
+#endif /* INCLUDED_GR_HEAD_IMPL_H */
diff --git a/gr-blocks/lib/qa_block_tags.cc b/gr-blocks/lib/qa_block_tags.cc
new file mode 100644
index 0000000000..93edc4695a
--- /dev/null
+++ b/gr-blocks/lib/qa_block_tags.cc
@@ -0,0 +1,451 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010,2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <qa_block_tags.h>
+#include <gr_block.h>
+#include <gr_top_block.h>
+#include <gr_null_source.h>
+#include <gr_null_sink.h>
+#include <gr_head.h>
+#include <blocks/annotator_alltoall.h>
+#include <blocks/annotator_1to1.h>
+#include <gr_keep_one_in_n.h>
+#include <filter/firdes.h>
+#include <gr_tags.h>
+
+
+// ----------------------------------------------------------------
+
+using namespace pmt;
+
+// set to 1 to turn on debug output
+// The debug output fully checks that the tags seen are what are expected. While
+// this behavior currently works with our implementation, there is no guarentee
+// that the tags will be coming in this specific order, so it's dangerous to
+// rely on this as a test of the tag system working. We would really want to
+// tags we know we should see and then test that they all occur once, but in no
+// particular order.
+#define QA_TAGS_DEBUG 0
+
+void
+qa_block_tags::t0()
+{
+  unsigned int N = 1000;
+  gr_top_block_sptr tb = gr_make_top_block("top");
+  gr_block_sptr src (gr_make_null_source(sizeof(int)));
+  gr_block_sptr head (gr_make_head(sizeof(int), N));
+  gr_block_sptr snk (gr_make_null_sink(sizeof(int)));
+
+  tb->connect(src, 0, head, 0);
+  tb->connect(head, 0, snk, 0);
+
+  //CPPUNIT_ASSERT_THROW(src->nitems_read(0), std::runtime_error);
+  //CPPUNIT_ASSERT_THROW(src->nitems_written(0), std::runtime_error);
+  CPPUNIT_ASSERT_EQUAL(src->nitems_read(0), (uint64_t)0);
+  CPPUNIT_ASSERT_EQUAL(src->nitems_written(0), (uint64_t)0);
+
+  tb->run();
+
+  CPPUNIT_ASSERT_THROW(src->nitems_read(0), std::invalid_argument);
+  CPPUNIT_ASSERT(src->nitems_written(0) >= N);
+  CPPUNIT_ASSERT_EQUAL(snk->nitems_read(0), (uint64_t)1000);
+  CPPUNIT_ASSERT_THROW(snk->nitems_written(0), std::invalid_argument);
+}
+
+
+void
+qa_block_tags::t1()
+{
+  int N = 40000;
+  gr_top_block_sptr tb = gr_make_top_block("top");
+  gr_block_sptr src (gr_make_null_source(sizeof(int)));
+  gr_block_sptr head (gr_make_head(sizeof(int), N));
+  gr::blocks::annotator_alltoall::sptr ann0(gr::blocks::annotator_alltoall::make(10000, sizeof(int)));
+  gr::blocks::annotator_alltoall::sptr ann1(gr::blocks::annotator_alltoall::make(10000, sizeof(int)));
+  gr::blocks::annotator_alltoall::sptr ann2(gr::blocks::annotator_alltoall::make(10000, sizeof(int)));
+  gr::blocks::annotator_alltoall::sptr ann3(gr::blocks::annotator_alltoall::make(10000, sizeof(int)));
+  gr::blocks::annotator_alltoall::sptr ann4(gr::blocks::annotator_alltoall::make(10000, sizeof(int)));
+  gr_block_sptr snk0 (gr_make_null_sink(sizeof(int)));
+  gr_block_sptr snk1 (gr_make_null_sink(sizeof(int)));
+
+  tb->connect(src, 0, head, 0);
+  tb->connect(head, 0, ann0, 0);
+
+  tb->connect(ann0, 0, ann1, 0);
+  tb->connect(ann0, 1, ann2, 0);
+  tb->connect(ann1, 0, ann3, 0);
+  tb->connect(ann2, 0, ann4, 0);
+
+  tb->connect(ann3, 0, snk0, 0);
+  tb->connect(ann4, 0, snk1, 0);
+
+  tb->run();
+
+  std::vector<gr_tag_t> tags0 = ann0->data();
+  std::vector<gr_tag_t> tags3 = ann3->data();
+  std::vector<gr_tag_t> tags4 = ann4->data();
+
+  // The first annotator does not receive any tags from the null sink upstream
+  CPPUNIT_ASSERT_EQUAL(tags0.size(), (size_t)0);
+  CPPUNIT_ASSERT_EQUAL(tags3.size(), (size_t)8);
+  CPPUNIT_ASSERT_EQUAL(tags4.size(), (size_t)8);
+
+#if QA_TAGS_DEBUG
+  // Kludge together the tags that we know should result from the above graph
+  std::stringstream str0, str1, str2;
+  str0 << ann0->name() << ann0->unique_id();
+  str1 << ann1->name() << ann1->unique_id();
+  str2 << ann2->name() << ann2->unique_id();
+
+  pmt_t expected_tags3[8];
+  expected_tags3[0] = mp(pmt_from_uint64(0),     mp(str1.str()), mp("seq"), mp(0));
+  expected_tags3[1] = mp(pmt_from_uint64(0),     mp(str0.str()), mp("seq"), mp(0));
+  expected_tags3[2] = mp(pmt_from_uint64(10000), mp(str1.str()), mp("seq"), mp(1));
+  expected_tags3[3] = mp(pmt_from_uint64(10000), mp(str0.str()), mp("seq"), mp(2));
+  expected_tags3[4] = mp(pmt_from_uint64(20000), mp(str1.str()), mp("seq"), mp(2));
+  expected_tags3[5] = mp(pmt_from_uint64(20000), mp(str0.str()), mp("seq"), mp(4));
+  expected_tags3[6] = mp(pmt_from_uint64(30000), mp(str1.str()), mp("seq"), mp(3));
+  expected_tags3[7] = mp(pmt_from_uint64(30000), mp(str0.str()), mp("seq"), mp(6));
+
+  pmt_t expected_tags4[8];
+  expected_tags4[0] = mp(pmt_from_uint64(0),     mp(str2.str()), mp("seq"), mp(0));
+  expected_tags4[1] = mp(pmt_from_uint64(0),     mp(str0.str()), mp("seq"), mp(1));
+  expected_tags4[2] = mp(pmt_from_uint64(10000), mp(str2.str()), mp("seq"), mp(1));
+  expected_tags4[3] = mp(pmt_from_uint64(10000), mp(str0.str()), mp("seq"), mp(3));
+  expected_tags4[4] = mp(pmt_from_uint64(20000), mp(str2.str()), mp("seq"), mp(2));
+  expected_tags4[5] = mp(pmt_from_uint64(20000), mp(str0.str()), mp("seq"), mp(5));
+  expected_tags4[6] = mp(pmt_from_uint64(30000), mp(str2.str()), mp("seq"), mp(3));
+  expected_tags4[7] = mp(pmt_from_uint64(30000), mp(str0.str()), mp("seq"), mp(7));
+
+  std::cout << std::endl << "qa_block_tags::t1" << std::endl;
+
+  // For annotator 3, we know it gets tags from ann0 and ann1, test this
+  for(size_t i = 0; i < tags3.size(); i++) {
+    std::cout << "tags3[" << i << "] = " << tags3[i] << "\t\t" << expected_tags3[i] << std::endl;
+    CPPUNIT_ASSERT_EQUAL(pmt_write_string(tags3[i]), pmt_write_string(expected_tags3[i]));
+  }
+
+  // For annotator 4, we know it gets tags from ann0 and ann2, test this
+  std::cout << std::endl;
+  for(size_t i = 0; i < tags4.size(); i++) {
+    std::cout << "tags4[" << i << "] = " << tags4[i] << "\t\t" << expected_tags4[i] << std::endl;
+    CPPUNIT_ASSERT_EQUAL(pmt_write_string(tags4[i]), pmt_write_string(expected_tags4[i]));
+  }
+#endif
+}
+
+void
+qa_block_tags::t2 ()
+{
+  int N = 40000;
+  gr_top_block_sptr tb = gr_make_top_block("top");
+  gr_block_sptr src (gr_make_null_source(sizeof(int)));
+  gr_block_sptr head (gr_make_head(sizeof(int), N));
+  gr::blocks::annotator_alltoall::sptr ann0(gr::blocks::annotator_alltoall::make(10000, sizeof(int)));
+  gr::blocks::annotator_alltoall::sptr ann1(gr::blocks::annotator_alltoall::make(10000, sizeof(int)));
+  gr::blocks::annotator_alltoall::sptr ann2(gr::blocks::annotator_alltoall::make(10000, sizeof(int)));
+  gr::blocks::annotator_alltoall::sptr ann3(gr::blocks::annotator_alltoall::make(10000, sizeof(int)));
+  gr::blocks::annotator_alltoall::sptr ann4(gr::blocks::annotator_alltoall::make(10000, sizeof(int)));
+  gr_block_sptr snk0 (gr_make_null_sink(sizeof(int)));
+  gr_block_sptr snk1 (gr_make_null_sink(sizeof(int)));
+  gr_block_sptr snk2 (gr_make_null_sink(sizeof(int)));
+
+  tb->connect(src, 0, head, 0);
+  tb->connect(head, 0, ann0, 0);
+
+  tb->connect(ann0, 0, ann1, 0);
+  tb->connect(ann0, 1, ann1, 1);
+  tb->connect(ann1, 0, ann2, 0);
+  tb->connect(ann1, 1, ann3, 0);
+  tb->connect(ann1, 2, ann4, 0);
+
+  tb->connect(ann2, 0, snk0, 0);
+  tb->connect(ann3, 0, snk1, 0);
+  tb->connect(ann4, 0, snk2, 0);
+
+  tb->run();
+
+  std::vector<gr_tag_t> tags0 = ann0->data();
+  std::vector<gr_tag_t> tags1 = ann1->data();
+  std::vector<gr_tag_t> tags2 = ann2->data();
+  std::vector<gr_tag_t> tags3 = ann4->data();
+  std::vector<gr_tag_t> tags4 = ann4->data();
+
+  // The first annotator does not receive any tags from the null sink upstream
+  CPPUNIT_ASSERT_EQUAL(tags0.size(), (size_t)0);
+  CPPUNIT_ASSERT_EQUAL(tags1.size(), (size_t)8);
+
+  // Make sure the rest all have 12 tags
+  CPPUNIT_ASSERT_EQUAL(tags2.size(), (size_t)12);
+  CPPUNIT_ASSERT_EQUAL(tags3.size(), (size_t)12);
+  CPPUNIT_ASSERT_EQUAL(tags4.size(), (size_t)12);
+
+
+#if QA_TAGS_DEBUG
+  // Kludge together the tags that we know should result from the above graph
+  std::stringstream str0, str1;
+  str0 << ann0->name() << ann0->unique_id();
+  str1 << ann1->name() << ann1->unique_id();
+
+  pmt_t expected_tags2[12];
+  expected_tags2[0] = mp(pmt_from_uint64(0),     mp(str1.str()), mp("seq"), mp(0));
+  expected_tags2[1] = mp(pmt_from_uint64(0),     mp(str0.str()), mp("seq"), mp(0));
+  expected_tags2[2] = mp(pmt_from_uint64(0),     mp(str0.str()), mp("seq"), mp(1));
+  expected_tags2[3] = mp(pmt_from_uint64(10000), mp(str1.str()), mp("seq"), mp(3));
+  expected_tags2[4] = mp(pmt_from_uint64(10000), mp(str0.str()), mp("seq"), mp(2));
+  expected_tags2[5] = mp(pmt_from_uint64(10000), mp(str0.str()), mp("seq"), mp(3));
+  expected_tags2[6] = mp(pmt_from_uint64(20000), mp(str1.str()), mp("seq"), mp(6));
+  expected_tags2[7] = mp(pmt_from_uint64(20000), mp(str0.str()), mp("seq"), mp(4));
+  expected_tags2[8] = mp(pmt_from_uint64(20000), mp(str0.str()), mp("seq"), mp(5));
+  expected_tags2[9] = mp(pmt_from_uint64(30000), mp(str1.str()), mp("seq"), mp(9));
+  expected_tags2[10] = mp(pmt_from_uint64(30000), mp(str0.str()), mp("seq"), mp(6));
+  expected_tags2[11] = mp(pmt_from_uint64(30000), mp(str0.str()), mp("seq"), mp(7));
+
+  pmt_t expected_tags4[12];
+  expected_tags4[0] = mp(pmt_from_uint64(0),     mp(str1.str()), mp("seq"), mp(2));
+  expected_tags4[1] = mp(pmt_from_uint64(0),     mp(str0.str()), mp("seq"), mp(0));
+  expected_tags4[2] = mp(pmt_from_uint64(0),     mp(str0.str()), mp("seq"), mp(1));
+  expected_tags4[3] = mp(pmt_from_uint64(10000), mp(str1.str()), mp("seq"), mp(5));
+  expected_tags4[4] = mp(pmt_from_uint64(10000), mp(str0.str()), mp("seq"), mp(2));
+  expected_tags4[5] = mp(pmt_from_uint64(10000), mp(str0.str()), mp("seq"), mp(3));
+  expected_tags4[6] = mp(pmt_from_uint64(20000), mp(str1.str()), mp("seq"), mp(8));
+  expected_tags4[7] = mp(pmt_from_uint64(20000), mp(str0.str()), mp("seq"), mp(4));
+  expected_tags4[8] = mp(pmt_from_uint64(20000), mp(str0.str()), mp("seq"), mp(5));
+  expected_tags4[9] = mp(pmt_from_uint64(30000), mp(str1.str()), mp("seq"), mp(11));
+  expected_tags4[10] = mp(pmt_from_uint64(30000), mp(str0.str()), mp("seq"), mp(6));
+  expected_tags4[11] = mp(pmt_from_uint64(30000), mp(str0.str()), mp("seq"), mp(7));
+
+  std::cout << std::endl << "qa_block_tags::t2" << std::endl;
+
+  // For annotator[2-4], we know it gets tags from ann0 and ann1
+  // but the tags from the different outputs of ann1 are different for each.
+  // Just testing ann2 and ann4; if they are correct it would be
+  // inconceivable for ann3 to have it wrong.
+  for(size_t i = 0; i < tags2.size(); i++) {
+    std::cout << "tags2[" << i << "] = " << tags2[i] << "\t\t" << expected_tags2[i] << std::endl;
+    CPPUNIT_ASSERT_EQUAL(pmt_write_string(tags2[i]), pmt_write_string(expected_tags2[i]));
+  }
+
+  std::cout << std::endl;
+  for(size_t i = 0; i < tags4.size(); i++) {
+    std::cout << "tags2[" << i << "] = " << tags4[i] << "\t\t" << expected_tags4[i] << std::endl;
+    CPPUNIT_ASSERT_EQUAL(pmt_write_string(tags4[i]), pmt_write_string(expected_tags4[i]));
+  }
+#endif
+}
+
+
+void
+qa_block_tags::t3()
+{
+  int N = 40000;
+  gr_top_block_sptr tb = gr_make_top_block("top");
+  gr_block_sptr src (gr_make_null_source(sizeof(int)));
+  gr_block_sptr head (gr_make_head(sizeof(int), N));
+  gr::blocks::annotator_1to1::sptr ann0 (gr::blocks::annotator_1to1::make(10000, sizeof(int)));
+  gr::blocks::annotator_alltoall::sptr ann1 (gr::blocks::annotator_alltoall::make(10000, sizeof(int)));
+  gr::blocks::annotator_alltoall::sptr ann2 (gr::blocks::annotator_alltoall::make(10000, sizeof(int)));
+  gr::blocks::annotator_1to1::sptr ann3 (gr::blocks::annotator_1to1::make(10000, sizeof(int)));
+  gr::blocks::annotator_1to1::sptr ann4 (gr::blocks::annotator_1to1::make(10000, sizeof(int)));
+  gr_block_sptr snk0 (gr_make_null_sink(sizeof(int)));
+  gr_block_sptr snk1 (gr_make_null_sink(sizeof(int)));
+
+  tb->connect(src, 0, head, 0);
+  tb->connect(head, 0, ann0, 0);
+  tb->connect(head, 0, ann0, 1);
+
+  tb->connect(ann0, 0, ann1, 0);
+  tb->connect(ann0, 1, ann2, 0);
+  tb->connect(ann1, 0, ann3, 0);
+  tb->connect(ann2, 0, ann4, 0);
+
+  tb->connect(ann3, 0, snk0, 0);
+  tb->connect(ann4, 0, snk1, 0);
+
+  tb->run();
+
+
+  std::vector<gr_tag_t> tags0 = ann0->data();
+  std::vector<gr_tag_t> tags3 = ann3->data();
+  std::vector<gr_tag_t> tags4 = ann4->data();
+
+  // The first annotator does not receive any tags from the null sink upstream
+  CPPUNIT_ASSERT_EQUAL(tags0.size(), (size_t)0);
+  CPPUNIT_ASSERT_EQUAL(tags3.size(), (size_t)8);
+  CPPUNIT_ASSERT_EQUAL(tags4.size(), (size_t)8);
+
+#if QA_TAGS_DEBUG
+  // Kludge together the tags that we know should result from the above graph
+  std::stringstream str0, str1, str2;
+  str0 << ann0->name() << ann0->unique_id();
+  str1 << ann1->name() << ann1->unique_id();
+  str2 << ann2->name() << ann2->unique_id();
+
+  pmt_t expected_tags3[8];
+  expected_tags3[0] = mp(pmt_from_uint64(0),     mp(str1.str()), mp("seq"), mp(0));
+  expected_tags3[1] = mp(pmt_from_uint64(0),     mp(str0.str()), mp("seq"), mp(0));
+  expected_tags3[2] = mp(pmt_from_uint64(10000), mp(str1.str()), mp("seq"), mp(1));
+  expected_tags3[3] = mp(pmt_from_uint64(10000), mp(str0.str()), mp("seq"), mp(2));
+  expected_tags3[4] = mp(pmt_from_uint64(20000), mp(str1.str()), mp("seq"), mp(2));
+  expected_tags3[5] = mp(pmt_from_uint64(20000), mp(str0.str()), mp("seq"), mp(4));
+  expected_tags3[6] = mp(pmt_from_uint64(30000), mp(str1.str()), mp("seq"), mp(3));
+  expected_tags3[7] = mp(pmt_from_uint64(30000), mp(str0.str()), mp("seq"), mp(6));
+
+  pmt_t expected_tags4[8];
+  expected_tags4[0] = mp(pmt_from_uint64(0),     mp(str2.str()), mp("seq"), mp(0));
+  expected_tags4[1] = mp(pmt_from_uint64(0),     mp(str0.str()), mp("seq"), mp(1));
+  expected_tags4[2] = mp(pmt_from_uint64(10000), mp(str2.str()), mp("seq"), mp(1));
+  expected_tags4[3] = mp(pmt_from_uint64(10000), mp(str0.str()), mp("seq"), mp(3));
+  expected_tags4[4] = mp(pmt_from_uint64(20000), mp(str2.str()), mp("seq"), mp(2));
+  expected_tags4[5] = mp(pmt_from_uint64(20000), mp(str0.str()), mp("seq"), mp(5));
+  expected_tags4[6] = mp(pmt_from_uint64(30000), mp(str2.str()), mp("seq"), mp(3));
+  expected_tags4[7] = mp(pmt_from_uint64(30000), mp(str0.str()), mp("seq"), mp(7));
+
+  std::cout << std::endl << "qa_block_tags::t3" << std::endl;
+
+  // For annotator 3, we know it gets tags from ann0 and ann1, test this
+  for(size_t i = 0; i < tags3.size(); i++) {
+    std::cout << "tags3[" << i << "] = " << tags3[i] << "\t\t" << expected_tags3[i] << std::endl;
+    CPPUNIT_ASSERT_EQUAL(pmt_write_string(tags3[i]), pmt_write_string(expected_tags3[i]));
+  }
+
+  // For annotator 4, we know it gets tags from ann0 and ann2, test this
+  std::cout << std::endl;
+  for(size_t i = 0; i < tags4.size(); i++) {
+    std::cout << "tags4[" << i << "] = " << tags4[i] << "\t\t" << expected_tags4[i] << std::endl;
+    CPPUNIT_ASSERT_EQUAL(pmt_write_string(tags4[i]), pmt_write_string(expected_tags4[i]));
+  }
+#endif
+}
+
+
+void
+qa_block_tags::t4()
+{
+  int N = 40000;
+  gr_top_block_sptr tb = gr_make_top_block("top");
+  gr_block_sptr src (gr_make_null_source(sizeof(int)));
+  gr_block_sptr head (gr_make_head(sizeof(int), N));
+  gr::blocks::annotator_1to1::sptr ann0(gr::blocks::annotator_1to1::make(10000, sizeof(int)));
+  gr::blocks::annotator_1to1::sptr ann1(gr::blocks::annotator_1to1::make(10000, sizeof(int)));
+  gr::blocks::annotator_1to1::sptr ann2(gr::blocks::annotator_1to1::make(10000, sizeof(int)));
+  gr_block_sptr snk0 (gr_make_null_sink(sizeof(int)));
+  gr_block_sptr snk1 (gr_make_null_sink(sizeof(int)));
+
+  // using 1-to-1 tag propagation without having equal number of
+  // ins and outs. Make sure this works; will just exit run early.
+  tb->connect(src, 0, head, 0);
+  tb->connect(head, 0, ann0, 0);
+  tb->connect(ann0, 0, ann1, 0);
+  tb->connect(ann0, 1, ann2, 0);
+  tb->connect(ann1, 0, snk0, 0);
+  tb->connect(ann2, 0, snk1, 0);
+
+  std::cerr << std::endl
+	    << "NOTE: This is supposed to produce an error from gr_block_executor"
+	    << std::endl;
+  tb->run();
+}
+
+
+void
+qa_block_tags::t5()
+{
+  int N = 40000;
+  gr_top_block_sptr tb = gr_make_top_block("top");
+  gr_block_sptr src (gr_make_null_source(sizeof(float)));
+  gr_block_sptr head (gr_make_head(sizeof(float), N));
+  gr::blocks::annotator_alltoall::sptr ann0(gr::blocks::annotator_alltoall::make(10000, sizeof(float)));
+  gr::blocks::annotator_alltoall::sptr ann1(gr::blocks::annotator_alltoall::make(10000, sizeof(float)));
+  gr::blocks::annotator_alltoall::sptr ann2(gr::blocks::annotator_alltoall::make(1000,  sizeof(float)));
+  gr_block_sptr snk0 (gr_make_null_sink(sizeof(float)));
+
+  // Rate change blocks
+  gr_keep_one_in_n_sptr dec10 (gr_make_keep_one_in_n(sizeof(float), 10));
+
+  tb->connect(src,  0, head, 0);
+  tb->connect(head, 0, ann0, 0);
+  tb->connect(ann0, 0, ann1, 0);
+  tb->connect(ann1, 0, dec10, 0);
+  tb->connect(dec10, 0, ann2, 0);
+  tb->connect(ann2, 0, snk0, 0);
+
+  tb->run();
+
+  std::vector<gr_tag_t> tags0 = ann0->data();
+  std::vector<gr_tag_t> tags1 = ann1->data();
+  std::vector<gr_tag_t> tags2 = ann2->data();
+
+  // The first annotator does not receive any tags from the null sink upstream
+  CPPUNIT_ASSERT_EQUAL(tags0.size(), (size_t)0);
+  CPPUNIT_ASSERT_EQUAL(tags1.size(), (size_t)4);
+  CPPUNIT_ASSERT_EQUAL(tags2.size(), (size_t)8);
+
+
+#if QA_TAGS_DEBUG
+  // Kludge together the tags that we know should result from the above graph
+  std::stringstream str0, str1, str2;
+  str0 << ann0->name() << ann0->unique_id();
+  str1 << ann1->name() << ann1->unique_id();
+  str2 << ann2->name() << ann2->unique_id();
+
+  pmt_t expected_tags1[5];
+  expected_tags1[0] = mp(pmt_from_uint64(0),     mp(str0.str()), mp("seq"), mp(0));
+  expected_tags1[1] = mp(pmt_from_uint64(10000), mp(str0.str()), mp("seq"), mp(1));
+  expected_tags1[2] = mp(pmt_from_uint64(20000), mp(str0.str()), mp("seq"), mp(2));
+  expected_tags1[3] = mp(pmt_from_uint64(30000), mp(str0.str()), mp("seq"), mp(3));
+
+  pmt_t expected_tags2[10];
+  expected_tags2[0] = mp(pmt_from_uint64(0),    mp(str1.str()), mp("seq"), mp(0));
+  expected_tags2[1] = mp(pmt_from_uint64(0),    mp(str0.str()), mp("seq"), mp(0));
+  expected_tags2[2] = mp(pmt_from_uint64(1000), mp(str1.str()), mp("seq"), mp(1));
+  expected_tags2[3] = mp(pmt_from_uint64(1000), mp(str0.str()), mp("seq"), mp(1));
+  expected_tags2[4] = mp(pmt_from_uint64(2000), mp(str1.str()), mp("seq"), mp(2));
+  expected_tags2[5] = mp(pmt_from_uint64(2000), mp(str0.str()), mp("seq"), mp(2));
+  expected_tags2[6] = mp(pmt_from_uint64(3000), mp(str1.str()), mp("seq"), mp(3));
+  expected_tags2[7] = mp(pmt_from_uint64(3000), mp(str0.str()), mp("seq"), mp(3));
+  expected_tags2[8] = mp(pmt_from_uint64(4000), mp(str1.str()), mp("seq"), mp(4));
+  expected_tags2[9] = mp(pmt_from_uint64(4000), mp(str0.str()), mp("seq"), mp(4));
+
+  std::cout << std::endl << "qa_block_tags::t5" << std::endl;
+
+  // annotator 1 gets tags from annotator 0
+  std::cout << "tags1.size(): " << tags1.size() << std::endl;
+  for(size_t i = 0; i < tags1.size(); i++) {
+    std::cout << "tags1[" << i << "] = " << tags1[i] << "\t\t" << expected_tags1[i] << std::endl;
+    CPPUNIT_ASSERT_EQUAL(pmt_write_string(tags1[i]), pmt_write_string(expected_tags1[i]));
+  }
+
+  // annotator 2 gets tags from annotators 0 and 1
+  std::cout << std::endl;
+  std::cout << "tags2.size(): " << tags2.size() << std::endl;
+  for(size_t i = 0; i < tags2.size(); i++) {
+    std::cout << "tags2[" << i << "] = " << tags2[i] << "\t\t" << expected_tags2[i] << std::endl;
+    CPPUNIT_ASSERT_EQUAL(pmt_write_string(tags2[i]), pmt_write_string(expected_tags2[i]));
+  }
+#endif
+}
+
diff --git a/gr-blocks/lib/qa_block_tags.h b/gr-blocks/lib/qa_block_tags.h
new file mode 100644
index 0000000000..83bebe23f6
--- /dev/null
+++ b/gr-blocks/lib/qa_block_tags.h
@@ -0,0 +1,50 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010,2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_QA_BLOCK_TAGS_H
+#define INCLUDED_QA_BLOCK_TAGS_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+#include <stdexcept>
+
+class qa_block_tags : public CppUnit::TestCase
+{
+  CPPUNIT_TEST_SUITE(qa_block_tags);
+  CPPUNIT_TEST(t0);
+  CPPUNIT_TEST(t1);
+  CPPUNIT_TEST(t2);
+  CPPUNIT_TEST(t3);
+  CPPUNIT_TEST(t4);
+  CPPUNIT_TEST(t5);
+  CPPUNIT_TEST_SUITE_END();
+
+ private:
+  void t0();
+  void t1();
+  void t2();
+  void t3();
+  void t4();
+  void t5();
+};
+
+#endif /* INCLUDED_QA_BLOCK_TAGS_H */
diff --git a/gr-blocks/lib/qa_blocks.cc b/gr-blocks/lib/qa_blocks.cc
index fbae11d264..ebf5d3c349 100644
--- a/gr-blocks/lib/qa_blocks.cc
+++ b/gr-blocks/lib/qa_blocks.cc
@@ -26,18 +26,22 @@
  */
 
 #include <qa_blocks.h>
+#include <qa_block_tags.h>
 #include <qa_fxpt.h>
 #include <qa_fxpt_nco.h>
 #include <qa_fxpt_vco.h>
+#include <qa_rotator.h>
 
 CppUnit::TestSuite *
 qa_gr_blocks::suite()
 {
   CppUnit::TestSuite *s = new CppUnit::TestSuite("gr-blocks");
 
+  s->addTest(qa_block_tags::suite());
   s->addTest(qa_fxpt::suite());
   s->addTest(qa_fxpt_nco::suite());
   s->addTest(qa_fxpt_vco::suite());
+  s->addTest(qa_rotator::suite());
 
   return s;
 }
diff --git a/gr-blocks/lib/qa_rotator.cc b/gr-blocks/lib/qa_rotator.cc
new file mode 100644
index 0000000000..86bbdd5282
--- /dev/null
+++ b/gr-blocks/lib/qa_rotator.cc
@@ -0,0 +1,75 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gruel/attributes.h>
+#include <cppunit/TestAssert.h>
+#include <qa_rotator.h>
+#include <blocks/rotator.h>
+#include <stdio.h>
+#include <cmath>
+#include <gr_expj.h>
+
+// error vector magnitude
+__GR_ATTR_UNUSED static float
+error_vector_mag(gr_complex a, gr_complex b)
+{
+  return abs(a-b);
+}
+
+void
+qa_rotator::t1()
+{
+  static const unsigned	int N = 100000;
+
+  gr::blocks::rotator r;
+
+  double phase_incr = 2*M_PI / 1003;
+  double phase = 0;
+
+  // Old code: We increment then return the rotated value, thus we
+  // need to start one tick back r.set_phase(gr_complex(1,0) *
+  // conj(gr_expj(phase_incr)));
+
+  r.set_phase(gr_complex(1,0));
+  r.set_phase_incr(gr_expj(phase_incr));
+
+  for(unsigned i = 0; i < N; i++) {
+    gr_complex expected = gr_expj(phase);
+    gr_complex actual = r.rotate(gr_complex(1, 0));
+
+#if 0
+    float evm = error_vector_mag(expected, actual);
+    printf("[%6d] expected: (%8.6f, %8.6f)  actual: (%8.6f, %8.6f)  evm: %8.6f\n",
+	   i, expected.real(), expected.imag(), actual.real(), actual.imag(), evm);
+#endif
+
+    CPPUNIT_ASSERT_COMPLEXES_EQUAL(expected, actual, 0.0001);
+
+    phase += phase_incr;
+    if(phase >= 2*M_PI)
+      phase -= 2*M_PI;
+  }
+}
diff --git a/gr-blocks/lib/qa_rotator.h b/gr-blocks/lib/qa_rotator.h
new file mode 100644
index 0000000000..575ea506c7
--- /dev/null
+++ b/gr-blocks/lib/qa_rotator.h
@@ -0,0 +1,39 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _QA_GR_ROTATOR_H_
+#define _QA_GR_ROTATOR_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_rotator : public CppUnit::TestCase 
+{
+  CPPUNIT_TEST_SUITE(qa_rotator);
+  CPPUNIT_TEST(t1);
+  CPPUNIT_TEST_SUITE_END();
+
+ private:
+  void t1();
+};
+
+#endif /* _QA_GR_ROTATOR_H_ */
diff --git a/gr-blocks/lib/skiphead_impl.cc b/gr-blocks/lib/skiphead_impl.cc
new file mode 100644
index 0000000000..feb39eb8f4
--- /dev/null
+++ b/gr-blocks/lib/skiphead_impl.cc
@@ -0,0 +1,93 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2007,2010,2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "skiphead_impl.h"
+#include <gr_io_signature.h>
+#include <string.h>
+
+namespace gr {
+  namespace blocks {
+
+    skiphead::sptr
+    skiphead::make(size_t itemsize, uint64_t nitems_to_skip)
+    {
+      return gnuradio::get_initial_sptr
+        (new skiphead_impl(itemsize, nitems_to_skip));
+    }
+
+    skiphead_impl::skiphead_impl(size_t itemsize, uint64_t nitems_to_skip)
+      : gr_block("skiphead",
+                 gr_make_io_signature(1, 1, itemsize),
+                 gr_make_io_signature(1, 1, itemsize)),
+        d_nitems_to_skip(nitems_to_skip), d_nitems(0)
+    {
+    }
+
+    skiphead_impl::~skiphead_impl()
+    {
+    }
+
+    int
+    skiphead_impl::general_work(int noutput_items,
+                                gr_vector_int &ninput_items_,
+                                gr_vector_const_void_star &input_items,
+                                gr_vector_void_star &output_items)
+    {
+      const char *in = (const char*)input_items[0];
+      char *out = (char*)output_items[0];
+
+      int ninput_items = std::min(ninput_items_[0], noutput_items);
+      int ii = 0;			// input index
+
+      while (ii < ninput_items) {
+        uint64_t ni_total = ii + d_nitems;  	// total items processed so far
+        if(ni_total < d_nitems_to_skip) {	// need to skip some more
+
+          int n_to_skip = (int)std::min(d_nitems_to_skip - ni_total,
+                                        (uint64_t)(ninput_items - ii));
+          ii += n_to_skip;
+        }
+
+        else {		// nothing left to skip.  copy away
+          int n_to_copy = ninput_items - ii;
+          if(n_to_copy > 0) {
+            size_t itemsize = output_signature()->sizeof_stream_item(0);
+            memcpy(out, in + (ii*itemsize), n_to_copy*itemsize);
+          }
+
+          d_nitems += ninput_items;
+          consume_each(ninput_items);
+          return n_to_copy;
+        }
+      }
+
+      d_nitems += ninput_items;
+      consume_each(ninput_items);
+      return 0;
+    }
+
+  } /* namespace blocks */
+} /* namespace gr */
diff --git a/gr-blocks/lib/skiphead_impl.h b/gr-blocks/lib/skiphead_impl.h
new file mode 100644
index 0000000000..d8e0870cb1
--- /dev/null
+++ b/gr-blocks/lib/skiphead_impl.h
@@ -0,0 +1,50 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_SKIPHEAD_IMPL_H
+#define INCLUDED_GR_SKIPHEAD_IMPL_H
+
+#include <blocks/skiphead.h>
+
+namespace gr {
+  namespace blocks {
+
+    class skiphead_impl : public skiphead
+    {
+    private:
+      uint64_t d_nitems_to_skip;
+      uint64_t d_nitems;           // total items seen
+
+    public:
+      skiphead_impl(size_t itemsize, uint64_t nitems_to_skip);
+      ~skiphead_impl();
+
+      int general_work(int noutput_items,
+                       gr_vector_int &ninput_items,
+                       gr_vector_const_void_star &input_items,
+                       gr_vector_void_star &output_items);
+    };
+
+  } /* namespace blocks */
+} /* namespace gr */
+
+#endif /* INCLUDED_GR_SKIPHEAD_IMPL_H */
diff --git a/gr-blocks/lib/vector_insert_X_impl.cc.t b/gr-blocks/lib/vector_insert_X_impl.cc.t
new file mode 100644
index 0000000000..adf31fe05a
--- /dev/null
+++ b/gr-blocks/lib/vector_insert_X_impl.cc.t
@@ -0,0 +1,109 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <@NAME_IMPL@.h>
+#include <algorithm>
+#include <gr_io_signature.h>
+#include <stdexcept>
+#include <stdio.h>
+
+namespace gr {
+  namespace blocks {
+
+    @NAME@::sptr
+    @NAME@::make(const std::vector<@TYPE@> &data, int periodicity, int offset)
+    {
+      return gnuradio::get_initial_sptr
+        (new @NAME_IMPL@(data, periodicity, offset));
+    }
+
+    @NAME_IMPL@::@NAME_IMPL@(const std::vector<@TYPE@> &data,
+                             int periodicity, int offset)
+    : gr_block("@BASE_NAME@",
+               gr_make_io_signature(1, 1, sizeof(@TYPE@)),
+               gr_make_io_signature(1, 1, sizeof(@TYPE@))),
+      d_data(data),
+      d_offset(offset),
+      d_periodicity(periodicity)
+    {
+      //printf("INITIAL: periodicity = %d, offset = %d\n", periodicity, offset);
+      // some sanity checks
+      assert(offset < periodicity);
+      assert(offset >= 0);
+      assert((size_t)periodicity > data.size());
+    }
+
+    @NAME_IMPL@::~@NAME_IMPL@()
+    {}
+
+    int
+    @NAME_IMPL@::general_work(int noutput_items,
+                              gr_vector_int &ninput_items,
+                              gr_vector_const_void_star &input_items,
+                              gr_vector_void_star &output_items)
+    {
+      @TYPE@ *out = (@TYPE@ *)output_items[0];
+      const @TYPE@ *in = (const @TYPE@ *)input_items[0];
+
+      int ii(0), oo(0);
+
+      while((oo < noutput_items) && (ii < ninput_items[0])) {
+        //printf("oo = %d, ii = %d, d_offset = %d, noutput_items = %d, ninput_items[0] = %d", oo, ii, d_offset, noutput_items, ninput_items[0]);
+        //printf(", d_periodicity = %d\n", d_periodicity);
+    
+        if(d_offset >= ((int)d_data.size())) { // if we are in the copy region
+          int max_copy = std::min(std::min(noutput_items - oo, ninput_items[0] - ii),
+                                  d_periodicity - d_offset);
+          //printf("copy %d from input\n", max_copy);
+          memcpy( &out[oo], &in[ii], sizeof(@TYPE@)*max_copy );
+          //printf(" * memcpy returned.\n");
+          ii += max_copy;
+          oo += max_copy;
+          d_offset = (d_offset + max_copy)%d_periodicity;
+        } 
+        else { // if we are in the insertion region
+          int max_copy = std::min(noutput_items - oo, ((int)d_data.size()) - d_offset);
+          //printf("copy %d from d_data[%d] to out[%d]\n", max_copy, d_offset, oo);
+          memcpy(&out[oo], &d_data[d_offset], sizeof(@TYPE@)*max_copy);
+          //printf(" * memcpy returned.\n");
+          oo += max_copy; 
+          d_offset = (d_offset + max_copy)%d_periodicity;
+          //printf(" ## (inelse) oo = %d, d_offset = %d\n", oo, d_offset);
+        }
+    
+        //printf(" # exit else, on to next loop.\n");
+      }
+      //printf(" # got out of loop\n");
+
+      //printf("consume = %d, produce = %d\n", ii, oo);
+      consume_each(ii);
+      return oo;
+    }
+
+  } /* namespace blocks */
+} /* namespace gr */
diff --git a/gr-blocks/lib/vector_insert_X_impl.h.t b/gr-blocks/lib/vector_insert_X_impl.h.t
new file mode 100644
index 0000000000..f447ef1e80
--- /dev/null
+++ b/gr-blocks/lib/vector_insert_X_impl.h.t
@@ -0,0 +1,58 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012,2013 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME_IMPL@
+#define @GUARD_NAME_IMPL@
+
+#include <blocks/@NAME@.h>
+
+namespace gr {
+  namespace blocks {
+
+    class @NAME_IMPL@ : public @NAME@
+    {
+    private:
+      std::vector<@TYPE@> d_data;
+      int d_offset;
+      int d_periodicity;
+
+    public:
+      @NAME_IMPL@(const std::vector<@TYPE@> &data,
+                  int periodicity, int offset);
+      ~@NAME_IMPL@();
+
+      void rewind() { d_offset=0; }
+      void set_data(const std::vector<@TYPE@> &data) {
+        d_data = data; rewind(); }
+
+      int general_work(int noutput_items,
+                       gr_vector_int &ninput_items,
+                       gr_vector_const_void_star &input_items,
+                       gr_vector_void_star &output_items);
+    };
+
+  } /* namespace blocks */
+} /* namespace gr */
+
+#endif /* @GUARD_NAME_IMPL@ */
diff --git a/gr-blocks/lib/vector_sink_X_impl.cc.t b/gr-blocks/lib/vector_sink_X_impl.cc.t
new file mode 100644
index 0000000000..3be2861025
--- /dev/null
+++ b/gr-blocks/lib/vector_sink_X_impl.cc.t
@@ -0,0 +1,83 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2008,2010,2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <@NAME_IMPL@.h>
+#include <gr_io_signature.h>
+#include <algorithm>
+#include <iostream>
+
+namespace gr {
+  namespace blocks {
+
+    @NAME@::sptr
+    @BASE_NAME@::make(int vlen)
+    {
+      return gnuradio::get_initial_sptr
+        (new @NAME_IMPL@(vlen));
+    }
+  
+    @NAME_IMPL@::@NAME_IMPL@(int vlen)
+    : gr_sync_block("@NAME@",
+                    gr_make_io_signature(1, 1, sizeof(@TYPE@) * vlen),
+                    gr_make_io_signature(0, 0, 0)),
+    d_vlen(vlen)
+    {
+    }
+
+    @NAME_IMPL@::~@NAME_IMPL@()
+    {}
+
+    std::vector<@TYPE@>
+    @NAME_IMPL@::data() const
+    {
+      return d_data;
+    }
+
+    std::vector<gr_tag_t>
+    @NAME_IMPL@::tags() const
+    {
+      return d_tags;
+    }
+
+    int
+    @NAME_IMPL@::work(int noutput_items,
+                      gr_vector_const_void_star &input_items,
+                      gr_vector_void_star &output_items)
+    {
+      @TYPE@ *iptr = (@TYPE@*)input_items[0];
+
+      for(int i = 0; i < noutput_items * d_vlen; i++)
+        d_data.push_back (iptr[i]);
+      std::vector<gr_tag_t> tags;
+      get_tags_in_range(tags, 0, nitems_read(0), nitems_read(0) + noutput_items);
+      d_tags.insert(d_tags.end(), tags.begin(), tags.end());
+      return noutput_items;
+    }
+
+  } /* namespace blocks */
+} /* namespace gr */
diff --git a/gr-blocks/lib/vector_sink_X_impl.h.t b/gr-blocks/lib/vector_sink_X_impl.h.t
new file mode 100644
index 0000000000..60d21e0c8c
--- /dev/null
+++ b/gr-blocks/lib/vector_sink_X_impl.h.t
@@ -0,0 +1,56 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2008,2009,2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME_IMPL@
+#define @GUARD_NAME_IMPL@
+
+#include <blocks/@NAME@.h>
+
+namespace gr {
+  namespace blocks {
+
+    class @NAME_IMPL@ : public @NAME@
+    {
+    private:
+      std::vector<@TYPE@> d_data;
+      std::vector<gr_tag_t> d_tags;
+      int d_vlen;
+
+    public:
+      @NAME_IMPL@(int vlen);
+      ~@NAME_IMPL@();
+
+      void reset() { d_data.clear(); }
+      std::vector<@TYPE@> data() const;
+      std::vector<gr_tag_t> tags() const;
+
+      int work(int noutput_items,
+               gr_vector_const_void_star &input_items,
+               gr_vector_void_star &output_items);
+    };
+
+  } /* namespace blocks */
+} /* namespace gr */
+
+#endif /* @GUARD_NAME_IMPL@ */
diff --git a/gr-blocks/lib/vector_source_X_impl.cc.t b/gr-blocks/lib/vector_source_X_impl.cc.t
new file mode 100644
index 0000000000..9c1c63a213
--- /dev/null
+++ b/gr-blocks/lib/vector_source_X_impl.cc.t
@@ -0,0 +1,144 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2008,2010,2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <@NAME_IMPL@.h>
+#include <algorithm>
+#include <gr_io_signature.h>
+#include <stdexcept>
+
+namespace gr {
+  namespace blocks {
+
+    @NAME@::sptr
+    @NAME@::make(const std::vector<@TYPE@> &data,
+                 bool repeat, int vlen,
+                 const std::vector<gr_tag_t> &tags)
+    {
+      return gnuradio::get_initial_sptr
+        (new @NAME_IMPL@(data, repeat, vlen, tags));
+    }
+
+    @NAME_IMPL@::@NAME_IMPL@(const std::vector<@TYPE@> &data,
+                             bool repeat, int vlen,
+                             const std::vector<gr_tag_t> &tags)
+    : gr_sync_block("@BASE_NAME@",
+                    gr_make_io_signature(0, 0, 0),
+                    gr_make_io_signature(1, 1, sizeof(@TYPE@) * vlen)),
+      d_data(data),
+      d_repeat(repeat),
+      d_offset(0),
+      d_vlen(vlen),
+      d_tags(tags),
+      d_tagpos(0)
+    {
+      if(tags.size() == 0) {
+        d_settags = 0;
+      }
+      else {
+        d_settags = 1;
+        set_output_multiple(data.size() / vlen);
+      }
+      if((data.size() % vlen) != 0)
+        throw std::invalid_argument("data length must be a multiple of vlen");
+    }
+
+    @NAME_IMPL@::~@NAME_IMPL@()
+    {}
+
+    void
+    @NAME_IMPL@::set_data (const std::vector<@TYPE@> &data,
+                           const std::vector<gr_tag_t> &tags)
+    {
+      d_data = data;
+      d_tags = tags;
+      rewind();
+      if(tags.size() == 0) {
+        d_settags = false;
+      }
+      else {
+        d_settags = true;
+      }
+    }
+
+    int
+    @NAME_IMPL@::work(int noutput_items,
+                      gr_vector_const_void_star &input_items,
+                      gr_vector_void_star &output_items)
+    {
+      @TYPE@ *optr = (@TYPE@ *) output_items[0];
+
+      if(d_repeat) {
+        unsigned int size = d_data.size ();
+        unsigned int offset = d_offset;
+        if(size == 0)
+          return -1;
+
+        if(d_settags) {
+          int n_outputitems_per_vector = d_data.size() / d_vlen;
+          for(int i = 0; i < noutput_items; i += n_outputitems_per_vector) {
+            // FIXME do proper vector copy
+            memcpy((void *) optr, (const void*)&d_data[0], size*sizeof (@TYPE@));
+            optr += size;
+            for(unsigned t = 0; t < d_tags.size(); t++) {
+              add_item_tag(0, nitems_written(0)+i+d_tags[t].offset,
+                           d_tags[t].key, d_tags[t].value);
+            }
+          }
+        }
+        else {
+          for(int i = 0; i < noutput_items*d_vlen; i++) {
+            optr[i] = d_data[offset++];
+            if(offset >= size) {
+              offset = 0;
+            }
+          }
+        }
+
+        d_offset = offset;
+        return noutput_items;
+      }
+      else {
+        if(d_offset >= d_data.size ())
+          return -1;  // Done!
+
+        unsigned n = std::min((unsigned)d_data.size() - d_offset,
+                              (unsigned)noutput_items*d_vlen);
+        for(unsigned i = 0; i < n; i++) {
+          optr[i] = d_data[d_offset + i];
+        }
+        for(unsigned t = 0; t < d_tags.size(); t++) {
+          if((d_tags[t].offset >= d_offset) && (d_tags[t].offset < d_offset+n))
+            add_item_tag(0, d_tags[t].offset, d_tags[t].key, d_tags[t].value);
+        }
+        d_offset += n;
+        return n/d_vlen;
+      }
+    }
+
+  } /* namespace blocks */
+} /* namespace gr */
diff --git a/gr-blocks/lib/vector_source_X_impl.h.t b/gr-blocks/lib/vector_source_X_impl.h.t
new file mode 100644
index 0000000000..78ec52bacf
--- /dev/null
+++ b/gr-blocks/lib/vector_source_X_impl.h.t
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2008,2012-2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME_IMPL@
+#define @GUARD_NAME_IMPL@
+
+#include <blocks/@NAME@.h>
+
+namespace gr {
+  namespace blocks {
+
+    class @NAME_IMPL@ : public @NAME@
+    {
+    private:
+      std::vector<@TYPE@> d_data;
+      bool d_repeat;
+      unsigned int d_offset;
+      int d_vlen;
+      bool d_settags;
+      std::vector<gr_tag_t> d_tags;
+      unsigned int d_tagpos;
+
+    public:
+      @NAME_IMPL@(const std::vector<@TYPE@> &data,
+                  bool repeat, int vlen,
+                  const std::vector<gr_tag_t> &tags);
+      ~@NAME_IMPL@();
+
+      void rewind() { d_offset=0; }
+      void set_data(const std::vector<@TYPE@> &data,
+                    const std::vector<gr_tag_t> &tags);
+
+      int work(int noutput_items,
+               gr_vector_const_void_star &input_items,
+               gr_vector_void_star &output_items);
+    };
+
+  } /* namespace blocks */
+} /* namespace gr */
+
+#endif /* @GUARD_NAME_IMPL@ */
diff --git a/gr-blocks/python/qa_copy.py b/gr-blocks/python/qa_copy.py
new file mode 100755
index 0000000000..04f6454231
--- /dev/null
+++ b/gr-blocks/python/qa_copy.py
@@ -0,0 +1,58 @@
+#!/usr/bin/env python
+#
+# Copyright 2009,2010,2013 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import blocks_swig as blocks
+
+class test_copy(gr_unittest.TestCase):
+
+    def setUp(self):
+        self.tb = gr.top_block()
+
+    def tearDown(self):
+        self.tb = None
+
+    def test_copy(self):
+        src_data = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+        expected_result = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+        src = blocks.vector_source_b(src_data)
+        op = blocks.copy(gr.sizeof_char)
+        dst = blocks.vector_sink_b()
+        self.tb.connect(src, op, dst)
+        self.tb.run()
+        dst_data = dst.data()
+        self.assertEqual(expected_result, dst_data)
+
+    def test_copy_drop (self):
+        src_data = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+        expected_result = ()
+        src = blocks.vector_source_b(src_data)
+        op = blocks.copy(gr.sizeof_char)
+	op.set_enabled(False)
+        dst = blocks.vector_sink_b()
+        self.tb.connect(src, op, dst)
+        self.tb.run()
+        dst_data = dst.data()
+        self.assertEqual(expected_result, dst_data)
+
+if __name__ == '__main__':
+    gr_unittest.run(test_copy, "test_copy.xml")
diff --git a/gr-blocks/python/qa_endian_swap.py b/gr-blocks/python/qa_endian_swap.py
new file mode 100644
index 0000000000..5180293052
--- /dev/null
+++ b/gr-blocks/python/qa_endian_swap.py
@@ -0,0 +1,66 @@
+#!/usr/bin/env python
+#
+# Copyright 2011-2013 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import blocks_swig as blocks
+import ctypes
+
+class test_endian_swap(gr_unittest.TestCase):
+
+    def setUp(self):
+        self.tb = gr.top_block()
+
+    def tearDown(self):
+        self.tb = None
+
+    def test_001(self):
+        src_data = [1,2,3,4]
+        expected_result = [256, 512, 768, 1024];
+
+        src = blocks.vector_source_s(src_data)
+        op = blocks.endian_swap(2)
+        dst = blocks.vector_sink_s()
+
+        self.tb.connect(src, op, dst)
+        self.tb.run()
+        result_data = list(dst.data())
+
+        self.assertEqual(expected_result, result_data)
+
+    def test_002(self):
+
+        src_data = [1,2,3,4]
+        expected_result = [16777216, 33554432, 50331648, 67108864];
+
+        src = blocks.vector_source_i(src_data)
+        op = blocks.endian_swap(4)
+        dst = blocks.vector_sink_i()
+
+        self.tb.connect(src, op, dst)
+        self.tb.run()
+        result_data = list(dst.data())
+    
+        self.assertEqual(expected_result, result_data)
+
+if __name__ == '__main__':
+    gr_unittest.run(test_endian_swap, "test_endian_swap.xml")
+
diff --git a/gr-blocks/python/qa_head.py b/gr-blocks/python/qa_head.py
new file mode 100755
index 0000000000..39b1255978
--- /dev/null
+++ b/gr-blocks/python/qa_head.py
@@ -0,0 +1,47 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,2007,2010,2013 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import blocks_swig as blocks
+
+class test_head(gr_unittest.TestCase):
+
+    def setUp(self):
+        self.tb = gr.top_block()
+
+    def tearDown(self):
+        self.tb = None
+
+    def test_head(self):
+        src_data = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+        expected_result = (1, 2, 3, 4)
+        src1 = blocks.vector_source_i(src_data)
+        op = blocks.head(gr.sizeof_int, 4)
+        dst1 = blocks.vector_sink_i()
+        self.tb.connect(src1, op)
+        self.tb.connect(op, dst1)
+        self.tb.run()
+        dst_data = dst1.data()
+        self.assertEqual(expected_result, dst_data)
+
+if __name__ == '__main__':
+    gr_unittest.run(test_head, "test_head.xml")
diff --git a/gr-blocks/python/qa_skiphead.py b/gr-blocks/python/qa_skiphead.py
new file mode 100755
index 0000000000..50a9bbc639
--- /dev/null
+++ b/gr-blocks/python/qa_skiphead.py
@@ -0,0 +1,103 @@
+#!/usr/bin/env python
+#
+# Copyright 2007,2010,2013 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import blocks_swig as blocks
+
+class test_skiphead(gr_unittest.TestCase):
+
+    def setUp(self):
+        self.tb = gr.top_block()
+        self.src_data = [int(x) for x in range(65536)]
+
+    def tearDown(self):
+        self.tb = None
+
+    def test_skip_0(self):
+        skip_cnt = 0
+        expected_result = tuple(self.src_data[skip_cnt:])
+        src1 = blocks.vector_source_i(self.src_data)
+        op = blocks.skiphead(gr.sizeof_int, skip_cnt)
+        dst1 = blocks.vector_sink_i()
+        self.tb.connect(src1, op, dst1)
+        self.tb.run()
+        dst_data = dst1.data()
+        self.assertEqual(expected_result, dst_data)
+
+    def test_skip_1(self):
+        skip_cnt = 1
+        expected_result = tuple(self.src_data[skip_cnt:])
+        src1 = blocks.vector_source_i(self.src_data)
+        op = blocks.skiphead(gr.sizeof_int, skip_cnt)
+        dst1 = blocks.vector_sink_i()
+        self.tb.connect(src1, op, dst1)
+        self.tb.run()
+        dst_data = dst1.data()
+        self.assertEqual(expected_result, dst_data)
+
+    def test_skip_1023(self):
+        skip_cnt = 1023
+        expected_result = tuple(self.src_data[skip_cnt:])
+        src1 = blocks.vector_source_i(self.src_data)
+        op = blocks.skiphead(gr.sizeof_int, skip_cnt)
+        dst1 = blocks.vector_sink_i()
+        self.tb.connect(src1, op, dst1)
+        self.tb.run()
+        dst_data = dst1.data()
+        self.assertEqual(expected_result, dst_data)
+
+    def test_skip_6339(self):
+        skip_cnt = 6339
+        expected_result = tuple(self.src_data[skip_cnt:])
+        src1 = blocks.vector_source_i(self.src_data)
+        op = blocks.skiphead(gr.sizeof_int, skip_cnt)
+        dst1 = blocks.vector_sink_i()
+        self.tb.connect(src1, op, dst1)
+        self.tb.run()
+        dst_data = dst1.data()
+        self.assertEqual(expected_result, dst_data)
+
+    def test_skip_12678(self):
+        skip_cnt = 12678
+        expected_result = tuple(self.src_data[skip_cnt:])
+        src1 = blocks.vector_source_i(self.src_data)
+        op = blocks.skiphead(gr.sizeof_int, skip_cnt)
+        dst1 = blocks.vector_sink_i()
+        self.tb.connect(src1, op, dst1)
+        self.tb.run()
+        dst_data = dst1.data()
+        self.assertEqual(expected_result, dst_data)
+
+    def test_skip_all(self):
+        skip_cnt = len(self.src_data)
+        expected_result = tuple(self.src_data[skip_cnt:])
+        src1 = blocks.vector_source_i(self.src_data)
+        op = blocks.skiphead(gr.sizeof_int, skip_cnt)
+        dst1 = blocks.vector_sink_i()
+        self.tb.connect(src1, op, dst1)
+        self.tb.run()
+        dst_data = dst1.data()
+        self.assertEqual(expected_result, dst_data)
+
+
+if __name__ == '__main__':
+    gr_unittest.run(test_skiphead, "test_skiphead.xml")
diff --git a/gr-blocks/python/qa_vector_insert.py b/gr-blocks/python/qa_vector_insert.py
new file mode 100755
index 0000000000..428a0031ba
--- /dev/null
+++ b/gr-blocks/python/qa_vector_insert.py
@@ -0,0 +1,59 @@
+#!/usr/bin/env python
+#
+# Copyright 2012-2013 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+from gnuradio import gr, gr_unittest
+import blocks_swig as blocks
+import math
+
+class test_vector_insert(gr_unittest.TestCase):
+
+    def setUp(self):
+        self.tb = gr.top_block()
+
+    def tearDown(self):
+        self.tb = None
+
+    def test_001(self):
+        src_data = [float(x) for x in range(16)]
+        expected_result = tuple(src_data)
+
+        period = 9177;
+        offset = 0;
+
+        src = gr.null_source(1)
+        head = gr.head(1, 10000000);
+        ins = blocks.vector_insert_b([1], period, offset);
+        dst = blocks.vector_sink_b()
+
+        self.tb.connect(src, head, ins, dst)
+        self.tb.run()
+        result_data = dst.data()
+
+        for i in range(10000):
+            if(i%period == offset):
+                self.assertEqual(1, result_data[i])
+            else:
+                self.assertEqual(0, result_data[i])
+
+if __name__ == '__main__':
+    gr_unittest.run(test_vector_insert, "test_vector_insert.xml")
+
diff --git a/gr-blocks/python/qa_vector_sink_source.py b/gr-blocks/python/qa_vector_sink_source.py
new file mode 100755
index 0000000000..169e6a4450
--- /dev/null
+++ b/gr-blocks/python/qa_vector_sink_source.py
@@ -0,0 +1,66 @@
+#!/usr/bin/env python
+#
+# Copyright 2008,2010,2013 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import blocks_swig as blocks
+import math
+
+class test_vector_sink_source(gr_unittest.TestCase):
+
+    def setUp(self):
+        self.tb = gr.top_block()
+
+    def tearDown(self):
+        self.tb = None
+
+    def test_001(self):
+        src_data = [float(x) for x in range(16)]
+        expected_result = tuple(src_data)
+
+        src = blocks.vector_source_f(src_data)
+        dst = blocks.vector_sink_f()
+
+        self.tb.connect(src, dst)
+        self.tb.run()
+        result_data = dst.data()
+        self.assertEqual(expected_result, result_data)
+
+    def test_002(self):
+        src_data = [float(x) for x in range(16)]
+        expected_result = tuple(src_data)
+
+        src = blocks.vector_source_f(src_data, False, 2)
+        dst = blocks.vector_sink_f(2)
+
+        self.tb.connect(src, dst)
+        self.tb.run()
+        result_data = dst.data()
+        self.assertEqual(expected_result, result_data)
+
+    def test_003(self):
+        src_data = [float(x) for x in range(16)]
+        expected_result = tuple(src_data)
+        self.assertRaises(RuntimeError, lambda : blocks.vector_source_f(src_data, False, 3))
+
+if __name__ == '__main__':
+    gr_unittest.run(test_vector_sink_source, "test_vector_sink_source.xml")
+
diff --git a/gr-blocks/swig/blocks_swig.i b/gr-blocks/swig/blocks_swig.i
index 14d6674e49..41202bb4b1 100644
--- a/gr-blocks/swig/blocks_swig.i
+++ b/gr-blocks/swig/blocks_swig.i
@@ -64,12 +64,14 @@
 #include "blocks/complex_to_mag_squared.h"
 #include "blocks/complex_to_arg.h"
 #include "blocks/conjugate_cc.h"
+#include "blocks/copy.h"
 #include "blocks/deinterleave.h"
 #include "blocks/delay.h"
 #include "blocks/divide_ff.h"
 #include "blocks/divide_ss.h"
 #include "blocks/divide_ii.h"
 #include "blocks/divide_cc.h"
+#include "blocks/endian_swap.h"
 #include "blocks/file_descriptor_sink.h"
 #include "blocks/file_descriptor_source.h"
 #include "blocks/file_sink_base.h"
@@ -82,6 +84,7 @@
 #include "blocks/float_to_int.h"
 #include "blocks/float_to_short.h"
 #include "blocks/float_to_uchar.h"
+#include "blocks/head.h"
 #include "blocks/int_to_float.h"
 #include "blocks/integrate_ss.h"
 #include "blocks/integrate_ii.h"
@@ -159,6 +162,7 @@
 #include "blocks/sample_and_hold_ff.h"
 #include "blocks/short_to_char.h"
 #include "blocks/short_to_float.h"
+#include "blocks/skiphead.h"
 #include "blocks/socket_pdu.h"
 #include "blocks/stream_mux.h"
 #include "blocks/stream_to_streams.h"
@@ -188,6 +192,21 @@
 #include "blocks/vco_f.h"
 #include "blocks/vector_to_stream.h"
 #include "blocks/vector_to_streams.h"
+#include "blocks/vector_insert_b.h"
+#include "blocks/vector_insert_s.h"
+#include "blocks/vector_insert_i.h"
+#include "blocks/vector_insert_f.h"
+#include "blocks/vector_insert_c.h"
+#include "blocks/vector_sink_b.h"
+#include "blocks/vector_sink_s.h"
+#include "blocks/vector_sink_i.h"
+#include "blocks/vector_sink_f.h"
+#include "blocks/vector_sink_c.h"
+#include "blocks/vector_source_b.h"
+#include "blocks/vector_source_s.h"
+#include "blocks/vector_source_i.h"
+#include "blocks/vector_source_f.h"
+#include "blocks/vector_source_c.h"
 #include "blocks/wavfile_sink.h"
 #include "blocks/wavfile_source.h"
 #include "blocks/xor_bb.h"
@@ -228,6 +247,7 @@
 %include "blocks/complex_to_mag_squared.h"
 %include "blocks/complex_to_arg.h"
 %include "blocks/conjugate_cc.h"
+%include "blocks/copy.h"
 %include "blocks/deinterleave.h"
 %include "blocks/delay.h"
 %include "blocks/file_descriptor_sink.h"
@@ -241,11 +261,13 @@
 %include "blocks/divide_ss.h"
 %include "blocks/divide_ii.h"
 %include "blocks/divide_cc.h"
+%include "blocks/endian_swap.h"
 %include "blocks/float_to_char.h"
 %include "blocks/float_to_complex.h"
 %include "blocks/float_to_int.h"
 %include "blocks/float_to_short.h"
 %include "blocks/float_to_uchar.h"
+%include "blocks/head.h"
 %include "blocks/int_to_float.h"
 %include "blocks/integrate_ss.h"
 %include "blocks/integrate_ii.h"
@@ -324,6 +346,7 @@
 %include "blocks/sample_and_hold_ff.h"
 %include "blocks/short_to_char.h"
 %include "blocks/short_to_float.h"
+%include "blocks/skiphead.h"
 %include "blocks/socket_pdu.h"
 %include "blocks/stream_mux.h"
 %include "blocks/stream_to_streams.h"
@@ -352,6 +375,21 @@
 %include "blocks/vco_f.h"
 %include "blocks/vector_to_stream.h"
 %include "blocks/vector_to_streams.h"
+%include "blocks/vector_insert_b.h"
+%include "blocks/vector_insert_s.h"
+%include "blocks/vector_insert_i.h"
+%include "blocks/vector_insert_f.h"
+%include "blocks/vector_insert_c.h"
+%include "blocks/vector_sink_b.h"
+%include "blocks/vector_sink_s.h"
+%include "blocks/vector_sink_i.h"
+%include "blocks/vector_sink_f.h"
+%include "blocks/vector_sink_c.h"
+%include "blocks/vector_source_b.h"
+%include "blocks/vector_source_s.h"
+%include "blocks/vector_source_i.h"
+%include "blocks/vector_source_f.h"
+%include "blocks/vector_source_c.h"
 %include "blocks/wavfile_sink.h"
 %include "blocks/wavfile_source.h"
 %include "blocks/xor_bb.h"
@@ -391,8 +429,10 @@ GR_SWIG_BLOCK_MAGIC2(blocks, complex_to_mag);
 GR_SWIG_BLOCK_MAGIC2(blocks, complex_to_mag_squared);
 GR_SWIG_BLOCK_MAGIC2(blocks, complex_to_arg);
 GR_SWIG_BLOCK_MAGIC2(blocks, conjugate_cc);
+GR_SWIG_BLOCK_MAGIC2(blocks, copy);
 GR_SWIG_BLOCK_MAGIC2(blocks, deinterleave);
 GR_SWIG_BLOCK_MAGIC2(blocks, delay);
+GR_SWIG_BLOCK_MAGIC2(blocks, endian_swap);
 GR_SWIG_BLOCK_MAGIC2(blocks, divide_ff);
 GR_SWIG_BLOCK_MAGIC2(blocks, divide_ss);
 GR_SWIG_BLOCK_MAGIC2(blocks, divide_ii);
@@ -408,6 +448,7 @@ GR_SWIG_BLOCK_MAGIC2(blocks, float_to_complex);
 GR_SWIG_BLOCK_MAGIC2(blocks, float_to_int);
 GR_SWIG_BLOCK_MAGIC2(blocks, float_to_short);
 GR_SWIG_BLOCK_MAGIC2(blocks, float_to_uchar);
+GR_SWIG_BLOCK_MAGIC2(blocks, head);
 GR_SWIG_BLOCK_MAGIC2(blocks, int_to_float);
 GR_SWIG_BLOCK_MAGIC2(blocks, integrate_ss);
 GR_SWIG_BLOCK_MAGIC2(blocks, integrate_ii);
@@ -485,6 +526,7 @@ GR_SWIG_BLOCK_MAGIC2(blocks, sample_and_hold_ii);
 GR_SWIG_BLOCK_MAGIC2(blocks, sample_and_hold_ff);
 GR_SWIG_BLOCK_MAGIC2(blocks, short_to_char);
 GR_SWIG_BLOCK_MAGIC2(blocks, short_to_float);
+GR_SWIG_BLOCK_MAGIC2(blocks, skiphead);
 GR_SWIG_BLOCK_MAGIC2(blocks, socket_pdu);
 GR_SWIG_BLOCK_MAGIC2(blocks, stream_mux);
 GR_SWIG_BLOCK_MAGIC2(blocks, stream_to_streams);
@@ -514,6 +556,21 @@ GR_SWIG_BLOCK_MAGIC2(blocks, unpacked_to_packed_ii);
 GR_SWIG_BLOCK_MAGIC2(blocks, vco_f);
 GR_SWIG_BLOCK_MAGIC2(blocks, vector_to_stream);
 GR_SWIG_BLOCK_MAGIC2(blocks, vector_to_streams);
+GR_SWIG_BLOCK_MAGIC2(blocks, vector_insert_b);
+GR_SWIG_BLOCK_MAGIC2(blocks, vector_insert_s);
+GR_SWIG_BLOCK_MAGIC2(blocks, vector_insert_i);
+GR_SWIG_BLOCK_MAGIC2(blocks, vector_insert_f);
+GR_SWIG_BLOCK_MAGIC2(blocks, vector_insert_c);
+GR_SWIG_BLOCK_MAGIC2(blocks, vector_sink_b);
+GR_SWIG_BLOCK_MAGIC2(blocks, vector_sink_s);
+GR_SWIG_BLOCK_MAGIC2(blocks, vector_sink_i);
+GR_SWIG_BLOCK_MAGIC2(blocks, vector_sink_f);
+GR_SWIG_BLOCK_MAGIC2(blocks, vector_sink_c);
+GR_SWIG_BLOCK_MAGIC2(blocks, vector_source_b);
+GR_SWIG_BLOCK_MAGIC2(blocks, vector_source_s);
+GR_SWIG_BLOCK_MAGIC2(blocks, vector_source_i);
+GR_SWIG_BLOCK_MAGIC2(blocks, vector_source_f);
+GR_SWIG_BLOCK_MAGIC2(blocks, vector_source_c);
 GR_SWIG_BLOCK_MAGIC2(blocks, wavfile_sink);
 GR_SWIG_BLOCK_MAGIC2(blocks, wavfile_source);
 GR_SWIG_BLOCK_MAGIC2(blocks, xor_bb);
-- 
cgit v1.2.3


From 51cbe589f7cd74056be613587e82e8d3b3168e84 Mon Sep 17 00:00:00 2001
From: Tom Rondeau <trondeau@vt.edu>
Date: Sat, 16 Mar 2013 23:34:34 -0400
Subject: blocks: moved nop, null source/sink, copy, vector_map to gr-blocks.

---
 gr-blocks/grc/blocks_block_tree.xml     |   3 +
 gr-blocks/grc/blocks_nop.xml            |  68 +++++++++++++++++
 gr-blocks/grc/blocks_null_sink.xml      |  54 ++++++++++++++
 gr-blocks/grc/blocks_null_source.xml    |  54 ++++++++++++++
 gr-blocks/include/blocks/CMakeLists.txt |   4 +
 gr-blocks/include/blocks/nop.h          |  56 ++++++++++++++
 gr-blocks/include/blocks/null_sink.h    |  55 ++++++++++++++
 gr-blocks/include/blocks/null_source.h  |  53 +++++++++++++
 gr-blocks/include/blocks/vector_map.h   |  71 ++++++++++++++++++
 gr-blocks/lib/CMakeLists.txt            |   4 +
 gr-blocks/lib/copy_impl.cc              |  31 +++++---
 gr-blocks/lib/copy_impl.h               |   1 +
 gr-blocks/lib/nop_impl.cc               |  78 ++++++++++++++++++++
 gr-blocks/lib/nop_impl.h                |  54 ++++++++++++++
 gr-blocks/lib/null_sink_impl.cc         |  60 +++++++++++++++
 gr-blocks/lib/null_sink_impl.h          |  45 +++++++++++
 gr-blocks/lib/null_source_impl.cc       |  63 ++++++++++++++++
 gr-blocks/lib/null_source_impl.h        |  45 +++++++++++
 gr-blocks/lib/vector_map_impl.cc        | 127 ++++++++++++++++++++++++++++++++
 gr-blocks/lib/vector_map_impl.h         |  55 ++++++++++++++
 gr-blocks/python/qa_copy.py             |   2 +-
 gr-blocks/python/qa_null_sink_source.py |  46 ++++++++++++
 gr-blocks/python/qa_vector_map.py       | 104 ++++++++++++++++++++++++++
 gr-blocks/swig/blocks_swig.i            |  15 ++++
 24 files changed, 1136 insertions(+), 12 deletions(-)
 create mode 100644 gr-blocks/grc/blocks_nop.xml
 create mode 100644 gr-blocks/grc/blocks_null_sink.xml
 create mode 100644 gr-blocks/grc/blocks_null_source.xml
 create mode 100644 gr-blocks/include/blocks/nop.h
 create mode 100644 gr-blocks/include/blocks/null_sink.h
 create mode 100644 gr-blocks/include/blocks/null_source.h
 create mode 100644 gr-blocks/include/blocks/vector_map.h
 create mode 100644 gr-blocks/lib/nop_impl.cc
 create mode 100644 gr-blocks/lib/nop_impl.h
 create mode 100644 gr-blocks/lib/null_sink_impl.cc
 create mode 100644 gr-blocks/lib/null_sink_impl.h
 create mode 100644 gr-blocks/lib/null_source_impl.cc
 create mode 100644 gr-blocks/lib/null_source_impl.h
 create mode 100644 gr-blocks/lib/vector_map_impl.cc
 create mode 100644 gr-blocks/lib/vector_map_impl.h
 create mode 100644 gr-blocks/python/qa_null_sink_source.py
 create mode 100644 gr-blocks/python/qa_vector_map.py

(limited to 'gr-blocks/include/blocks/CMakeLists.txt')

diff --git a/gr-blocks/grc/blocks_block_tree.xml b/gr-blocks/grc/blocks_block_tree.xml
index 618539354b..810ac300b5 100644
--- a/gr-blocks/grc/blocks_block_tree.xml
+++ b/gr-blocks/grc/blocks_block_tree.xml
@@ -40,6 +40,7 @@
 		<block>blocks_wavfile_source</block>
 		<block>blocks_vector_source_x</block>
 		<block>blocks_vector_insert_x</block>
+		<block>blocks_null_source</block>
 	</cat>
 	<cat>
 	        <name>Sinks (New)</name>
@@ -53,6 +54,7 @@
 		<block>blocks_udp_sink</block>
 		<block>blocks_wavfile_sink</block>
 		<block>blocks_vector_sink_x</block>
+		<block>blocks_null_sink</block>
 	</cat>
 	<cat>
 		<name>Math Operations (New) </name>
@@ -140,6 +142,7 @@
 		<block>blocks_head</block>
 		<block>blocks_skiphead</block>
                 <block>blocks_copy</block>
+                <block>blocks_nop</block>
 	</cat>
 	<cat>
 	        <name>Networking</name>
diff --git a/gr-blocks/grc/blocks_nop.xml b/gr-blocks/grc/blocks_nop.xml
new file mode 100644
index 0000000000..d38c23839d
--- /dev/null
+++ b/gr-blocks/grc/blocks_nop.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##Nop
+###################################################
+ -->
+<block>
+	<name>Nop</name>
+	<key>blocks_nop</key>
+	<import>from gnuradio import blocks</import>
+	<make>blocks.nop($type.size*$vlen)</make>
+	<param>
+		<name>Type</name>
+		<key>type</key>
+		<type>enum</type>
+		<option>
+			<name>Complex</name>
+			<key>complex</key>
+			<opt>size:gr.sizeof_gr_complex</opt>
+		</option>
+		<option>
+			<name>Float</name>
+			<key>float</key>
+			<opt>size:gr.sizeof_float</opt>
+		</option>
+		<option>
+			<name>Int</name>
+			<key>int</key>
+			<opt>size:gr.sizeof_int</opt>
+		</option>
+		<option>
+			<name>Short</name>
+			<key>short</key>
+			<opt>size:gr.sizeof_short</opt>
+		</option>
+		<option>
+			<name>Byte</name>
+			<key>byte</key>
+			<opt>size:gr.sizeof_char</opt>
+		</option>
+	</param>
+	<param>
+		<name>Num Ports</name>
+		<key>num_ports</key>
+		<value>1</value>
+		<type>int</type>
+	</param>
+	<param>
+		<name>Vec Length</name>
+		<key>vlen</key>
+		<value>1</value>
+		<type>int</type>
+	</param>
+	<check>$num_ports &gt; 0</check>
+	<check>$vlen &gt; 0</check>
+	<sink>
+		<name>in</name>
+		<type>$type</type>
+		<vlen>$vlen</vlen>
+		<nports>$num_ports</nports>
+	</sink>
+	<source>
+		<name>out</name>
+		<type>$type</type>
+		<vlen>$vlen</vlen>
+		<nports>$num_ports</nports>
+	</source>
+</block>
diff --git a/gr-blocks/grc/blocks_null_sink.xml b/gr-blocks/grc/blocks_null_sink.xml
new file mode 100644
index 0000000000..2ae20e619a
--- /dev/null
+++ b/gr-blocks/grc/blocks_null_sink.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##Null Sink
+###################################################
+ -->
+<block>
+	<name>Null Sink</name>
+	<key>blocks_null_sink</key>
+	<import>from gnuradio import blocks</import>
+	<make>blocks.null_sink($type.size*$vlen)</make>
+	<param>
+		<name>Input Type</name>
+		<key>type</key>
+		<type>enum</type>
+		<option>
+			<name>Complex</name>
+			<key>complex</key>
+			<opt>size:gr.sizeof_gr_complex</opt>
+		</option>
+		<option>
+			<name>Float</name>
+			<key>float</key>
+			<opt>size:gr.sizeof_float</opt>
+		</option>
+		<option>
+			<name>Int</name>
+			<key>int</key>
+			<opt>size:gr.sizeof_int</opt>
+		</option>
+		<option>
+			<name>Short</name>
+			<key>short</key>
+			<opt>size:gr.sizeof_short</opt>
+		</option>
+		<option>
+			<name>Byte</name>
+			<key>byte</key>
+			<opt>size:gr.sizeof_char</opt>
+		</option>
+	</param>
+	<param>
+		<name>Vec Length</name>
+		<key>vlen</key>
+		<value>1</value>
+		<type>int</type>
+	</param>
+	<check>$vlen &gt; 0</check>
+	<sink>
+		<name>in</name>
+		<type>$type</type>
+		<vlen>$vlen</vlen>
+	</sink>
+</block>
diff --git a/gr-blocks/grc/blocks_null_source.xml b/gr-blocks/grc/blocks_null_source.xml
new file mode 100644
index 0000000000..01d3905cab
--- /dev/null
+++ b/gr-blocks/grc/blocks_null_source.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##Null Source
+###################################################
+ -->
+<block>
+	<name>Null Source</name>
+	<key>blocks_null_source</key>
+	<import>from gnuradio import blocks</import>
+	<make>blocks.null_source($type.size*$vlen)</make>
+	<param>
+		<name>Output Type</name>
+		<key>type</key>
+		<type>enum</type>
+		<option>
+			<name>Complex</name>
+			<key>complex</key>
+			<opt>size:gr.sizeof_gr_complex</opt>
+		</option>
+		<option>
+			<name>Float</name>
+			<key>float</key>
+			<opt>size:gr.sizeof_float</opt>
+		</option>
+		<option>
+			<name>Int</name>
+			<key>int</key>
+			<opt>size:gr.sizeof_int</opt>
+		</option>
+		<option>
+			<name>Short</name>
+			<key>short</key>
+			<opt>size:gr.sizeof_short</opt>
+		</option>
+		<option>
+			<name>Byte</name>
+			<key>byte</key>
+			<opt>size:gr.sizeof_char</opt>
+		</option>
+	</param>
+	<param>
+		<name>Vec Length</name>
+		<key>vlen</key>
+		<value>1</value>
+		<type>int</type>
+	</param>
+	<check>$vlen &gt; 0</check>
+	<source>
+		<name>out</name>
+		<type>$type</type>
+		<vlen>$vlen</vlen>
+	</source>
+</block>
diff --git a/gr-blocks/include/blocks/CMakeLists.txt b/gr-blocks/include/blocks/CMakeLists.txt
index a7cc1e0a31..b34809ae59 100644
--- a/gr-blocks/include/blocks/CMakeLists.txt
+++ b/gr-blocks/include/blocks/CMakeLists.txt
@@ -158,6 +158,9 @@ install(FILES
     multiply_const_cc.h
     multiply_const_ff.h
     nlog10_ff.h
+    nop.h
+    null_sink.h
+    null_source.h
     pack_k_bits_bb.h
     patterned_interleaver.h
     pdu.h
@@ -192,6 +195,7 @@ install(FILES
     udp_source.h
     unpack_k_bits_bb.h
     vco_f.h
+    vector_map.h
     vector_to_stream.h
     vector_to_streams.h
     wavfile_sink.h
diff --git a/gr-blocks/include/blocks/nop.h b/gr-blocks/include/blocks/nop.h
new file mode 100644
index 0000000000..b3135e1cc8
--- /dev/null
+++ b/gr-blocks/include/blocks/nop.h
@@ -0,0 +1,56 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010,2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_NOP_H
+#define INCLUDED_GR_NOP_H
+
+#include <blocks/api.h>
+#include <gr_block.h>
+#include <stddef.h>			// size_t
+
+namespace gr {
+  namespace blocks {
+
+    /*!
+     * \brief Does nothing. Used for testing only.
+     * \ingroup misc_blk
+     */
+    class BLOCKS_API nop : virtual public gr_block
+    {
+    public:
+      // gr::blocks::nop::sptr
+      typedef boost::shared_ptr<nop> sptr;
+
+      /*!
+       * Build a nop block.
+       *
+       * \param sizeof_stream_item size of the stream items in bytes.
+       */
+      static sptr make(size_t sizeof_stream_item);
+
+      virtual int nmsgs_received() const = 0;
+    };
+
+  } /* namespace blocks */
+} /* namespace gr */
+
+#endif /* INCLUDED_GR_NOP_H */
diff --git a/gr-blocks/include/blocks/null_sink.h b/gr-blocks/include/blocks/null_sink.h
new file mode 100644
index 0000000000..c13a7552c6
--- /dev/null
+++ b/gr-blocks/include/blocks/null_sink.h
@@ -0,0 +1,55 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010,2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_NULL_SINK_H
+#define INCLUDED_GR_NULL_SINK_H
+
+#include <blocks/api.h>
+#include <gr_sync_block.h>
+#include <stddef.h>			// size_t
+
+namespace gr {
+  namespace blocks {
+
+    /*!
+     * \brief Bit bucket. Use as a termination point when a sink is
+     * required and we don't want to do anything real.
+     * \ingroup sink_blk
+     */
+    class BLOCKS_API null_sink : virtual public gr_sync_block
+    {
+    public:
+      // gr::blocks::null_sink::sptr
+      typedef boost::shared_ptr<null_sink> sptr;
+
+      /*!
+       * Build a null sink block.
+       *
+       * \param sizeof_stream_item size of the stream items in bytes.
+       */
+      static sptr make(size_t sizeof_stream_item);
+    };
+
+  } /* namespace blocks */
+} /* namespace gr */
+
+#endif /* INCLUDED_GR_NULL_SINK_H */
diff --git a/gr-blocks/include/blocks/null_source.h b/gr-blocks/include/blocks/null_source.h
new file mode 100644
index 0000000000..904a0c1ba3
--- /dev/null
+++ b/gr-blocks/include/blocks/null_source.h
@@ -0,0 +1,53 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010,2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_NULL_SOURCE_H
+#define INCLUDED_GR_NULL_SOURCE_H
+
+#include <blocks/api.h>
+#include <gr_sync_block.h>
+
+namespace gr {
+  namespace blocks {
+
+    /*!
+     * \brief A source of zeros used mainly for testing.
+     * \ingroup source_blk
+     */
+    class BLOCKS_API null_source : virtual public gr_sync_block
+    {
+    public:
+      // gr::blocks::null_source::sptr
+      typedef boost::shared_ptr<null_source> sptr;
+
+      /*!
+       * Build a null source block.
+       *
+       * \param sizeof_stream_item size of the stream items in bytes.
+       */
+      static sptr make(size_t sizeof_stream_item);
+    };
+
+  } /* namespace blocks */
+} /* namespace gr */
+
+#endif /* INCLUDED_GR_NULL_SOURCE_H */
diff --git a/gr-blocks/include/blocks/vector_map.h b/gr-blocks/include/blocks/vector_map.h
new file mode 100644
index 0000000000..64c8744975
--- /dev/null
+++ b/gr-blocks/include/blocks/vector_map.h
@@ -0,0 +1,71 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012,2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_VECTOR_MAP_H
+#define INCLUDED_GR_VECTOR_MAP_H
+
+#include <blocks/api.h>
+#include <vector>
+#include <gr_sync_block.h>
+
+namespace gr {
+  namespace blocks {
+
+    /*!
+     * \brief Maps elements from a set of input vectors to a set of output vectors.
+     * \ingroup slicedice_blk
+     *
+     * If in[i] is the input vector in the i'th stream then the output
+     * vector in the j'th stream is:
+     *
+     * out[j][k] = in[mapping[j][k][0]][mapping[j][k][1]]
+     *
+     * That is mapping is of the form (out_stream1_mapping,
+     * out_stream2_mapping, ...)  and out_stream1_mapping is of the
+     * form (element1_mapping, element2_mapping, ...)  and
+     * element1_mapping is of the form (in_stream, in_element).
+     */
+    class BLOCKS_API vector_map : virtual public gr_sync_block
+    {
+    public:
+      // gr::blocks::vector_map::sptr
+      typedef boost::shared_ptr<vector_map> sptr;
+
+      /*!
+       * Build a vector map block.
+       *
+       * \param item_size (integer) size of vector elements
+       * \param in_vlens (vector of integers) number of elements in each
+       *                 input vector
+       * \param mapping (vector of vectors of vectors of integers) how to
+       *                map elements from input to output vectors
+       */
+      static sptr make(size_t item_size, std::vector<size_t> in_vlens,
+                       std::vector< std::vector< std::vector<size_t> > > mapping);
+
+      virtual void set_mapping(std::vector< std::vector< std::vector<size_t> > > mapping) = 0;
+    };
+
+  } /* namespace blocks */
+} /* namespace gr */
+
+#endif /* INCLUDED_GR_VECTOR_MAP_H */
diff --git a/gr-blocks/lib/CMakeLists.txt b/gr-blocks/lib/CMakeLists.txt
index b0f3ef15cd..3f456b6b04 100644
--- a/gr-blocks/lib/CMakeLists.txt
+++ b/gr-blocks/lib/CMakeLists.txt
@@ -195,6 +195,9 @@ list(APPEND gr_blocks_sources
     multiply_const_cc_impl.cc
     multiply_const_ff_impl.cc
     nlog10_ff_impl.cc
+    nop_impl.cc
+    null_sink_impl.cc
+    null_source_impl.cc
     pack_k_bits_bb_impl.cc
     patterned_interleaver_impl.cc
     pdu.cc
@@ -232,6 +235,7 @@ list(APPEND gr_blocks_sources
     udp_source_impl.cc
     unpack_k_bits_bb_impl.cc
     vco_f_impl.cc
+    vector_map_impl.cc
     vector_to_stream_impl.cc
     vector_to_streams_impl.cc
     wavfile_sink_impl.cc
diff --git a/gr-blocks/lib/copy_impl.cc b/gr-blocks/lib/copy_impl.cc
index f489b03c0c..929f22b7d3 100644
--- a/gr-blocks/lib/copy_impl.cc
+++ b/gr-blocks/lib/copy_impl.cc
@@ -40,8 +40,8 @@ namespace gr {
 
     copy_impl::copy_impl(size_t itemsize)
       : gr_block("copy",
-                 gr_make_io_signature(1, 1, itemsize),
-                 gr_make_io_signature(1, 1, itemsize)),
+                 gr_make_io_signature(1, -1, itemsize),
+                 gr_make_io_signature(1, -1, itemsize)),
         d_itemsize(itemsize),
         d_enabled(true)
     {
@@ -51,6 +51,14 @@ namespace gr {
     {
     }
 
+    void
+    copy_impl::forecast(int noutput_items, gr_vector_int &ninput_items_required)
+    {
+      unsigned ninputs = ninput_items_required.size();
+      for (unsigned i = 0; i < ninputs; i++)
+	ninput_items_required[i] = noutput_items;
+    }
+
     bool
     copy_impl::check_topology(int ninputs, int noutputs)
     {
@@ -63,19 +71,20 @@ namespace gr {
                             gr_vector_const_void_star &input_items,
                             gr_vector_void_star &output_items)
     {
-      const uint8_t *in = (const uint8_t*)input_items[0];
-      uint8_t *out = (uint8_t*)output_items[0];
-
-      int n = std::min<int>(ninput_items[0], noutput_items);
-      int j = 0;
+      const uint8_t **in = (const uint8_t**)&input_items[0];
+      uint8_t **out = (uint8_t**)&output_items[0];
 
+      int n = 0;
       if(d_enabled) {
-        memcpy(out, in, n*d_itemsize);
-        j = n;
+        int ninputs = input_items.size();
+        for(int i = 0; i < ninputs; i++) {
+          memcpy(out[i], in[i], noutput_items*d_itemsize);
+        }
+        n = noutput_items;
       }
 
-      consume_each(n);
-      return j;
+      consume_each(noutput_items);
+      return n;
     }
 
   } /* namespace blocks */
diff --git a/gr-blocks/lib/copy_impl.h b/gr-blocks/lib/copy_impl.h
index f462ffebdc..1f0f1a655e 100644
--- a/gr-blocks/lib/copy_impl.h
+++ b/gr-blocks/lib/copy_impl.h
@@ -38,6 +38,7 @@ namespace gr {
       copy_impl(size_t itemsize);
       ~copy_impl();
 
+      void forecast(int noutput_items, gr_vector_int &ninput_items_required);
       bool check_topology(int ninputs, int noutputs);
 
       void set_enabled(bool enable) { d_enabled = enable; }
diff --git a/gr-blocks/lib/nop_impl.cc b/gr-blocks/lib/nop_impl.cc
new file mode 100644
index 0000000000..766f07e2b8
--- /dev/null
+++ b/gr-blocks/lib/nop_impl.cc
@@ -0,0 +1,78 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010,2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "nop_impl.h"
+#include <gr_io_signature.h>
+#include <boost/bind.hpp>
+
+namespace gr {
+  namespace blocks {
+
+    nop::sptr
+    nop::make(size_t sizeof_stream_item)
+    {
+      return gnuradio::get_initial_sptr
+        (new nop_impl(sizeof_stream_item));
+    }
+
+    nop_impl::nop_impl (size_t sizeof_stream_item)
+      : gr_block("nop",
+                 gr_make_io_signature(0, -1, sizeof_stream_item),
+                 gr_make_io_signature(0, -1, sizeof_stream_item)),
+        d_nmsgs_recvd(0)
+    {
+      // Arrange to have count_received_msgs called when messages are received.
+      message_port_register_in(pmt::mp("port"));
+      set_msg_handler(pmt::mp("port"), boost::bind(&nop_impl::count_received_msgs, this, _1));
+    }
+
+    nop_impl::~nop_impl()
+    {
+    }
+
+    // Trivial message handler that just counts them.
+    // (N.B., This feature is used in qa_set_msg_handler)
+    void
+    nop_impl::count_received_msgs(pmt::pmt_t msg)
+    {
+      d_nmsgs_recvd++;
+    }
+
+    int
+    nop_impl::general_work(int noutput_items,
+                           gr_vector_int &ninput_items,
+                           gr_vector_const_void_star &input_items,
+                           gr_vector_void_star &output_items)
+    {
+      // eat any input that's available
+      for(unsigned i = 0; i < ninput_items.size (); i++)
+        consume(i, ninput_items[i]);
+
+      return noutput_items;
+    }
+
+  } /* namespace blocks */
+} /* namespace gr */
diff --git a/gr-blocks/lib/nop_impl.h b/gr-blocks/lib/nop_impl.h
new file mode 100644
index 0000000000..b236abb7aa
--- /dev/null
+++ b/gr-blocks/lib/nop_impl.h
@@ -0,0 +1,54 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010,2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_NOP_IMPL_H
+#define INCLUDED_GR_NOP_IMPL_H
+
+#include <blocks/nop.h>
+
+namespace gr {
+  namespace blocks {
+
+    class nop_impl : public nop
+    {
+    protected:
+      int d_nmsgs_recvd;
+
+      // Method that just counts any received messages.
+      void count_received_msgs(pmt::pmt_t msg);
+
+    public:
+      nop_impl(size_t sizeof_stream_item);
+      ~nop_impl();
+
+      int nmsgs_received() const { return d_nmsgs_recvd; }
+
+      int general_work(int noutput_items,
+                       gr_vector_int &ninput_items,
+                       gr_vector_const_void_star &input_items,
+                       gr_vector_void_star &output_items);
+    };
+
+  } /* namespace blocks */
+} /* namespace gr */
+
+#endif /* INCLUDED_GR_NOP_IMPL_H */
diff --git a/gr-blocks/lib/null_sink_impl.cc b/gr-blocks/lib/null_sink_impl.cc
new file mode 100644
index 0000000000..b780a2405a
--- /dev/null
+++ b/gr-blocks/lib/null_sink_impl.cc
@@ -0,0 +1,60 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010,2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "null_sink_impl.h"
+#include <gr_io_signature.h>
+
+namespace gr {
+  namespace blocks {
+
+    null_sink::sptr
+    null_sink::make(size_t sizeof_stream_item)
+    {
+      return gnuradio::get_initial_sptr
+        (new null_sink_impl(sizeof_stream_item));
+    }
+
+    null_sink_impl::null_sink_impl(size_t sizeof_stream_item)
+      : gr_sync_block("null_sink",
+                      gr_make_io_signature(1, 1, sizeof_stream_item),
+                      gr_make_io_signature(0, 0, 0))
+    {
+    }
+
+    null_sink_impl::~null_sink_impl()
+    {
+    }
+
+    int
+    null_sink_impl::work(int noutput_items,
+                         gr_vector_const_void_star &input_items,
+                         gr_vector_void_star &output_items)
+    {
+      return noutput_items;
+    }
+
+  } /* namespace blocks */
+} /* namespace gr */
diff --git a/gr-blocks/lib/null_sink_impl.h b/gr-blocks/lib/null_sink_impl.h
new file mode 100644
index 0000000000..bb4c695c23
--- /dev/null
+++ b/gr-blocks/lib/null_sink_impl.h
@@ -0,0 +1,45 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010,2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_NULL_SINK_IMPL_H
+#define INCLUDED_GR_NULL_SINK_IMPL_H
+
+#include <blocks/null_sink.h>
+
+namespace gr {
+  namespace blocks {
+
+    class null_sink_impl : public null_sink
+    {
+    public:
+      null_sink_impl(size_t sizeof_stream_item);
+      ~null_sink_impl();
+
+      int work(int noutput_items,
+               gr_vector_const_void_star &input_items,
+               gr_vector_void_star &output_items);
+    };
+
+  } /* namespace blocks */
+} /* namespace gr */
+
+#endif /* INCLUDED_GR_NULL_SINK_IMPL_H */
diff --git a/gr-blocks/lib/null_source_impl.cc b/gr-blocks/lib/null_source_impl.cc
new file mode 100644
index 0000000000..81999d0501
--- /dev/null
+++ b/gr-blocks/lib/null_source_impl.cc
@@ -0,0 +1,63 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010,2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "null_source_impl.h"
+#include <gr_io_signature.h>
+#include <string.h>
+
+namespace gr {
+  namespace blocks {
+
+    null_source::sptr
+    null_source::make(size_t sizeof_stream_item)
+    {
+      return gnuradio::get_initial_sptr
+        (new null_source_impl(sizeof_stream_item));
+    }
+
+    null_source_impl::null_source_impl (size_t sizeof_stream_item)
+      : gr_sync_block("null_source",
+                      gr_make_io_signature(0, 0, 0),
+                      gr_make_io_signature(1, 1, sizeof_stream_item))
+    {
+    }
+
+    null_source_impl::~null_source_impl()
+    {
+    }
+
+    int
+    null_source_impl::work(int noutput_items,
+                           gr_vector_const_void_star &input_items,
+                           gr_vector_void_star &output_items)
+    {
+      void *optr = (void*)output_items[0];
+      memset(optr, 0, noutput_items * output_signature()->sizeof_stream_item(0));
+      return noutput_items;
+    }
+
+  } /* namespace blocks */
+} /* namespace gr */
diff --git a/gr-blocks/lib/null_source_impl.h b/gr-blocks/lib/null_source_impl.h
new file mode 100644
index 0000000000..36201d54b6
--- /dev/null
+++ b/gr-blocks/lib/null_source_impl.h
@@ -0,0 +1,45 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2010,2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_NULL_SOURCE_IMPL_H
+#define INCLUDED_GR_NULL_SOURCE_IMPL_H
+
+#include <blocks/null_source.h>
+
+namespace gr {
+  namespace blocks {
+
+    class null_source_impl : public null_source
+    {
+    public:
+      null_source_impl(size_t sizeof_stream_item);
+      ~null_source_impl();
+
+      int work(int noutput_items,
+               gr_vector_const_void_star &input_items,
+               gr_vector_void_star &output_items);
+    };
+
+  } /* namespace blocks */
+} /* namespace gr */
+
+#endif /* INCLUDED_GR_NULL_SOURCE_IMPL_H */
diff --git a/gr-blocks/lib/vector_map_impl.cc b/gr-blocks/lib/vector_map_impl.cc
new file mode 100644
index 0000000000..cefaaeea35
--- /dev/null
+++ b/gr-blocks/lib/vector_map_impl.cc
@@ -0,0 +1,127 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012,2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "vector_map_impl.h"
+#include <gr_io_signature.h>
+#include <string.h>
+
+namespace gr {
+  namespace blocks {
+
+    std::vector<int>
+    get_in_sizeofs(size_t item_size, std::vector<size_t> in_vlens)
+    {
+      std::vector<int> in_sizeofs;
+      for(unsigned int i = 0; i < in_vlens.size(); i++) {
+        in_sizeofs.push_back(in_vlens[i]*item_size);
+      }
+      return in_sizeofs;
+    }
+
+    std::vector<int>
+    get_out_sizeofs(size_t item_size,
+                    std::vector< std::vector< std::vector<size_t> > > mapping)
+    {
+      std::vector<int> out_sizeofs;
+      for(unsigned int i = 0; i < mapping.size(); i++) {
+        out_sizeofs.push_back(mapping[i].size()*item_size);
+      }
+      return out_sizeofs;
+    } 
+
+    vector_map::sptr
+    vector_map::make(size_t item_size, std::vector<size_t> in_vlens,
+                     std::vector< std::vector< std::vector<size_t> > > mapping)
+    {
+      return gnuradio::get_initial_sptr
+        (new vector_map_impl(item_size, in_vlens, mapping));
+    }
+
+    vector_map_impl::vector_map_impl(size_t item_size, std::vector<size_t> in_vlens,
+                                     std::vector< std::vector< std::vector<size_t> > > mapping)
+      : gr_sync_block("vector_map",
+                      gr_make_io_signaturev(in_vlens.size(), in_vlens.size(),
+                                            get_in_sizeofs(item_size, in_vlens)),
+                      gr_make_io_signaturev(mapping.size(), mapping.size(),
+                                            get_out_sizeofs(item_size, mapping))),
+        d_item_size(item_size), d_in_vlens(in_vlens)
+    {
+      set_mapping(mapping);
+    }
+
+    vector_map_impl::~vector_map_impl()
+    {
+    }
+
+    void
+    vector_map_impl::set_mapping(std::vector< std::vector< std::vector<size_t> > > mapping)
+    {
+      // Make sure the contents of the mapping vectors are possible.
+      for(unsigned int i=0; i<mapping.size(); i++) {
+        for(unsigned int j=0; j<mapping[i].size(); j++) {
+          if(mapping[i][j].size() != 2) {
+            throw std::runtime_error("Mapping must be of the form (out_mapping_stream1, out_mapping_stream2, ...), where out_mapping_stream1 is of the form (mapping_element1, mapping_element2, ...), where mapping_element1 is of the form (input_stream, input_element).  This error is raised because a mapping_element vector does not contain exactly 2 items.");
+          }
+          unsigned int s = mapping[i][j][0];
+          unsigned int index = mapping[i][j][1];
+          if(s >= d_in_vlens.size()) {
+            throw std::runtime_error("Stream numbers in mapping must be less than the number of input streams.");
+          }
+          if((index < 0) || (index >= d_in_vlens[s])) {
+            throw std::runtime_error ("Indices in mapping must be greater than 0 and less than the input vector lengths.");
+          }
+        }
+      }
+      gruel::scoped_lock guard(d_mutex);
+      d_mapping = mapping;
+    }
+
+    int
+    vector_map_impl::work(int noutput_items,
+                          gr_vector_const_void_star &input_items,
+                          gr_vector_void_star &output_items)
+    {
+      const char **inv = (const char**)&input_items[0];
+      char **outv = (char**)&output_items[0];
+
+      for(unsigned int n = 0; n < (unsigned int)(noutput_items); n++) {
+        for(unsigned int i = 0; i < d_mapping.size(); i++) {
+          unsigned int out_vlen = d_mapping[i].size();
+          for(unsigned int j = 0; j < out_vlen; j++) {
+            unsigned int s = d_mapping[i][j][0];
+            unsigned int k = d_mapping[i][j][1];
+            memcpy(outv[i] + out_vlen*d_item_size*n +
+                   d_item_size*j, inv[s] + d_in_vlens[s]*d_item_size*n +
+                   k*d_item_size, d_item_size);
+          }
+        }
+      }
+
+      return noutput_items;
+    }
+
+  } /* namespace blocks */
+} /* namespace gr */
diff --git a/gr-blocks/lib/vector_map_impl.h b/gr-blocks/lib/vector_map_impl.h
new file mode 100644
index 0000000000..e27b3b9cec
--- /dev/null
+++ b/gr-blocks/lib/vector_map_impl.h
@@ -0,0 +1,55 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012,2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_VECTOR_MAP_IMPL_H
+#define INCLUDED_GR_VECTOR_MAP_IMPL_H
+
+#include <blocks/vector_map.h>
+#include <gruel/thread.h>
+
+namespace gr {
+  namespace blocks {
+
+    class vector_map_impl : public vector_map
+    {
+    private:
+      size_t d_item_size;
+      std::vector<size_t> d_in_vlens;
+      std::vector< std::vector< std::vector<size_t> > > d_mapping;
+      gruel::mutex d_mutex; // mutex to protect set/work access
+
+    public:
+      vector_map_impl(size_t item_size, std::vector<size_t> in_vlens,
+                      std::vector< std::vector< std::vector<size_t> > > mapping);
+      ~vector_map_impl();
+
+      void set_mapping(std::vector< std::vector< std::vector<size_t> > > mapping);
+
+      int work(int noutput_items,
+               gr_vector_const_void_star &input_items,
+               gr_vector_void_star &output_items);
+    };
+
+  } /* namespace blocks */
+} /* namespace gr */
+
+#endif /* INCLUDED_GR_VECTOR_MAP_IMPL_H */
diff --git a/gr-blocks/python/qa_copy.py b/gr-blocks/python/qa_copy.py
index 04f6454231..012d790609 100755
--- a/gr-blocks/python/qa_copy.py
+++ b/gr-blocks/python/qa_copy.py
@@ -46,7 +46,7 @@ class test_copy(gr_unittest.TestCase):
         src_data = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
         expected_result = ()
         src = blocks.vector_source_b(src_data)
-        op = blocks.copy(gr.sizeof_char)
+        op = gr.copy(gr.sizeof_char)
 	op.set_enabled(False)
         dst = blocks.vector_sink_b()
         self.tb.connect(src, op, dst)
diff --git a/gr-blocks/python/qa_null_sink_source.py b/gr-blocks/python/qa_null_sink_source.py
new file mode 100644
index 0000000000..60552cb207
--- /dev/null
+++ b/gr-blocks/python/qa_null_sink_source.py
@@ -0,0 +1,46 @@
+#!/usr/bin/env python
+#
+# Copyright 2013 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import blocks_swig as blocks
+import math
+
+class test_null_sink_source(gr_unittest.TestCase):
+
+    def setUp(self):
+        self.tb = gr.top_block()
+
+    def tearDown(self):
+        self.tb = None
+
+    def test_001(self):
+        # Just running some data through null source/sink
+        src = blocks.null_source(gr.sizeof_float)
+        hed = blocks.head(gr.sizeof_float, 100)
+        dst = blocks.null_sink(gr.sizeof_float)
+
+        self.tb.connect(src, hed, dst)
+        self.tb.run()
+
+if __name__ == '__main__':
+    gr_unittest.run(test_null_sink_source, "test_null_sink_source.xml")
+
diff --git a/gr-blocks/python/qa_vector_map.py b/gr-blocks/python/qa_vector_map.py
new file mode 100644
index 0000000000..54565fe443
--- /dev/null
+++ b/gr-blocks/python/qa_vector_map.py
@@ -0,0 +1,104 @@
+#!/usr/bin/env python
+#
+# Copyright 2012,2013 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest
+import blocks_swig as blocks
+import math
+
+class test_vector_map(gr_unittest.TestCase):
+
+    def setUp(self):
+        self.tb = gr.top_block()
+
+    def tearDown(self):
+        self.tb = None
+
+    def test_reversing(self):
+        # Chunk data in blocks of N and reverse the block contents.
+        N = 5
+        src_data = range(0, 20)
+        expected_result = []
+        for i in range(N-1, len(src_data), N):
+            for j in range(0, N):
+                expected_result.append(1.0*(i-j))
+        mapping = [list(reversed([(0, i) for i in range(0, N)]))]
+        src = blocks.vector_source_f(src_data, False, N)
+        vmap = blocks.vector_map(gr.sizeof_float, (N, ), mapping)
+        dst = blocks.vector_sink_f(N)
+        self.tb.connect(src, vmap, dst)
+        self.tb.run()
+        result_data = list(dst.data())
+        self.assertEqual(expected_result, result_data)
+
+    def test_vector_to_streams(self):
+        # Split an input vector into N streams.
+        N = 5
+        M = 20
+        src_data = range(0, M)
+        expected_results = []
+        for n in range(0, N):
+            expected_results.append(range(n, M, N))
+        mapping = [[(0, n)] for n in range(0, N)]
+        src = blocks.vector_source_f(src_data, False, N)
+        vmap = blocks.vector_map(gr.sizeof_float, (N, ), mapping)
+        dsts = [blocks.vector_sink_f(1) for n in range(0, N)]
+        self.tb.connect(src, vmap)
+        for n in range(0, N):
+            self.tb.connect((vmap, n), dsts[n])
+        self.tb.run()
+        for n in range(0, N):
+            result_data = list(dsts[n].data())
+            self.assertEqual(expected_results[n], result_data)
+        
+    def test_interleaving(self):
+        # Takes 3 streams (a, b and c)
+        # Outputs 2 streams.
+        # First (d) is interleaving of a and b.
+        # Second (e) is interleaving of a and b and c.  c is taken in
+        #     chunks of 2 which are reversed.
+        A = (1, 2, 3, 4, 5)
+        B = (11, 12, 13, 14, 15)
+        C = (99, 98, 97, 96, 95, 94, 93, 92, 91, 90)
+        expected_D = (1, 11, 2, 12, 3, 13, 4, 14, 5, 15)
+        expected_E = (1, 11, 98, 99, 2, 12, 96, 97, 3, 13, 94, 95,
+                      4, 14, 92, 93, 5, 15, 90, 91)
+        mapping = [[(0, 0), (1, 0)], # mapping to produce D
+                   [(0, 0), (1, 0), (2, 1), (2, 0)], # mapping to produce E
+                   ]
+        srcA = blocks.vector_source_f(A, False, 1)
+        srcB = blocks.vector_source_f(B, False, 1)
+        srcC = blocks.vector_source_f(C, False, 2)
+        vmap =  blocks.vector_map(gr.sizeof_int, (1, 1, 2), mapping)
+        dstD = blocks.vector_sink_f(2)
+        dstE = blocks.vector_sink_f(4)
+        self.tb.connect(srcA, (vmap, 0))
+        self.tb.connect(srcB, (vmap, 1)) 
+        self.tb.connect(srcC, (vmap, 2)) 
+        self.tb.connect((vmap, 0), dstD)
+        self.tb.connect((vmap, 1), dstE)
+        self.tb.run()
+        self.assertEqual(expected_D, dstD.data())
+        self.assertEqual(expected_E, dstE.data())
+
+if __name__ == '__main__':
+    gr_unittest.run(test_vector_map, "test_vector_map.xml")
+
diff --git a/gr-blocks/swig/blocks_swig.i b/gr-blocks/swig/blocks_swig.i
index 41202bb4b1..37d9c251ae 100644
--- a/gr-blocks/swig/blocks_swig.i
+++ b/gr-blocks/swig/blocks_swig.i
@@ -30,6 +30,9 @@
 
 %include <gr_endianness.h>
 
+%template() std::vector<size_t>;
+%template() std::vector< std::vector< std::vector<size_t> > >;
+
 %{
 #include "blocks/add_ff.h"
 #include "blocks/add_ss.h"
@@ -124,9 +127,12 @@
 #include "blocks/mute_ff.h"
 #include "blocks/mute_cc.h"
 #include "blocks/nlog10_ff.h"
+#include "blocks/nop.h"
 #include "blocks/not_bb.h"
 #include "blocks/not_ss.h"
 #include "blocks/not_ii.h"
+#include "blocks/null_sink.h"
+#include "blocks/null_source.h"
 #include "blocks/patterned_interleaver.h"
 #include "blocks/pack_k_bits_bb.h"
 #include "blocks/packed_to_unpacked_bb.h"
@@ -190,6 +196,7 @@
 #include "blocks/unpacked_to_packed_ss.h"
 #include "blocks/unpacked_to_packed_ii.h"
 #include "blocks/vco_f.h"
+#include "blocks/vector_map.h"
 #include "blocks/vector_to_stream.h"
 #include "blocks/vector_to_streams.h"
 #include "blocks/vector_insert_b.h"
@@ -307,9 +314,12 @@
 %include "blocks/mute_ff.h"
 %include "blocks/mute_cc.h"
 %include "blocks/nlog10_ff.h"
+%include "blocks/nop.h"
 %include "blocks/not_bb.h"
 %include "blocks/not_ss.h"
 %include "blocks/not_ii.h"
+%include "blocks/null_sink.h"
+%include "blocks/null_source.h"
 %include "blocks/probe_signal_b.h"
 %include "blocks/probe_signal_s.h"
 %include "blocks/probe_signal_i.h"
@@ -373,6 +383,7 @@
 %include "blocks/unpacked_to_packed_ss.h"
 %include "blocks/unpacked_to_packed_ii.h"
 %include "blocks/vco_f.h"
+%include "blocks/vector_map.h"
 %include "blocks/vector_to_stream.h"
 %include "blocks/vector_to_streams.h"
 %include "blocks/vector_insert_b.h"
@@ -488,9 +499,12 @@ GR_SWIG_BLOCK_MAGIC2(blocks, mute_ii);
 GR_SWIG_BLOCK_MAGIC2(blocks, mute_ff);
 GR_SWIG_BLOCK_MAGIC2(blocks, mute_cc);
 GR_SWIG_BLOCK_MAGIC2(blocks, nlog10_ff);
+GR_SWIG_BLOCK_MAGIC2(blocks, nop);
 GR_SWIG_BLOCK_MAGIC2(blocks, not_bb);
 GR_SWIG_BLOCK_MAGIC2(blocks, not_ss);
 GR_SWIG_BLOCK_MAGIC2(blocks, not_ii);
+GR_SWIG_BLOCK_MAGIC2(blocks, null_sink);
+GR_SWIG_BLOCK_MAGIC2(blocks, null_source);
 GR_SWIG_BLOCK_MAGIC2(blocks, patterned_interleaver);
 GR_SWIG_BLOCK_MAGIC2(blocks, pack_k_bits_bb);
 GR_SWIG_BLOCK_MAGIC2(blocks, packed_to_unpacked_bb);
@@ -554,6 +568,7 @@ GR_SWIG_BLOCK_MAGIC2(blocks, unpacked_to_packed_bb);
 GR_SWIG_BLOCK_MAGIC2(blocks, unpacked_to_packed_ss);
 GR_SWIG_BLOCK_MAGIC2(blocks, unpacked_to_packed_ii);
 GR_SWIG_BLOCK_MAGIC2(blocks, vco_f);
+GR_SWIG_BLOCK_MAGIC2(blocks, vector_map);
 GR_SWIG_BLOCK_MAGIC2(blocks, vector_to_stream);
 GR_SWIG_BLOCK_MAGIC2(blocks, vector_to_streams);
 GR_SWIG_BLOCK_MAGIC2(blocks, vector_insert_b);
-- 
cgit v1.2.3