code: def process(self, pair):
          # TODO: check docstring
          
          a, b = pair
  
          new_solution = self.clone()
  
          i, j = new_solution.get_pair((a, b))
  
          route_i = i.route_allocation()
          route_j = j.route_allocation()
  
          inserted = False
  
          if ((route_i is not None and route_j is not None) and (route_i != route_j)):
              if route_i._nodes.index(i) == 0 and route_j._nodes.index(j) == len(route_j._nodes) - 1:
                  if route_j.can_allocate(route_i._nodes):
                      route_j.allocate(route_i._nodes)
  
                      if i.route_allocation() != j.route_allocation():
                          raise Exception('wtf')
  
                      inserted = True
              elif route_j._nodes.index(j) == 0 and route_i._nodes.index(i) == len(route_i._nodes) - 1:
                  if route_i.can_allocate(route_j._nodes):
                      route_i.allocate(route_j._nodes)
  
                      if i.route_allocation() != j.route_allocation():
                          raise Exception('wtf j')
  
                      inserted = True
  
          new_solution._routes = [route for route in new_solution._routes if route._nodes]
  
          return new_solution, inserted
docs: Processes a pair of nodes into the current solution
  
          MUST CREATE A NEW INSTANCE, NOT CHANGE ANY INSTANCE ATTRIBUTES
  
          Returns a new instance (deep copy) of self object
          
          Args
          ----
          pair : type
              description
              
          Returns
          -------
          type
              Description (Copy of self?)