You should create an `ScmCommands` interface like this: public interface ScmCommands { public String[] getRevisionCommand(); public List<String[]> getDiffCommand(); public List<String[]> getCodebaseInfoCommand(); } and two implementations: `SvnCommands`, `GitCommands`. It would improve type safety a lot. (With a `Map<String, Object>` you usually have to cast the values which is error-prone). Furthermore, it eliminates the magic constants. It's easy to call `Map.get()` with a mistyped key. With the interface the compiler warns you if the method name is wrong. --- Edit: I've changed the return types. Sample implementations are the following: public class GitCommands implements ScmCommands { private static final String GIT_COMMAND = "git"; public GitCommands() { } @Override public String[] getRevisionCommand() { return new String[] { GIT_COMMAND, "rev-parse", "HEAD" }; } @Override public List<String[]> getDiffCommand() { final List<String[]> result = new ArrayList<String[]>(); result.add(new String[] { GIT_COMMAND, "diff", "HEAD" }); result.add(new String[] { GIT_COMMAND, "diff", "HEAD", "--no-prefix" }); return result; } @Override public List<String[]> getCodebaseInfoCommand() { final List<String[]> result = new ArrayList<String[]>(); result.add(new String[] { GIT_COMMAND, "branch", "-v" }); result.add(new String[] { GIT_COMMAND, "remote", "-v" }); result.add(new String[] { GIT_COMMAND, "log", "--max-count=1" }); result.add(new String[] { GIT_COMMAND, "status" }); return result; } } <!-- magic --> public class SvnCommands implements ScmCommands { private static final String SVN_COMMAND = "svn"; public SvnCommands() { } @Override public String[] getRevisionCommand() { return new String[] { SVN_COMMAND, "info" }; } @Override public List<String[]> getDiffCommand() { final List<String[]> result = new ArrayList<String[]>(); result.add(new String[] {SVN_COMMAND, "diff"}); return result; } @Override public List<String[]> getCodebaseInfoCommand() { final List<String[]> result = new ArrayList<String[]>(); result.add(new String[] { SVN_COMMAND, "status" }); return result; } } It fits well to `ProcessBuilder` but I'd consider extracting out all SCM related methods to an interface (for example `Scm`), and move the code to SCM-specific classes which implement the `Scm` interface, like `GitScm`, `SubversionScm` etc. Calling command line executables doesn't [smell](http://en.wikipedia.org/wiki/Code_smell) good, maybe it would be better to use native Subversion and Git Java libraries.