use(...middleware) {
    const router = this;
    let path;

    // support array of paths
    if (Array.isArray(middleware[0]) && typeof middleware[0][0] === 'string') {
      const arrPaths = middleware[0];
      for (const p of arrPaths) {
        router.use.apply(router, [p, ...middleware.slice(1)]);
      }

      return this;
    }

    const hasPath = typeof middleware[0] === 'string';
    if (hasPath) path = middleware.shift();

    for (const m of middleware) {
      if (m.router) {
        const cloneRouter = Object.assign(
          Object.create(Router.prototype),
          m.router,
          {
            stack: [...m.router.stack]
          }
        );

        for (let j = 0; j < cloneRouter.stack.length; j++) {
          const nestedLayer = cloneRouter.stack[j];
          const cloneLayer = Object.assign(
            Object.create(Layer.prototype),
            nestedLayer
          );

          if (path) cloneLayer.setPrefix(path);
          if (router.opts.prefix) cloneLayer.setPrefix(router.opts.prefix);
          router.stack.push(cloneLayer);
          cloneRouter.stack[j] = cloneLayer;
        }

        if (router.params) {
          const routerParams = Object.keys(router.params);
          for (const key of routerParams) {
            cloneRouter.param(key, router.params[key]);
          }
        }
      } else {
        const keys = [];
        pathToRegexp(router.opts.prefix || '', keys);
        const routerPrefixHasParam = Boolean(
          router.opts.prefix && keys.length > 0
        );
        router.register(path || '([^/]*)', [], m, {
          end: false,
          ignoreCaptures: !hasPath && !routerPrefixHasParam
        });
      }
    }

    return this;
  }
Use given middleware.

Middleware run in the order they are defined by `.use()`. They are invoked
sequentially, requests start at the first middleware and work their way
"down" the middleware stack.

@example

```javascript
// session middleware will run before authorize
router
  .use(session())
  .use(authorize());

// use middleware only with given path
router.use('/users', userAuth());

// or with an array of paths
router.use(['/users', '/admin'], userAuth());

app.use(router.routes());
```

@param {String=} path
@param {Function} middleware
@param {Function=} ...
@returns {Router}