docs: 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