private TopLevelItem cloneJob(AbstractProject jobToClone, String newName, Map<String, String> variableValues) throws IOException, ServletException {
        TopLevelItem result = null;

        TemplateBuildWrapper templateBuildWrapper = BuildWrapperUtils.findBuildWrapper(TemplateBuildWrapper.class, jobToClone);
        if (templateBuildWrapper != null) {
            if (jobToClone instanceof TopLevelItem) {
                @SuppressWarnings("RedundantCast") //Need to cast to get the generics to work properly
                        Class<? extends TopLevelItem> jobClass = ((TopLevelItem) jobToClone).getClass();
                TopLevelItem newJob = Jenkins.getInstance().createProject(jobClass, newName);

                if (newJob != null && newJob instanceof BuildableItemWithBuildWrappers) {
                    // If the target job (jobToClone) is actually a template, let's implement it rather than just clone it.

                    BuildableItemWithBuildWrappers buildable = (BuildableItemWithBuildWrappers) newJob;
                    DescribableList<BuildWrapper, Descriptor<BuildWrapper>> buildWrappersList = buildable.getBuildWrappersList();
                    TemplateBuildWrapper toRemove = BuildWrapperUtils.findBuildWrapper(TemplateBuildWrapper.class, buildable);
                    buildWrappersList.remove(toRemove);

                    String variablesAsPropertiesFile = squashVariables(variableValues);
                    ImplementationBuildWrapper implementationBuildWrapper = new ImplementationBuildWrapper(jobToClone.getName(), newJob.getName(), variablesAsPropertiesFile);
                    buildWrappersList.add(implementationBuildWrapper);
                    newJob.save();
                    result = newJob;
                    implementationBuildWrapper.sync();

                }
            }
        }

        if (result == null) {
            //clone
            result = (TopLevelItem) Jenkins.getInstance().copy(jobToClone, newName);
        }
        return result;
    }