diff --git a/tools/oneclick/components/component.py b/tools/oneclick/components/component.py
new file mode 100644
index 0000000000000000000000000000000000000000..e0522bb6be03a989d42841c7413e6d3835bc2eed
--- /dev/null
+++ b/tools/oneclick/components/component.py
@@ -0,0 +1,460 @@
+import multiprocessing as mp
+import time
+import common as cm
+
+###############################################################################
+# Base classes
+###############################################################################
+
+class Signal(object):
+        def __init__(self, name, stype):
+            self.name = name
+            self.stype = stype
+            self.vhdl_signal_declaration = 'SIGNAL %s : %s;\n' %(name, stype)
+
+class StreamPort(object):
+    def __init__(self, component_name, name, mode, stream_index, data_width):
+        self.component_name = component_name
+
+        if stream_index != None:
+            self.name = name + '[' + str(stream_index) + ']'
+        else:
+            self.name = name
+
+        self.mode = mode
+        self.stream_index = stream_index
+        self.data_width = data_width
+        self.pipe_end = None
+
+        self.port_type = 't_dp_sosi'
+        self.signal = Signal(component_name+'_'+name, self.port_type)
+
+    #'>' operator: Connect
+    def __gt__(self, other):
+        return self.__connect__(other)
+
+    def __connect__(self, other):
+        if not(self.pipe_end == None):
+            # The pipe end is already assigned, this is the case for composite components that
+            # have wired their entity port to internal instance ports. 
+            # If self is a source port (mode='out'), this means that self.pipe_end is already occupied
+            # with a pipe sink end from which this entity port receives from an internal source entity.
+            # To make a connection between other and self, all we need to do is move the existing pipe's snk end
+            # from self to other. The source end remains connected to self's internal instance.
+            other.pipe_end = self.pipe_end
+        elif not(other.pipe_end == None):
+            # The pipe end is already assigned, this is the case for composite components that
+            # have wired their entity port to internal instance ports. 
+            # If other is a sink port (mode='in'), this means that other.pipe_end is already occupied
+            # with a pipe source end from which this entity port send to an internal sink entity.
+            # To make a connection between other and self, all we need to do is move the existing pipe's src end
+            # from other to self. The sink end remains connected to other's internal instance.
+            self.pipe_end = other.pipe_end
+        else:
+            snk_end, src_end = mp.Pipe(duplex=False)
+            self.pipe_end  = src_end
+            other.pipe_end = snk_end
+
+        return Connection( (self.component_name, self.name), (other.component_name, other.name) )
+
+    def send(self, item):
+        self.pipe_end.send(item) 
+
+    def recv(self):
+        while True:
+            try:
+                yield self.pipe_end.recv()
+            except EOFError:
+                break
+
+class StreamPortArray(list):
+    def __init__(self, component_name, name, mode, nof_streams, data_width):
+        list.__init__(self)
+        self.component_name = component_name
+        self.name = name
+        self.mode = mode
+        self.nof_streams = nof_streams
+        self.data_width = data_width
+        for stream_index in range(nof_streams):
+            self.append(StreamPort(component_name, name, mode, stream_index, data_width))
+
+        self.port_type = 't_dp_sosi_arr(%s-1 DOWNTO 0)' %nof_streams
+        self.signal = Signal(component_name+'_'+name, self.port_type)
+
+    #'>' operator: Connect
+    def __gt__(self, other):
+        return self.__connect__(other)
+
+    def __connect__(self, other):
+        for stream_port_self, stream_port_other in zip(self,other):
+            stream_port_self.__connect__(stream_port_other)
+        return Connection( (self.component_name, self.name), (other.component_name, other.name) )
+
+    def recv(self):
+        while True:
+            try:
+                items = []
+                for stream_port in self:
+                    items.append( stream_port.pipe_end.recv() )
+                yield items
+            except EOFError:
+                break
+
+class Connection():
+    def __init__(self, src, snk):
+        self.src_component_name = src[0]
+        self.src_port_name = src[1]
+        self.snk_component_name = snk[0]
+        self.snk_port_name = snk[1]
+        self.vhdl_assignment_left  = self.snk_component_name + '_' + self.snk_port_name
+        self.vhdl_assignment_right = self.src_component_name + '_' + self.src_port_name
+        self.vhdl_assignment_operator =  '<=' 
+        self.vhdl_assignment = self.vhdl_assignment_left + ' ' + self.vhdl_assignment_operator + ' ' + self.vhdl_assignment_right + ';\n'
+
+class Component(mp.Process):
+    def __init__(self, name, components=[], connections=[], inst_nr=None):
+        mp.Process.__init__(self)
+        if inst_nr != None:
+            self.name = name+'_'+str(inst_nr)
+        else:
+            self.name = name
+        self.inst_nr = inst_nr
+        self.file_name = self.name + '.vhd' # Overridden by component subclasses; these assign an existing file name.
+        self.ports = {}
+        self.components = components
+        self.connections = connections
+        self.temp_connections = []
+
+    def start_components(self):
+        if self.components == []:
+            # This is not a composite component but a base component, start this instance itself
+            self.start()
+        else:
+            # This is a composite component, start the internal instances
+            for component in self.components:
+                print 'Starting', component
+                component.start_components()
+
+    def terminate_components(self):
+        if self.components == []:
+            # This is not a composite component but a base component, terminate this instance itself
+            self.terminate()
+        else:
+            # This is a composite component, terminate the internal instances
+            for component in self.components:
+                print 'Terminating', component
+                component.terminate_components()
+
+    def run_time(self, time_sec):
+        self.start_components()
+        time.sleep(time_sec)
+        self.terminate_components()
+
+    def generate(self, target_file=None):
+        if self.components != []:
+            target_file = open(self.file_name, "w")
+            target_file.write('ASTRON HEADER\n')
+            target_file.write('INCLUDED LIBRARIES\n')
+            target_file.write('ENTITY DECLARATION\n')
+            target_file.write('ARCHITECTURE str OF %s IS\n' %self.name)
+            target_file.write('. CONSTANT DECLARATIONS\n')
+
+            # Get the signal declaration from each internal component's port object
+            for component in self.components:
+                for port_name, port in component.ports.iteritems():
+                    target_file.write(port.signal.vhdl_signal_declaration)
+
+            target_file.write('BEGIN\n')
+    
+            # Write this component's connections
+            for connection in cm.flatten(self.connections):
+#                print connection
+                target_file.write(connection.vhdl_assignment)
+      
+            # Iterate through internal components
+            for component in self.components:
+                component.generate()
+                target_file.write(component.get_vhdl_instance())
+    
+            target_file.write('END str\n')
+            target_file.close()
+
+    def get_vhdl_instance(self):
+        # Only base components have a pre-declared VHDL instance. Composites do not.
+        if hasattr(self, 'vhdl_instance'):
+            # I'm a base component...return my pre-declared VHDL instace string
+            return self.vhdl_instance
+        else:
+            # I'm a composite component. Create a VHDL instance here.
+            return 'A string that contains the %s VHDL instance\n' %self.name
+
+
+    def __set_port__(self, name, mode, dimensions):
+        """
+        Mode:
+        . 'in'
+        . 'out'
+        Dimension examples:
+        . 32 = 1 stream, 32b (sosi)
+        . (2,32) = 2 streams, 32b each (sosi_arr)
+        . (2,4,32) = 2 buses, 4 streams/bus, 32b/stream (sosi_2arr)
+        . (8,2,4,32) = 8 buses, 2 sub-buses/bus, 4 streams/sub-bus, 32b/stream (sosi_3arr)
+        """
+    def __set_port__(self, name, mode, dimensions):
+        if isinstance(dimensions, int):
+            # Single stream
+            self.ports[name] = StreamPort(self.name, name, mode, stream_index=None, data_width=dimensions)
+        elif len(dimensions)==2:
+            # Multi stream
+            self.ports[name] = StreamPortArray(self.name, name, mode, nof_streams=dimensions[0], data_width=dimensions[1])
+        elif len(dimensions)==3:
+            pass
+            # Multi bus, multi stream
+#            self.ports[name] = StreamPort2Array(self.name, name, mode, nof_buses=dimensions[0], nof_streams=dimensions[1], data_width=dimensions[2])
+
+    def set_input(self, name, dimensions):
+        self.__set_port__(name=name, mode='in', dimensions=dimensions)
+
+    def set_output(self, name, dimensions):
+        self.__set_port__(name=name, mode='out', dimensions=dimensions)
+
+    #'>' operator: Connect
+    def __gt__(self, other):
+        return self.__connect__(other)
+
+    def __connect__(self, other):
+        for port_name_self, port_self in self.ports.iteritems():
+            if port_self.mode == 'out':
+                 for port_name_other,port_other in other.ports.iteritems():
+                     if port_other.mode == 'in':
+                         if type(port_self)==type(port_other):
+                             # We want to be able to daisy chain components so we need to store intermediate results
+                             # in the component on the right.
+                             connection = port_self.__connect__(port_other)
+                             other.temp_connections.append(connection)
+        result = self.temp_connections+[connection]
+        self.temp_connections = []
+        return result
+
+
+###############################################################################
+# Component subclasses
+###############################################################################
+
+class SingleCounter(Component):
+    def __init__(self, data_width=32, inst_nr=None):
+        Component.__init__(self, inst_nr=inst_nr, name='SingleCounter')
+        self.vhdl_instance = 'A string that contains the SingleCounter VHDL instance\n'
+        self.set_output('src_out', data_width)
+    def run(self):
+        for value in xrange(10):
+            if self.inst_nr==None:
+                cnt_offset=0
+            else:
+                cnt_offset = self.inst_nr * 100
+            item = value + cnt_offset
+            print '[Counter] src', self.inst_nr, ': sending', item
+            # Offset sent value by 100 for each instance number increment
+            self.ports['src_out'].send(item) 
+
+class SinglePrinter(Component):
+    def __init__(self, data_width=32, inst_nr=None):
+        Component.__init__(self, inst_nr=inst_nr, name='SinglePrinter')
+        self.vhdl_instance = 'A string that contains the SinglePrinter VHDL instance\n'
+        self.set_input('snk_in', data_width)
+    def run(self):
+        for item in self.ports['snk_in'].recv():
+            print '[Printer] snk', self.inst_nr, ': receiving', item    
+
+
+class Counter(Component):
+    def __init__(self, nof_streams, data_width=32, inst_nr=None):
+        Component.__init__(self, inst_nr=inst_nr, name='Counter')
+        self.vhdl_instance = 'A string that contains the Counter VHDL instance\n'
+        self.set_output('src_out_arr', (nof_streams, data_width))
+    def run(self):
+        for value in xrange(10):
+            for src in self.ports['src_out_arr']:
+                item = value + src.stream_index*100
+                print '[Counter] src', src.stream_index, ': sending', item
+                # Offset sent value by 100 for each incremental stream
+                src.send(item) 
+
+class Through(Component):
+    def __init__(self, nof_streams, data_width=32, inst_nr=None):
+        Component.__init__(self, inst_nr=inst_nr, name='Through')
+        self.vhdl_instance = 'A string that contains the Through VHDL instance\n'
+        self.set_input('snk_in_arr', (nof_streams, data_width))
+        self.set_output('src_out_arr', (nof_streams, data_width))
+    def run(self):
+        for items in self.ports['snk_in_arr'].recv():
+            for item,src in zip(items, self.ports['src_out_arr']):
+                print '[Through] snk', src.stream_index, ': forwarding', item, 'to src', src.stream_index
+                src.send(item)
+
+class Printer(Component):
+    def __init__(self, nof_streams, data_width=32, inst_nr=None):
+        Component.__init__(self, inst_nr=inst_nr, name='Printer')
+        self.vhdl_instance = 'A string that contains the Printer VHDL instance\n'
+        self.set_input('snk_in_arr', (nof_streams, data_width))
+    def run(self):
+        for items in self.ports['snk_in_arr'].recv():
+            for item_index, item in enumerate(items):
+                print '[Printer] snk', item_index, ': receiving', item
+
+
+###############################################################################
+# Help function for keypress
+###############################################################################
+def press_enter():
+    try:
+        input("Press enter to continue")
+    except SyntaxError:
+        pass
+
+
+###############################################################################
+# Main
+###############################################################################
+
+print
+print '###############################################################################'
+print '# Example 1: connect ports component-wise'
+print '###############################################################################'
+print
+
+nof_streams = 3 
+
+a = Counter(nof_streams)
+b = Through(nof_streams)
+c = Printer(nof_streams)
+
+connections = [ a>b>c ]
+
+d = Component('my_component_1', [a,b,c], connections)
+
+d.run_time(1)
+d.generate()
+
+press_enter()
+
+print
+print '###############################################################################'
+print '# Example 2: connect ports array-wise'
+print '###############################################################################'
+print
+
+nof_streams = 3 
+
+a = Counter(nof_streams)
+b = Through(nof_streams)
+c = Printer(nof_streams)
+
+connections = []
+connections.append( a.ports['src_out_arr'] > b.ports['snk_in_arr' ] )
+connections.append(                          b.ports['src_out_arr']   > c.ports['snk_in_arr'] )
+
+d = Component('my_component_2', [a,b,c], connections)
+
+d.run_time(1)
+d.generate()
+
+press_enter()
+
+print
+print '###############################################################################'
+print '# Example 3: connect ports stream-wise (with stream 0 / stream 1 swap)'
+print '###############################################################################'
+print
+
+nof_streams = 3 
+
+a = Counter(nof_streams)
+b = Through(nof_streams)
+c = Printer(nof_streams)
+
+connections = []
+connections.append( a.ports['src_out_arr'][0] > b.ports['snk_in_arr' ][0] )
+connections.append( a.ports['src_out_arr'][1] > b.ports['snk_in_arr' ][1] )
+connections.append( a.ports['src_out_arr'][2] > b.ports['snk_in_arr' ][2] )
+connections.append(                             b.ports['src_out_arr'][1]   > c.ports['snk_in_arr'][0] ) # We're swapping streams 0 and 1 here
+connections.append(                             b.ports['src_out_arr'][0]   > c.ports['snk_in_arr'][1] ) # We're swapping streams 0 and 1 here
+connections.append(                             b.ports['src_out_arr'][2]   > c.ports['snk_in_arr'][2] )
+
+d = Component('my_component_3', [a,b,c], connections)
+
+d.run_time(1)
+d.generate()
+
+press_enter()
+
+print
+print '###############################################################################'
+print '# Example 4: Mix single and multi stream components'
+print '###############################################################################'
+print
+
+nof_streams = 1
+
+a = SingleCounter()
+b = Through(nof_streams)
+c = Printer(nof_streams)
+
+connections = []
+connections.append( a.ports['src_out'] > b.ports['snk_in_arr' ][0] )
+connections.append(                      b.ports['src_out_arr']      > c.ports['snk_in_arr'] )
+
+d = Component('my_component_4', [a,b,c], connections)
+
+d.run_time(1)
+d.generate()
+
+press_enter()
+
+print
+print '###############################################################################'
+print '# Example 5: Creating multi-instance composites from single stream components'
+print '# . We replace the Counter with a new component that instantiates 3 SingeCounters'
+print '# . We replace the Printer with a new component that instantiates 3 SingePrinters'
+print '###############################################################################'
+print
+
+nof_streams = 3
+data_width = 32
+
+# Create [nof_streams] SingleCounter instances
+a_list = []
+for i in range(nof_streams):
+    a_list.append(SingleCounter(inst_nr=i))
+# Create a new components wrapping these SingleCounter instances
+a_multi = Component('a_multi', a_list)
+# Declare the output of this new component
+a_multi.set_output('src_out_arr', (nof_streams, data_width))
+# Forward the SingleCounter outputs to the new component's output
+for i in range(nof_streams):
+    a_multi.components[i].ports['src_out'] > a_multi.ports['src_out_arr'][i]
+
+# Unchanged: the Through component
+b = Through(nof_streams)
+
+# Create [nof_streams] SinglePrinter instances
+c_list = []
+for i in range(nof_streams):
+    c_list.append(SinglePrinter(inst_nr=i))
+# Create a new components wrapping these SinglePrinter instances
+c_multi = Component('c_multi', c_list)
+# Declare the input of this new component
+c_multi.set_input('snk_in_arr', (nof_streams, data_width))
+# Forward the new component's input to the SinglePrinter inputs
+for i in range(nof_streams):
+    c_multi.ports['snk_in_arr'][i] > c_multi.components[i].ports['snk_in']
+
+# Continue as before (in the other examples)
+connections = [ a_multi>b>c_multi ]
+
+d = Component('my_component_5', [a_multi,b,c_multi], connections)
+
+d.run_time(1)
+d.generate()
+
+