Make a copy of this runnable.

        @return: Copy of this runnable.
        @rtype: lems.sim.runnable.Runnable

def copy(self):
        """
        Make a copy of this runnable.

        @return: Copy of this runnable.
        @rtype: lems.sim.runnable.Runnable
        """
        if self.debug: print("Coping....."+self.id)
        r = Runnable(self.id, self.component, self.parent)
        copies = dict()

        # Copy simulation time parameters
        r.time_step = self.time_step
        r.time_completed = self.time_completed
        r.time_total = self.time_total

        # Plasticity and state stack (?)
        r.plastic = self.plastic
        r.state_stack = Stack()
        
        # Copy variables (GG - Faster using the add_* methods?)
        for v in self.instance_variables:
            r.instance_variables.append(v)
            r.__dict__[v] = self.__dict__[v]
            r.__dict__[v + '_shadow'] = self.__dict__[v + '_shadow']
        
        for v in self.derived_variables:
            r.derived_variables.append(v)
            r.__dict__[v] = self.__dict__[v]
            r.__dict__[v + '_shadow'] = self.__dict__[v + '_shadow']
        
        # Copy array elements
        for child in self.array:
            child_copy = child.copy()
            child_copy.parent = r
            r.array.append(child_copy)
            copies[child.uid] = child_copy
            
        # Copy attachment def
        for att in self.attachments:
            atn = self.attachments[att]
            r.attachments[att] = atn
            r.__dict__[atn] = []

        # Copy children
        for uid in self.uchildren:
            child = self.uchildren[uid]
            child_copy = child.copy()
            child_copy.parent = r
            copies[child.uid] = child_copy
            
            r.add_child(child_copy.id, child_copy)

            # For typerefs
            try:
                idx = [k for k in self.__dict__ if self.__dict__[k] == child][0]
                r.__dict__[idx] = child_copy
            except:
                pass

            # For groups and attachments:
            try:
                idx = [k for k in self.__dict__ if child in self.__dict__[k]][0]
                if idx not in r.__dict__:
                    r.__dict__[idx] = []
                r.__dict__[idx].append(child_copy)

            except:
                pass
               
        # Copy event ports
        for port in self.event_in_ports:
            r.event_in_ports.append(port)
            r.event_in_counters[port] = 0

        for port in self.event_out_ports:
            r.event_out_ports.append(port)
            r.event_out_callbacks[port] = self.event_out_callbacks[port]
        
        for ec in r.component.structure.event_connections:
            if self.debug: print("--- Fixing event_connection: %s in %s"%(ec.toxml(), id(r)))
            
            source = r.parent.resolve_path(ec.from_)
            target = r.parent.resolve_path(ec.to)
            
            if ec.receiver:
                # Will throw error...
                receiver_template = self.build_runnable(ec.receiver, target)                                
                #receiver = copy.deepcopy(receiver_template)
                receiver = receiver_template.copy()
                receiver.id = "{0}__{1}__".format(component.id,
                                                  receiver_template.id)

                if ec.receiver_container:
                    target.add_attachment(receiver, ec.receiver_container)
                target.add_child(receiver_template.id, receiver)
                target = receiver
            else:
                source = r.resolve_path(ec.from_)
                target = r.resolve_path(ec.to)

            source_port = ec.source_port
            target_port = ec.target_port

            if not source_port:
                if len(source.event_out_ports) == 1:
                    source_port = source.event_out_ports[0]
                else:
                    raise SimBuildError(("No source event port "
                                         "uniquely identifiable"
                                         " in '{0}'").format(source.id))
            if not target_port:
                if len(target.event_in_ports) == 1:
                    target_port = target.event_in_ports[0]
                else:
                    raise SimBuildError(("No destination event port "
                                         "uniquely identifiable "
                                         "in '{0}'").format(target))
             
            if self.debug: print("register_event_out_callback\n   Source: %s, %s (port: %s) \n   -> %s, %s (port: %s)"%(source, id(source), source_port, target, id(target), target_port))
            source.register_event_out_callback(\
                source_port, lambda: target.inc_event_in(target_port))
            
        
            

        # Copy methods
        if getattr(self, "update_kinetic_scheme", None): r.update_kinetic_scheme = self.update_kinetic_scheme
        if getattr(self, "run_startup_event_handlers", None): r.run_startup_event_handlers = self.run_startup_event_handlers
        if getattr(self, "run_preprocessing_event_handlers", None): r.run_preprocessing_event_handlers = self.run_preprocessing_event_handlers
        if getattr(self, "run_postprocessing_event_handlers", None): r.run_postprocessing_event_handlers = self.run_postprocessing_event_handlers
        
        if getattr(self, "update_state_variables", None): r.update_state_variables = self.update_state_variables
        if getattr(self, "update_derived_variables", None): r.update_derived_variables = self.update_derived_variables
        #r.update_shadow_variables = self.update_shadow_variables
        if getattr(self, "update_derived_parameters", None): r.update_derived_parameters = self.update_derived_parameters

        for rn in self.regimes:
            r.add_regime(self.regimes[rn])
        r.current_regime = self.current_regime

        # Copy groups
        for gn in self.groups:
            g = self.__dict__[gn]
            for c in g:
                if c.uid in copies:
                    r.add_child_to_group(gn, copies[c.uid])
                else:
                    c2 = c.copy()
                    c2.parent = r
                    copies[c.uid] = c2
                    r.add_child_to_group(gn, c2)
                    

        # Copy remaining runnable references.
        for k in self.__dict__:
            if k == 'parent':
                continue
            c = self.__dict__[k]
            if isinstance(c, Runnable):
                if c.uid in copies:
                    r.__dict__[k] = copies[c.uid]
                else:
                    c2 = c.copy()
                    c2.parent = r
                    copies[c.uid] = c2
                    r.__dict__[k] = c2
           
        # Copy text fields
        for k in self.__dict__:          
            if not k in r.__dict__:
                c = self.__dict__[k]
                if self.debug: print("Adding remaining field: %s = %s"%(k,c))
                r.__dict__[k] = c
                
        if self.debug:
            print('########################################')
            keys = list(self.__dict__.keys())
            keys.sort()
            print(len(keys))
            for k in keys:
                print(k, self.__dict__[k])
            print('----------------------------------------')
            keys = list(r.__dict__.keys())
            keys.sort()
            print(len(keys))
            for k in keys:
                print(k, r.__dict__[k])
            print('########################################')
            print('')
            print('')
            print('')
            print('')
            
        if self.debug: print("Finished coping..."+self.id)
        
        return r