docs: private int scanURL(String url, User user, int maxChildren, boolean recurse, Context context, boolean subtreeOnly) throws ApiException {
  		log.debug("API Spider scanning url: " + url);
  
  		boolean useUrl = true;
  		if (url == null || url.isEmpty()) {
  			if (context == null || !context.hasNodesInContextFromSiteTree()) {
  				throw new ApiException(Type.MISSING_PARAMETER, PARAM_URL);
  			}
  			useUrl = false;
  		} else if (context != null && !context.isInContext(url)) {
  			throw new ApiException(Type.URL_NOT_IN_CONTEXT, PARAM_URL);
  		}
  
  		StructuralNode node = null;
  		URI startURI = null;
  		if (useUrl) {
  			try {
  				// Try to build uri
  				startURI = new URI(url, true);
  			} catch (URIException e) {
  				throw new ApiException(ApiException.Type.ILLEGAL_PARAMETER, PARAM_URL);
  			}
  			String scheme = startURI.getScheme();
  			if (scheme == null || (!scheme.equalsIgnoreCase("http") && !scheme.equalsIgnoreCase("https"))) {
  				throw new ApiException(ApiException.Type.ILLEGAL_PARAMETER, PARAM_URL);
  			}
  
  			node = getStartNode(startURI, recurse);
  		}
  		Target target = new Target();
  		if (useUrl && node != null) {
  			target.setStartNode(node);
  		}
  		target.setContext(context);
  		target.setRecurse(recurse);
  		
  		switch (Control.getSingleton().getMode()) {
  		case safe:
  			throw new ApiException(ApiException.Type.MODE_VIOLATION);
  		case protect:
  			if ((useUrl && !Model.getSingleton().getSession().isInScope(url))
  					|| (context != null && !context.isInScope())) {
  				throw new ApiException(ApiException.Type.MODE_VIOLATION);
  			}
  			// No problem
  			break;
  		case standard:
  			// No problem
  			break;
  		case attack:
  			// No problem
  			break;
  		}
  		
  		List<Object> objs = new ArrayList<>(4);
  		if (startURI != null) {
  			objs.add(startURI);
  			if (subtreeOnly) {
  				objs.add(new HttpPrefixFetchFilter(startURI));
  			}
  		}
  
  		if (maxChildren > 0) {
      		// Add the filters to filter on maximum number of children
      		MaxChildrenFetchFilter maxChildrenFetchFilter = new MaxChildrenFetchFilter();
      		maxChildrenFetchFilter.setMaxChildren(maxChildren);
      		maxChildrenFetchFilter.setModel(extension.getModel());
      		
      		MaxChildrenParseFilter maxChildrenParseFilter = new MaxChildrenParseFilter(extension.getMessages());
      		maxChildrenParseFilter.setMaxChildren(maxChildren);
      		maxChildrenParseFilter.setModel(extension.getModel());
  			objs.add(maxChildrenFetchFilter);
  			objs.add(maxChildrenParseFilter);
  		}
  		
  		return extension.startScan(target, user, objs.toArray(new Object[objs.size()]));
  	}