@NonNull
    public final Launcher decorateByEnv(@NonNull EnvVars _env) {
        final EnvVars env = new EnvVars(_env);
        final Launcher outer = this;
        return new Launcher(outer) {
            @Override
            public boolean isUnix() {
                return outer.isUnix();
            }

            @Override
            public Proc launch(ProcStarter starter) throws IOException {
                EnvVars e = new EnvVars(env);
                if (starter.envs != null) {
                    for (String env : starter.envs) {
                        e.addLine(env);
                    }
                }
                starter.envs = Util.mapToEnv(e);
                return outer.launch(starter);
            }

            @Override
            public Channel launchChannel(String[] cmd, OutputStream out, FilePath workDir, Map<String, String> envVars) throws IOException, InterruptedException {
                EnvVars e = new EnvVars(env);
                e.putAll(envVars);
                return outer.launchChannel(cmd, out, workDir, e);
            }

            @Override
            public void kill(Map<String, String> modelEnvVars) throws IOException, InterruptedException {
                outer.kill(modelEnvVars);
            }
        };
    }
@Issue("JENKINS-15733")
    @Test public void decorateByEnv() throws Exception {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        TaskListener l = new StreamBuildListener(baos, Charset.defaultCharset());
        Launcher base = new Launcher.LocalLauncher(l);
        EnvVars env = new EnvVars("key1", "val1");
        Launcher decorated = base.decorateByEnv(env);
        int res = decorated.launch().envs("key2=val2").cmds(Functions.isWindows() ? new String[] {"cmd", "/q", "/c", "echo %key1% %key2%"} : new String[] {"sh", "-c", "echo $key1 $key2"}).stdout(l).join();
        String log = baos.toString(Charset.defaultCharset());
        assertEquals(log, 0, res);
        assertTrue(log, log.contains("val1 val2"));
    }