
<%
/**
 * Copyright (c) 2002-2010 IBM Corporation and others.
 * All rights reserved.   This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v20.html
 * 
 * Contributors: 
 *   IBM - Initial API and implementation
 */
%>
<%GenModel genModel = (GenModel)argument;%>
<%String pluginClassesLocation = genModel.isRuntimeJar() ? genModel.getEditPluginID()+".jar" : ".";%>
<%List<String> sourceFolders = genModel.getEditSourceFolders();%>
<%@ egf:patternCall patternId="platform:/plugin/org.eclipse.egf.emf.pattern.base/egf/EMF_Pattern_Base.fcore#LogicalName=org.eclipse.egf.emf.pattern.base.HeaderProperties" args="parameter:argument"%>

bin.includes = <%=pluginClassesLocation%>,\
<%if (genModel.getRuntimePlatform() != GenRuntimePlatform.GWT) {%>
               icons/,\
<%}%>
<%if (genModel.isBundleManifest()) {%>
               META-INF/,\
<%}%>
<%if (genModel.getRuntimePlatform() != GenRuntimePlatform.GWT) {%>
               plugin.xml,\
<%}%>
<%String editBundleLocalization = genModel.getEditBundleLocalization(); int index = editBundleLocalization.indexOf("/"); if (index == -1) {%>
               <%=editBundleLocalization%>.properties
<%} else {%>
               <%=editBundleLocalization.substring(0, index + 1)%>
<%}%>
jars.compile.order = <%=pluginClassesLocation%>
<% boolean first=true; for (Iterator<String> i = sourceFolders.iterator(); i.hasNext();) { String sourceFolder = i.next(); if (i.hasNext()){sourceFolder +=",\\";} if (first) {%>
source.<%=pluginClassesLocation%> = <%=sourceFolder%><%first=false;} else {%><%=sourceFolder%><%}}%>
output.<%=pluginClassesLocation%> = bin/
