code: package org.applause.lang.ui.wizard;
  
  import java.io.File;
  import java.io.FileOutputStream;
  import java.io.IOException;
  import java.io.InputStream;
  import java.lang.reflect.InvocationTargetException;
  import java.util.List;
  import java.util.zip.ZipEntry;
  import java.util.zip.ZipInputStream;
  
  import org.apache.commons.io.FileUtils;
  import org.apache.commons.io.IOUtils;
  import org.apache.commons.lang.StringUtils;
  import org.applause.lang.ui.builder.MobilePlatform;
  import org.eclipse.core.resources.IFile;
  import org.eclipse.core.resources.IFolder;
  import org.eclipse.core.resources.IProject;
  import org.eclipse.core.resources.IResource;
  import org.eclipse.core.runtime.CoreException;
  import org.eclipse.core.runtime.IProgressMonitor;
  import org.eclipse.core.runtime.SubMonitor;
  import org.eclipse.emf.ecore.resource.impl.ExtensibleURIConverterImpl;
  import org.eclipse.xtext.ui.util.PluginProjectFactory;
  import org.eclipse.xtext.ui.util.ProjectFactory;
  import org.eclipse.xtext.ui.wizard.AbstractProjectCreator;
  import org.eclipse.xtext.util.StringInputStream;
  
  import com.google.common.collect.ImmutableList;
  import com.google.inject.Inject;
  import com.google.inject.Provider;
  
  public class CustomApplauseProjectCreator extends AbstractProjectCreator {
  
  	private static final String MODEL_ROOT = "model";
  	private static final List<String> ALL_FOLDERS = ImmutableList.of();
  	
  	@Inject
  	private Provider<PluginProjectFactory> projectFactoryProvider;
  	
  	@Inject
  	private Provider<ProjectFactory> platformProjectFactoryProvider;
  
  	@Override
  	protected ProjectFactory createProjectFactory() {
  		return projectFactoryProvider.get();	
  	}
  	
  	protected ProjectFactory createPlatformProjectFactory() {
  		return platformProjectFactoryProvider.get();
  	}
  
  	@Override
  	protected String getModelFolderName() {
  		return MODEL_ROOT;
  	}
  
  	@Override
  	protected List<String> getAllFolders() {
  		return ALL_FOLDERS;
  	}
  	
  	protected ApplauseDslProjectInfo getApplauseProjectInfo() {
  		return (ApplauseDslProjectInfo)getProjectInfo();
  	}
  	
  	@Override
  	protected void execute(final IProgressMonitor monitor) throws CoreException, InvocationTargetException,
  			InterruptedException {
  		SubMonitor subMonitor = SubMonitor.convert(
  				monitor, 
  				getCreateModelProjectMessage(),
  				getApplauseProjectInfo().numberOfPlatforms() + 1);
  
  		IProject project = createModelProject(subMonitor.newChild(1));
  		for(MobilePlatform platform : getApplauseProjectInfo().getSelectedPlatforms()) {
  			createPlatformProject(platform, subMonitor.newChild(1));
  		}
  
  		IFile modelFile = getModelFile(project);
  		setResult(modelFile);
  	}
  
  	private IProject createModelProject(SubMonitor monitor) throws CoreException {
  		ProjectFactory factory = createProjectFactory();
  		configureProjectFactory(factory);
  		IProject modelProject = factory.createProject(monitor, null);
  		createModel(modelProject, monitor);
  		return modelProject;
  	}	
  	
  	private void createModel(final IProject project, final SubMonitor monitor) throws CoreException {
  		InputStream contents = this.getClass().getClassLoader().getResourceAsStream("/templateproject/project.zip");
  		enhancePlatformProject(project, contents, monitor);
  	}
  	
  	protected ProjectFactory configureProjectFactoryForPlatformProject(ProjectFactory factory, MobilePlatform platform) {
  		factory.setProjectName(getProjectInfo().getProjectName() + platform.getProjectNameSuffix());
  		factory.addReferencedProjects(getReferencedProjects());
  		factory.addProjectNatures(getProjectNatures());
  		factory.addBuilderIds(getBuilders());
  		return factory;
  	}
  	
  	
  	private IProject createPlatformProject(MobilePlatform platform, SubMonitor monitor) {
  		ProjectFactory factory = createPlatformProjectFactory();
  		configureProjectFactoryForPlatformProject(factory, platform);
  		IProject platformProject = factory.createProject(monitor, null);
  		enhancePlatformProject(platformProject, platform, monitor);
  		return platformProject;
  	}
  	private void enhancePlatformProject(IProject project, MobilePlatform platform, SubMonitor monitor) {
  		ExtensibleURIConverterImpl uriConverter = new ExtensibleURIConverterImpl();
  		try {
  			InputStream stream = uriConverter.createInputStream(platform.getTemplateProjectURI());
  			enhancePlatformProject(project, stream, monitor);
  		} catch (IOException e) {
  			throw new RuntimeException(e);
  		}
  		
  	}
  	
  	private void enhancePlatformProject(IProject project, InputStream stream, SubMonitor monitor) {
  		try {
  			ZipInputStream zipStream = new ZipInputStream(stream);
  			ZipEntry entry;
  			while ((entry = zipStream.getNextEntry()) != null) {
  				String name = entry.getName();
  				if(name.contains("__MACOSX/"))
  					continue;
  				
  				name = replaceTemplate(name);
  				if (entry.isDirectory()) {
  					IFolder folder = project.getFolder(name);
  					if (!folder.exists()) {
  						folder.create(true, true, monitor);
  					}
  				} else {
  					IFile file = project.getFile(name);
  					// PFR: PNGs, GIfs and ZIPs will not be filtered. Poor man's binary detection :-/
  					if (entry.getName().endsWith(".png") || entry.getName().endsWith(".gif") || entry.getName().endsWith(".jar")) {
  						File destFile = file.getLocation().toFile();
  						FileOutputStream output = FileUtils.openOutputStream(destFile);
  						IOUtils.copy(zipStream, output);
  					}
  					else {
  						String content;
  						content = replaceTemplate(IOUtils.toString(zipStream, "UTF-8"));
  						if (file.exists()) {
  							file.delete(true, monitor);
  						}
  						file.create(new StringInputStream(content), true, monitor);
  					}
  				}
  			}
  			project.refreshLocal(IResource.DEPTH_INFINITE, monitor);
  		} catch (CoreException e) {
  			throw new RuntimeException(e);
  		} catch (IOException e) {
  			throw new RuntimeException(e);
  		} finally {
  			IOUtils.closeQuietly(stream);
  		}
  	}
  	
  	private String replaceTemplate(String str) {
  		String projectName = getProjectInfo().getProjectName();
  		String capitalizedProjectName = projectName.equals("_template_") ? "_Template_" : StringUtils.capitalize(projectName);
  		str = str.replace("itemisApp", projectName);
  		str = str.replace("ItemisApp", capitalizedProjectName);
  		str = str.replace("de.itemis.itemisapp.R", "de.itemis." + projectName.toLowerCase() + ".R");
  		return str;
  	}
  
  }
  