def search(self, source, destination = None, display = None,
               component = None, q = None,
               algo = 'DFS', reverse = False, **kargs):
        '''
        API: search(self, source, destination = None, display = None,
               component = None, q = Stack(),
               algo = 'DFS', reverse = False, **kargs)
        Description:
        Generic search method. Changes behavior (dfs,bfs,dijkstra,prim)
        according to algo argument.
        if destination is not specified:
           This method determines all nodes reachable from "source" ie. creates
           precedence tree and returns it (dictionary).
        if destionation is given:
           If there exists a path from "source" to "destination" it will return
           list of the nodes is this path. If there is no such path, it will
           return the precedence tree constructed from source (dictionary).
        Optionally, it marks all nodes reachable from "source" with a component
        number. The variable "q" determines the order in which the nodes are
        searched.
        Input:
            source: Search starts from node with this name.
            destination: Destination node name.
            display: Display method.
            algo: Algortihm that specifies search. Available algortihms are
            'DFS', 'BFS', 'Dijkstra' and 'Prim'.
            reverse: Search goes in reverse arc directions if True.
            kargs: Additional keyword arguments.
        Post:
            Nodes will have 'component' attribute that will have component
            number as value (if component argument provided). Color attribute
            of nodes and edges may change.
        Return:
            Returns predecessor tree in dictionary form if destination is
            not specified, returns list of node names in the path from source
            to destionation if destionation is specified and there is a path.
            If there is no path returns predecessor tree in dictionary form.
            See description section.
        '''
        if display == None:
            display = self.attr['display']
        else:
            self.set_display_mode(display)
        if algo == 'DFS':
            if q is None:
                q = Stack()
            self.get_node(source).set_attr('component', component)
        elif algo == 'BFS' or algo == 'UnweightedSPT':
            if q is None:
                q = Queue()
            self.get_node(source).set_attr('component', component)
        elif algo == 'Dijkstra' or algo == 'Prim':
            if q is None:
                q = PriorityQueue()
        else:
            print("Unknown search algorithm...exiting")
            return
        neighbors = self.neighbors
        if self.graph_type == DIRECTED_GRAPH and reverse:
            neighbors = self.in_neighbors
        for i in self.get_node_list():
            self.get_node(i).set_attr('label', '-')
            self.get_node(i).attr.pop('priority', None)
            self.get_node(i).set_attr('distance', None)
            self.get_node(i).set_attr('color', 'black')
            for j in neighbors[i]:
                if reverse:
                    self.set_edge_attr(j, i, 'color', 'black')
                else:
                    self.set_edge_attr(i, j, 'color', 'black')
        self.display()
        pred = {}
        self.process_edge_search(None, source, pred, q, component, algo,
                                 **kargs)
        found = True
        if source != destination:
            found = False
        while not q.isEmpty() and not found:
            current = q.peek()
            if self.get_node(current).get_attr('color') == 'green':
                q.remove(current)
                continue
            self.process_node_search(current, q, **kargs)
            self.get_node(current).set_attr('color', 'blue')
            if current != source:
                if reverse:
                    self.set_edge_attr(current, pred[current], 'color', 'green')
                else:
                    self.set_edge_attr(pred[current], current, 'color', 'green')
            if current == destination:
                found = True
                break
            self.display()
            for n in neighbors[current]:
                if self.get_node(n).get_attr('color') != 'green':
                    if reverse:
                        self.set_edge_attr(n, current, 'color', 'yellow')
                    else:
                        self.set_edge_attr(current, n, 'color', 'yellow')
                    self.display()
                    self.process_edge_search(current, n, pred, q, component,
                                             algo, **kargs)
                    if reverse:
                        self.set_edge_attr(n, current, 'color', 'black')
                    else:
                        self.set_edge_attr(current, n, 'color', 'black')
            q.remove(current)
            self.get_node(current).set_attr('color', 'green')
            self.display()
        if found:
            path = [destination]
            current = destination
            while current != source:
                path.insert(0, pred[current])
                current = pred[current]
            return path
        if destination == None:
            return pred
        else:
            return None
API: search(self, source, destination = None, display = None,
               component = None, q = Stack(),
               algo = 'DFS', reverse = False, **kargs)
        Description:
        Generic search method. Changes behavior (dfs,bfs,dijkstra,prim)
        according to algo argument.
        if destination is not specified:
           This method determines all nodes reachable from "source" ie. creates
           precedence tree and returns it (dictionary).
        if destionation is given:
           If there exists a path from "source" to "destination" it will return
           list of the nodes is this path. If there is no such path, it will
           return the precedence tree constructed from source (dictionary).
        Optionally, it marks all nodes reachable from "source" with a component
        number. The variable "q" determines the order in which the nodes are
        searched.
        Input:
            source: Search starts from node with this name.
            destination: Destination node name.
            display: Display method.
            algo: Algortihm that specifies search. Available algortihms are
            'DFS', 'BFS', 'Dijkstra' and 'Prim'.
            reverse: Search goes in reverse arc directions if True.
            kargs: Additional keyword arguments.
        Post:
            Nodes will have 'component' attribute that will have component
            number as value (if component argument provided). Color attribute
            of nodes and edges may change.
        Return:
            Returns predecessor tree in dictionary form if destination is
            not specified, returns list of node names in the path from source
            to destionation if destionation is specified and there is a path.
            If there is no path returns predecessor tree in dictionary form.
            See description section.