### Question:
ViewHandlerImpl extends ViewHandler { @Override public String getBookmarkableURL(FacesContext context, String viewId, Map<String, List<String>> parameters, boolean includeViewParams) { Map<String, List<String>> viewParameters; if (includeViewParams) { viewParameters = getViewParameterList(context, viewId, parameters); } else { viewParameters = parameters; } String actionEncodedViewId = getViewHandler(context).getActionURL(context, viewId); ExternalContext externalContext = context.getExternalContext(); String bookmarkEncodedURL = externalContext.encodeBookmarkableURL(actionEncodedViewId, viewParameters); return externalContext.encodeActionURL(bookmarkEncodedURL); } ViewHandlerImpl(); static ViewHandler getViewHandler(FacesContext facesContext); @Override String deriveViewId(FacesContext context, String rawViewId); @Override String deriveLogicalViewId(FacesContext context, String rawViewId); @Override String getBookmarkableURL(FacesContext context, String viewId,
            Map<String, List<String>> parameters, boolean includeViewParams); @Override String getRedirectURL(FacesContext context, String viewId,
            Map<String, List<String>> parameters, boolean includeViewParams); @Override ViewDeclarationLanguage getViewDeclarationLanguage(
            FacesContext context, String viewId); @Override void initView(FacesContext context); @Override Locale calculateLocale(FacesContext facesContext); @Override String calculateRenderKitId(FacesContext facesContext); @Override UIViewRoot createView(FacesContext context, String viewId); @Override String getActionURL(FacesContext context, String viewId); @Override String getResourceURL(FacesContext facesContext, String path); @Override void renderView(FacesContext context, UIViewRoot viewToRender); @Override UIViewRoot restoreView(FacesContext context, String viewId); @Override void writeState(FacesContext context); @Override void addProtectedView(String urlPattern); @Override boolean removeProtectedView(String urlPattern); @Override Set<String> getProtectedViewsUnmodifiable(); void setViewIdSupport(ViewIdSupport viewIdSupport); @Override Stream<String> getViews(FacesContext facesContext, String path, int maxDepth, ViewVisitOption... options); @Override String getWebsocketURL(FacesContext context, String channelAndToken); static final String FORM_STATE_MARKER; }### Answer:
@Test @SuppressWarnings("unchecked") public void testGetBookmarkableURLDoesNotChangeParametersMap() { request.setPathElements("/", null, "/newview.jsf", null); externalContext.getApplicationMap().put("paramvalue", "paramvalue"); Map<String, List<String>> parameters = new HashMap<String, List<String>>(); parameters.put("key1", Collections.unmodifiableList(Arrays.asList("value11", "value12"))); parameters.put("key2", Collections.unmodifiableList(Arrays.asList("value2"))); parameters = Collections.unmodifiableMap(parameters); String url = null; try { url = _viewHandler.getBookmarkableURL(facesContext, "/newview.xhtml", parameters, true); } catch (UnsupportedOperationException uoe) { Assert.fail("ViewHandler.getBookmarkableURL() must not change the parameter Map!"); } Assert.assertTrue(url.contains("key1=value11")); Assert.assertTrue(url.contains("key1=value12")); Assert.assertTrue(url.contains("key2=value2")); Assert.assertTrue(url.contains("myparam=paramvalue")); }