def _process_routers(self, routers, removed_routers,
                         device_id=None, all_routers=False):
        """Process the set of routers.

        Iterating on the set of routers received and comparing it with the
        set of routers already in the routing service helper, new routers
        which are added are identified. Before processing check the
        reachability (via ping) of hosting device where the router is hosted.
        If device is not reachable it is backlogged.

        For routers which are only updated, call `_process_router()` on them.

        When all_routers is set to True (because of a full sync),
        this will result in the detection and deletion of routers which
        have been removed.

        Whether the router can only be assigned to a particular hosting device
        is decided and enforced by the plugin. No checks are done here.

        :param routers: The set of routers to be processed
        :param removed_routers: the set of routers which where removed
        :param device_id: Id of the hosting device
        :param all_routers: Flag for specifying a partial list of routers
        :return: None
        """
        try:
            ids_previously_hosted_routers = (
                set(r_id for r_id, rdata in self.router_info.items()
                    if rdata.router.get('hosting_device',
                                        {}).get('id') == device_id))

            if all_routers:
                prev_router_ids = ids_previously_hosted_routers
            else:
                prev_router_ids = (ids_previously_hosted_routers &
                                   set([router['id'] for router in routers]))
            cur_router_ids = set()
            deleted_routerids_list = []

            for r in routers:
                if not r['admin_state_up']:
                        continue
                cur_router_ids.add(r['id'])

            # identify list of routers(ids) that no longer exist
            for router_id in prev_router_ids - cur_router_ids:
                deleted_routerids_list.append(router_id)
            if removed_routers:
                self._adjust_router_list_for_global_router(removed_routers)
                for router in removed_routers:
                    deleted_routerids_list.append(router['id'])

            self._adjust_router_list_for_global_router(routers)
            # First process create/updated routers
            for r in routers:
                LOG.debug("Processing router[id:%(id)s, role:%(role)s]",
                          {'id': r['id'], 'role': r[ROUTER_ROLE_ATTR]})
                if r['id'] in deleted_routerids_list:
                    continue
                if r['status'] == c_constants.ROUTER_INFO_INCOMPLETE:
                    # The plugin could not fill in all the info due to
                    # timing and db settling down. So put this router
                    # back in updated_routers, we will pull again on the
                    # sync time.
                    LOG.debug("Router: %(id)s INFO_INCOMPLETE",
                              {'id': r['id']})
                    self._update_updated_routers_cache([r['id']])
                    continue
                try:
                    if not r['admin_state_up']:
                        continue
                    cur_router_ids.add(r['id'])
                    hd = r['hosting_device']
                    if not self._dev_status.is_hosting_device_reachable(hd):
                        LOG.info("Router: %(id)s is on an unreachable "
                                 "hosting device. ", {'id': r['id']})
                        continue
                    if r['id'] not in self.router_info:
                        self._router_added(r['id'], r)
                    ri = self.router_info[r['id']]
                    ri.router = r
                    self._process_router(ri)
                except ncc_errors.SessionCloseError as e:
                    LOG.exception(
                        "ncclient Unexpected session close %s", e)
                    if not self._dev_status.is_hosting_device_reachable(
                        r['hosting_device']):
                        LOG.debug("Lost connectivity to hosting device %s" %
                                  r['hosting_device']['id'])
                        # Will rely on heartbeat to detect hd state
                        # and schedule resync when hd comes back
                    else:
                        # retry the router update on the next pass
                        self._update_updated_routers_cache([r['id']])
                        LOG.debug("RETRY_RTR_UPDATE %s" % (r['id']))

                    continue
                except KeyError as e:
                    LOG.exception("Key Error, missing key: %s", e)
                    self._update_updated_routers_cache([r['id']])
                    continue
                except cfg_exceptions.DriverException as e:
                    LOG.exception("Driver Exception on router:%(id)s. "
                                  "Error is %(e)s", {'id': r['id'],
                                                     'e': e})
                    self._update_updated_routers_cache([r['id']])
                    continue
                LOG.debug("Done processing router[id:%(id)s, role:%(role)s]",
                          {'id': r['id'], 'role': r[ROUTER_ROLE_ATTR]})
            # Finally process removed routers
            for router_id in deleted_routerids_list:
                LOG.debug("Processing deleted router:%s", router_id)
                self._router_removed(router_id)
        except Exception:
            LOG.exception("Exception in processing routers on device:%s",
                          device_id)
            self.sync_devices.add(device_id)