gt: 			if(paramEnd < 0 || paramStart < 0) return null;
context: import java.awt.BorderLayout;
  import java.awt.GridLayout;
  import java.awt.event.ActionEvent;
  import java.awt.event.ActionListener;
  import java.io.BufferedReader;
  import java.io.BufferedWriter;
  import java.io.File;
  import java.io.FileWriter;
  import java.io.IOException;
  import java.io.InputStream;
  import java.io.InputStreamReader;
  import java.io.Reader;
  import java.util.LinkedList;
  
  import javax.swing.JButton;
  import javax.swing.JFrame;
  import javax.swing.JLabel;
  import javax.swing.JPanel;
  import javax.swing.JScrollPane;
  import javax.swing.JTextArea;
  import javax.swing.JTextField;
  
  import lex.FunctionParser;
  import lex.InvalidParameterException;
  import lex.ParameterParser;
  import utils.Pair;
  import element.Function;
  import element.Parameter;
  
  
  public class UI extends JFrame {
  	private static String functions_txt = "";
  	
  	public static final String F_NAME = "clust";
  
  	JTextArea fMainTA; 
  	JTextField fExternTF, fIgnoreKeywordListTF;
  	/**
  	 * 
  	 */
  	private static final long serialVersionUID = -7316827103620049173L;
  
  	private LinkedList<Function> functions = new LinkedList<Function>();
  	private String[] ignoreList = null;
  
  	public UI() {
  		super(LibraryOverrider.APPLICATION_NAME);
  
  		this.setLayout(new BorderLayout());
  
  		JPanel mainPanel = new JPanel();
  		loadMainPanel(mainPanel);
  		this.add(mainPanel, BorderLayout.CENTER);
  
  
  		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
  		this.setSize(480,720);
  		this.setLocationRelativeTo(null);
  		this.setVisible(true);
  	}
  
  	private void loadMainPanel(JPanel mainPanel) {
  		mainPanel.setLayout(new BorderLayout());
  		// Configuration section
  		JPanel topPanel = new JPanel();
  		topPanel.setLayout(new GridLayout(2,2));
  		JLabel externLabel = new JLabel("\"extern\" keyword");
  		externLabel.setToolTipText("<html>The extern keyword can be replaced by a define in your header file:<br />type the define that defines the extern keyword here.</html>");
  		topPanel.add(externLabel);
  		fExternTF = new JTextField("extern");
  		topPanel.add(fExternTF);
  
  		JLabel ignoreListLabel = new JLabel("Ignore keyword list");
  		ignoreListLabel.setToolTipText("<html>If the header contains some empty defines that may be ignored,<br />list them here. Separate them with comas.</html>");
  		topPanel.add(ignoreListLabel);
  		fIgnoreKeywordListTF = new JTextField("CL_API_CALL,CL_API_ENTRY,CL_EXT_PREFIX__VERSION_2_0_DEPRECATED,CL_EXT_PREFIX__VERSION_1_1_DEPRECATED,CL_EXT_PREFIX__VERSION_1_0_DEPRECATED");
  		topPanel.add(fIgnoreKeywordListTF);
  
  		mainPanel.add(topPanel, BorderLayout.NORTH);
  		// Middle section
  		fMainTA = new JTextArea(functions_txt);
  
  		JScrollPane jsp = new JScrollPane(fMainTA);
  
  		mainPanel.add(jsp, BorderLayout.CENTER);
  
  		JPanel bottomPanel = new JPanel();
  		bottomPanel.setLayout(new BorderLayout());
  		JButton generateButton = new JButton("Generate");
  		bottomPanel.add(generateButton, BorderLayout.WEST);
  		generateButton.addActionListener(new ActionListener() {
  
  			@Override
  			public void actionPerformed(ActionEvent ae) {
  				generateFiles();
  			}
  		});
  
  		mainPanel.add(bottomPanel, BorderLayout.SOUTH);
  	}
  
  	protected void generateFiles() {
  		ignoreList = fIgnoreKeywordListTF.getText().split(",");
  		functions = new LinkedList<Function>();
  
  		String content = fMainTA.getText();
  		FunctionParser parser = new FunctionParser(content, fExternTF.getText());
  
  		Pair<String, String> functionText = null;
  		while((functionText = parser.getNextFunction()) != null) {
  			processFunction(functionText);
  		}
  		String header = genHeader();
  		String code = genCode();
  		String tp_header = genTpHeader();
  
  		save(header, F_NAME + ".h");
  		save(code, F_NAME + ".c");
  		save(tp_header, F_NAME + "_tp.h");
  		
  		/*Enumeration<String> keys = Function.types.keys();
  		String key = null;
  		while(keys.hasMoreElements()) {
  			key = keys.nextElement();
  			Integer count = Function.types.get(key);
  			System.out.println(key + " : " + count);
  		}*/
  		System.out.println("done");
  	}
  
  
  	private void save(String content, String filepath) {
  		FileWriter fw = null;
  		BufferedWriter bw = null;
  		try {
  			fw = new FileWriter(new File(filepath));
  			bw = new BufferedWriter(fw);
  			bw.write(content);
  		} catch (IOException e) {
  			e.printStackTrace();
  		} finally {
  			if(bw != null) {
  				try {
  					bw.close();
  				} catch (IOException e) {
  					e.printStackTrace();
  				}
  			}
  			if(fw != null) {
  				try {
  					fw.close();
  				} catch (IOException e) {
  					e.printStackTrace();
  				}
  			}
  		}
  	}
  
  	private String genCode() {
  		
  		String template = getRessourceAsString("clust.c.template");
  		
  		StringBuilder strbldr = new StringBuilder();
  
  		for(Function fct : functions) {
  			strbldr.append("cl_api_call_" + fct.getName() + " " + "reallib_" + fct.getName() + ";\n");
  		}
  		
  		template = template.replaceAll("\\[\\[\\[reallibdefines\\]\\]\\]", strbldr.toString());
  		
  		strbldr = new StringBuilder();
  		
  		for(Function fct : functions) {
  			strbldr.append("\treallib_" + fct.getName() + " = (cl_api_call_" + fct.getName() + ") dlSymFunction(libcl_ptr, \"" + fct.getName() + "\");\n");
  		}
  		
  		template = template.replaceAll("\\[\\[\\[reallibdlsym\\]\\]\\]", strbldr.toString());
  
  		strbldr = new StringBuilder();
  		
  		
  		for(Function fct : functions) {
  			strbldr.append(fct.getTracepointDeclaration() + "\n" + fct.getInstrumentedFunctionCode() + "\n\n");
  		}
  
  		template = template.replaceAll("\\[\\[\\[functions\\]\\]\\]", strbldr.toString());
  		
  		return template;
  	}
  
  	private String genHeader() {
  		
  		String template = getRessourceAsString("clust.h.template");
  
  		StringBuilder strbldr = new StringBuilder();
  		for(Function fct : functions) {
  			strbldr.append(fct.getHeaderTypeDef() + "\n\n");
  		}
  		
  		template = template.replaceAll("\\[\\[\\[functionprototypes\\]\\]\\]", strbldr.toString());
  		
  		strbldr = new StringBuilder();
  		int index = 0;
  		for(Function fct : functions) {
  			strbldr.append("#define API_CALL_" + fct.getName().toUpperCase() + "\t" + index++ + "\n");
  		}
  		
  		template = template.replaceAll("\\[\\[\\[clapicallenum\\]\\]\\]", strbldr.toString());
  		
  
  		return template;
  	}
  	
  
  	private String genTpHeader() {
  		
  		/*
  		TRACEPOINT_EVENT(
  				clust_provider,
  				cl_<functionName>,
  		    TP_ARGS(
  		    ),
  		    TP_FIELDS(
  		    )
  		)
  		*/
  		StringBuilder strbldr = new StringBuilder();
  
  		for(Function fct: functions) {
  			strbldr.append(
  					"TRACEPOINT_EVENT(\n" +
  							"	clust_provider,\n" +
  							"	cl_" + fct.getName() + "_start,\n" +
  							"TP_ARGS(\n" +
  							"),\n" +
  							"TP_FIELDS(\n" +
  							")\n" +
  					")\n");
  			strbldr.append(
  					"TRACEPOINT_EVENT(\n" +
  							"	clust_provider,\n" +
  							"	cl_" + fct.getName() + "_end,\n" +
  							"TP_ARGS(\n" +
  							"),\n" +
  							"TP_FIELDS(\n" +
  							")\n" +
  					")\n");
  		}
  		
  		
  		String template = getRessourceAsString("clust_tp.h.template");
  
  		template = template.replaceAll("\\[\\[\\[apifunctiontracepoints\\]\\]\\]", strbldr.toString());
  		
  		return template;
  	}
  	
  	private String getRessourceAsString(String ressourcePath) {
  		InputStream is = UI.class.getResourceAsStream(ressourcePath);
  		Reader r = new InputStreamReader(is);
  		BufferedReader br = new BufferedReader(r);
  		StringBuilder stb = new StringBuilder();
  		String line = null;
  		try {
  			while((line = br.readLine()) != null) {
  				stb.append(line + "\n");
  			}
  		} catch (IOException e) {
  			e.printStackTrace();
  		} finally {
  			try {
  				br.close();
  				r.close();
  				is.close();
  			} catch (IOException e) {
  				e.printStackTrace();
  			}
  		}
  		
  		return stb.toString();
  	}
  
  	private void processFunction(Pair<String, String> functionText) {
  		try {
  			functions.addLast(parseFunction(functionText));
  		} catch (InvalidFunctionException e) {
  			e.printStackTrace();
  		}
  	}
  
  	private Function parseFunction(Pair<String, String> functionText) throws InvalidFunctionException {
  		try {
  			int paramStart = functionText.b.indexOf('(');
  			int paramEnd = functionText.b.lastIndexOf(')');
  