<file_sep>package org.uva.sea.ql.parser.test;

	import static org.junit.Assert.assertEquals;

import java.util.HashMap;
import java.util.Map;

import org.junit.Test;
import org.uva.sea.ql.parser.antlr.ANTLRParser;
import org.uva.sea.ql.visitor.evaluator.ExprEvaluator;
import org.uva.sea.ql.visitor.evaluator.values.BoolValue;
import org.uva.sea.ql.visitor.evaluator.values.DecValue;
import org.uva.sea.ql.visitor.evaluator.values.IntValue;
import org.uva.sea.ql.visitor.evaluator.values.Value;

	public class TestExpressionEvaluator {

		private ANTLRParser parser;
		private final Map<String,Value> runTimeValues;


		public TestExpressionEvaluator() {

			parser = new ANTLRParser();
			this.runTimeValues=new HashMap<String,Value>();

		}

		@Test
		public void testBinAlgebraic() throws ParseError {
			runTimeValues.put("IntVal",new IntValue(100));
			assertEquals(new IntValue(136).getValue() , ((IntValue) ExprEvaluator.eval(parser.parseExpr("(3 * 12)+IntVal"),runTimeValues)).getValue() );
			assertEquals(new IntValue(120).getValue(), ((IntValue) ExprEvaluator.eval(parser.parseExpr("IntVal + (200 * 10)/(200 - 100)"),runTimeValues)).getValue() );

			runTimeValues.put("DecimalVal",new DecValue(100.0f));
			assertEquals(139.0, ((DecValue) ExprEvaluator.eval(parser.parseExpr("DecimalVal+(3.0 * 13.0)"),runTimeValues)).getValue() ,0.0);
			assertEquals(120.0, ((DecValue) ExprEvaluator.eval(parser.parseExpr("DecimalVal + (200.0 * 10.0)/(200.0 - 100.0)"),runTimeValues)).getValue(),0.0 );
			
				}


		@Test
		public void testBinBool() throws ParseError {
			runTimeValues.put("TRUE",new BoolValue(true));
			System.out.println(((BoolValue) ExprEvaluator.eval(parser.parseExpr("136 == 136"),runTimeValues)).getValue());
			assertEquals(true , ((BoolValue) ExprEvaluator.eval(parser.parseExpr("((3 * 12) + 100) == 136"),runTimeValues)).getValue() );
			assertEquals(true , ((BoolValue) ExprEvaluator.eval(parser.parseExpr("((3 * 12) + 100) >= 136"),runTimeValues)).getValue() );
			assertEquals(true , ((BoolValue) ExprEvaluator.eval(parser.parseExpr("((3 * 12) + 100) <= 136"),runTimeValues)).getValue() );
			assertEquals(false , ((BoolValue) ExprEvaluator.eval(parser.parseExpr("((3 * 12) + 100) != 136"),runTimeValues)).getValue() );
			assertEquals(false , ((BoolValue) ExprEvaluator.eval(parser.parseExpr("((3 * 12) + 100) > 136"),runTimeValues)).getValue() );
			assertEquals(false , ((BoolValue) ExprEvaluator.eval(parser.parseExpr("((3 * 12) + 100) < 136"),runTimeValues)).getValue() );
			assertEquals(true, ((BoolValue) ExprEvaluator.eval(parser.parseExpr("((100 + (200 * 10)/(200 - 100)) == 120) && TRUE"),runTimeValues)).getValue() );
			assertEquals(false, ((BoolValue) ExprEvaluator.eval(parser.parseExpr("((100 + (200 * 10)/(200 - 100)) != 120) && TRUE"),runTimeValues)).getValue() );

			runTimeValues.put("FALSE",new BoolValue(false));
			assertEquals(false, ((BoolValue) ExprEvaluator.eval(parser.parseExpr("((100 + (200 * 10)/(200 - 100)) == 120) && FALSE"),runTimeValues)).getValue() );
			assertEquals(true, ((BoolValue) ExprEvaluator.eval(parser.parseExpr("((100 + (200 * 10)/(200 - 100)) == 120) || FALSE"),runTimeValues)).getValue() );
		}
		
		@Test
		public void testUnary() throws ParseError {
			runTimeValues.put("IntVal",new IntValue(100));
			assertEquals(new IntValue(136).getValue() , ((IntValue) ExprEvaluator.eval(parser.parseExpr("(-3 * -12)+IntVal"),runTimeValues)).getValue() );
			assertEquals(new IntValue(-120).getValue(), ((IntValue) ExprEvaluator.eval(parser.parseExpr("-IntVal + (200 * -10)/(200 - 100)"),runTimeValues)).getValue() );

			runTimeValues.put("DecimalVal",new DecValue(100.0f));
			assertEquals(-139.0, ((DecValue) ExprEvaluator.eval(parser.parseExpr("-DecimalVal+(-3.0 * 13.0)"),runTimeValues)).getValue() ,0.0);
			assertEquals(120.0, ((DecValue) ExprEvaluator.eval(parser.parseExpr("DecimalVal + (-200.0 * -10.0)/(200.0 - 100.0)"),runTimeValues)).getValue(),0.0 );
		
		}
		
		


		

	}
<file_sep>package org.uva.sea.ql.gui.qlform;

import java.awt.Dimension;
import java.util.List;
import java.util.Map;
import java.util.Observable;
import java.util.Observer;

import javax.swing.JPanel;

import net.miginfocom.swing.MigLayout;

import org.uva.sea.ql.ast.expr.Expr;
import org.uva.sea.ql.gui.qlform.interpreter.VariableUpdater;
import org.uva.sea.ql.visitor.evaluator.ExprEvaluator;
import org.uva.sea.ql.visitor.evaluator.values.BoolValue;
import org.uva.sea.ql.visitor.evaluator.values.Value;

@SuppressWarnings("serial")
public abstract class QLConditionalBody extends JPanel implements Observer, QLContainerComponent{

	private final List<JPanel> questionPanelList;
	private  Map<String,Value> runTimeValues;
	private final VariableUpdater varUpdater;
	private final Expr condition;
	private final boolean isElseBody;

	
	public QLConditionalBody(List<JPanel> questionPanelList,Expr condition,VariableUpdater varUpdater,Map<String,Value> runTimeValues,boolean isElseBody){
	    super(new MigLayout("fill,insets 0"));
		this.questionPanelList=questionPanelList;
		this.runTimeValues=runTimeValues;
		this.varUpdater=varUpdater;
		this.varUpdater.addObserver(this);
		this.condition=condition;
		this.isElseBody=isElseBody;	
		setSettings();
	}
	
	
	
	private void setSettings(){
		this.setMinimumSize(new Dimension(617, 40));
		this.setOpaque(false);
		fillPanel();
		setVisibility(runTimeValues);
	}
	
	
	private void fillPanel(){
		for(JPanel questionPanel:questionPanelList){
			this.add(questionPanel,"align label,wrap");
		}
	}
	
	
	public JPanel getPanel(){
		return this;
	}


	@Override
	public void update(Observable arg0, Object arg1) {
		setVisibility(varUpdater.getUpdatedValues());
			
	}
	
	private void setVisibility(Map<String,Value> runTimeValues){
		boolean isVisible=((BoolValue) ExprEvaluator.eval(condition, runTimeValues)).getValue();
		if(isElseBody){
		this.setVisible(!isVisible);
		return;
		}
		this.setVisible(isVisible);
	}
	
	
	
	
}
<file_sep>package org.uva.sea.ql.gui.ide;

import java.awt.Color;
import java.awt.Dimension;

import javax.swing.ImageIcon;
import javax.swing.JFrame;

import net.miginfocom.swing.MigLayout;

@SuppressWarnings("serial")
public class IDEFrame extends JFrame {
	private final static ImageIcon imgIcon = new ImageIcon(IDEFrame.class.getResource("/org/uva/sea/ql/gui/ide/icons/logo.png"));


	public IDEFrame() {
		setSettings();

	}

	private void setSettings() {
		this.setIconImage(imgIcon.getImage());
		this.setLocation(50, 90);
		this.setTitle("QL Editor");
		this.setLayout(new MigLayout());
		this.setSize(new Dimension(575, 470));
		this.setResizable(false);
		this.getContentPane().setBackground(Color.LIGHT_GRAY);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}

}
<file_sep>package org.uva.sea.ql.gui.qlform;

import java.awt.Color;

import javax.swing.JPanel;

import net.miginfocom.swing.MigLayout;



@SuppressWarnings("serial")
public class QLContentPanel extends JPanel implements QLContainerComponent {

	public QLContentPanel(){
		setSettings();
	}
	

	private void setSettings(){
		this.setLayout(new MigLayout("hidemode 1"));
		this.setBackground(Color.black);
		
	}

	@Override
	public boolean isConditionalBody() {
		return false;
	}

	@Override
	public boolean isPanel() {
		return true;
	}

}
<file_sep>package org.uva.sea.ql.gui.qlform.output;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.uva.sea.ql.gui.qlform.interpreter.VariableUpdater;
import org.uva.sea.ql.visitor.evaluator.values.Value;

public class QLOutputState {
	private final List<String> questionLabels;
	private final List<String> questionValues;
	private boolean hasError = false;
	private  VariableUpdater varUpdater;

	public QLOutputState(VariableUpdater varUpdater) {
		this.varUpdater=varUpdater;
		questionLabels = new ArrayList<String>();
		questionValues = new ArrayList<String>();
	}

	public void addValue(String value) {
		questionValues.add(value);
	}

	public void addLabelText(String value) {
		questionLabels.add(value);
	}

	public List<String> getQuestionLabels() {
		return questionLabels;
	}

	public List<String> getQuestionVisibleValues() {
		return questionValues;
	}

	public void setErrorFlag(boolean hasError) {
		this.hasError = hasError;
	}

	public boolean hasError() {
		return hasError;
	}
	
	public Map<String,Value> getAllRunTimeValues(){
		return varUpdater.getUpdatedValues();
	}
}
<file_sep>package org.uva.sea.ql.gui.ide;

import java.awt.Color;
import java.awt.Dimension;

import javax.swing.JPanel;

import net.miginfocom.swing.MigLayout;

@SuppressWarnings("serial")
public class UtilityBarPanel extends JPanel  {
	
	public UtilityBarPanel(){
		super(new MigLayout());
		setSettings();
	}

	private void setSettings() {
		this.setMaximumSize(new Dimension(200,90));
		this.setBackground(Color.LIGHT_GRAY);		
	}

}
<file_sep>package org.uva.sea.ql.gui.qlform;

import java.awt.Color;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JTextField;

import org.uva.sea.ql.ast.types.Type;

@SuppressWarnings("serial")
public class QLInputVerifier extends JLabel implements KeyListener, QLAtomComponent{
	private final JTextField inputTextField;
	private final Type type;
	private String value="";

	public QLInputVerifier(JComponent component, Type type) {
		this.inputTextField = (JTextField) component;
		this.type = type;
		setSettings();
	}
	
	private void setSettings(){
		this.setForeground(Color.ORANGE);
		inputTextField.addKeyListener(this);
	}

	

	private void setVerifierMsg() {
		String input = inputTextField.getText();
		if (type.isCompatibleToNumericType()) {
			numVerifier(input);
			return;
		}
		stringVerifier(input);
	}

	private void numVerifier(String input) {
		if (!isNumChar(input)) {
			value="*accepts only numeric characters*";
			this.setText(value);
			return;
		}

		value="";
		this.setText(value);

	}

	private void stringVerifier(String input) {
		if (!isStringChar(input)) {
			this.setVisible(true);
			this.setText("*accepts only string characters*");
			return;
		}

		this.setVisible(false);
		this.setText("");
	}

	public static boolean isStringChar(String input) {
		return !input.matches(".*\\d.*");
	}

	public static boolean isNumChar(String input) {
		try {
			Float.parseFloat(input);
		} catch (Exception e) {
			return false;
		}
		return true;
	}

	@Override
	public void keyPressed(KeyEvent e) {

	}

	@Override
	public void keyReleased(KeyEvent e) {
		setVerifierMsg();

	}

	@Override
	public void keyTyped(KeyEvent e) {
	}

	@Override
	public String getDisplayedValue() {
		return value;
	}
	
	public boolean hasError(){
		return !value.isEmpty();
	}

	@Override
	public boolean isQuestionLabel() {
		return false;
	}

	@Override
	public boolean isAnswerHolder() {
		return false;
	}

	@Override
	public boolean isWarningLabel() {
		return true;
	}
}
<file_sep>package org.uva.sea.ql.gui.ide;

import java.awt.Color;
import java.awt.Dimension;

import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

import net.miginfocom.swing.MigLayout;

@SuppressWarnings("serial")
public class EditorArea extends JPanel {
	private final JTextArea editorArea;
	
	public EditorArea() {
		super(new MigLayout());
		editorArea = new JTextArea(18, 50);
		setSettings();
	}

	private void setSettings() {
		this.setBackground(new Color(49, 49, 49));
		editorArea.setBackground(Color.black);
		editorArea.setForeground(new Color(255, 185, 15));
		editorArea.setLineWrap(true);
		editorArea.setWrapStyleWord(true);
		editorArea.setCaretColor(Color.white);
		JScrollPane bar = new JScrollPane(editorArea,
				JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
				JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
		bar.setPreferredSize(new Dimension(550, 300));
		this.add(bar);
		
	}
	
	public String getSourceCode(){
		return editorArea.getText();
	}
	
	public void setSourceCode(String input){
		editorArea.setText(input);
	}

}
<file_sep>package org.uva.sea.ql.output.generators.pdf;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.filechooser.FileFilter;

import org.uva.sea.ql.gui.qlform.output.QLOutputSelectorFrame;

import com.itextpdf.text.Chunk;
import com.itextpdf.text.Document;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Image;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.PdfWriter;
 
public class QLToPDF {
	private final static Font symbolFont = new Font(Font.FontFamily.ZAPFDINGBATS, 15, Font.BOLD);
	private final static Font titleFont = new Font(Font.FontFamily.TIMES_ROMAN, 18,Font.UNDERLINE);
    private final static Font questionFont = new Font(Font.FontFamily.TIMES_ROMAN, 14,Font.ITALIC);
    private final static Font resultsFont = new Font(Font.FontFamily.TIMES_ROMAN, 14,Font.BOLD);
    private final static URL imgPath =  QLToPDF.class.getResource("/org/uva/sea/ql/output/generators/pdf/images/uva_logo.jpg");
    private final static Map<String,String> boolValues;
    static
    {
    	boolValues = new HashMap<String, String>();
    	boolValues.put("true", "Yes");
    	boolValues.put("false","No");
    }
    
    private final static Map<String,String> yesOrNoSymbol;
    static
    {
    	yesOrNoSymbol = new HashMap<String, String>();
    	yesOrNoSymbol.put("true", "4");   //** Values '4' and '6' corresponds to 'tick' and 'X' symbols of
    	yesOrNoSymbol.put("false","6");   //** the ZAPFDINGBATS font. 
    }


    private final List<String> questionLabels;
    private final List<String> questionValues;
    private final JFrame frame;
	
	
	
	private QLToPDF(List<String> questionLabels,List<String> questionValues, JFrame frame){
		this.questionLabels=questionLabels;
		this.questionValues=questionValues;
		this.frame= frame;
	}

    public static void generatePdf(JFrame frame,List<String> questionLabels,List<String> questionValues) {
    	QLToPDF generator=new QLToPDF(questionLabels,questionValues, frame);
    	generator.putContent(frame.getTitle());
    	
    }
    
    
	private void putContent(String frameName) {
		try {
			String path = showSaveDialog(frameName+".pdf",new TypeOfPDF());
			if (path.isEmpty())
				return;
			File filePath = new File(path);
			OutputStream file = new FileOutputStream(filePath.getAbsolutePath());
			Document document = new Document();
			PdfWriter.getInstance(document, file);
			document.open();
			Image img = Image.getInstance(imgPath);
			document.add(setHeaderLogo(img));
			document.add(setTitle(frameName));

			for (int i = 0; i <= questionLabels.size() - 1; i++) {
				Paragraph p1 = new Paragraph(questionLabels.get(i),
						questionFont);

				p1 = getProperDisplayedValue(p1, questionValues.get(i));
				addEmptyLine(p1, 1);
				document.add(new Paragraph(p1));
			}
			document.close();
			file.close();
			QLOutputSelectorFrame.showConfirmationMessage(frame, frame.getTitle()+".pdf file successful created!");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
    
    private static void addEmptyLine(Paragraph paragraph, int number) {
        for (int i = 0; i < number; i++) {
          paragraph.add(new Paragraph(" "));
        }
      }
    
	private static Paragraph setHeaderLogo(Image img) {
		Paragraph logoHeader = new Paragraph();
		img.scalePercent(15f);
		Chunk imgChunk = new Chunk(img, 0, 0, true);
		logoHeader.add(imgChunk);
		logoHeader.setAlignment(Element.ALIGN_LEFT);
		addEmptyLine(logoHeader, 1);
		return logoHeader;
	}
    
	private static Paragraph setTitle(String frameName) {
		Paragraph header = new Paragraph();
		addEmptyLine(header, 1);
		Paragraph title = new Paragraph(frameName + " Questionnaire", titleFont);
		header.add(title);
		addEmptyLine(header, 2);
		title.setAlignment(Element.ALIGN_CENTER);
		return header;
	}
    
	private Paragraph getProperDisplayedValue(Paragraph paragraph, String value) {
		paragraph.add(new Chunk("     "));
		if (boolValues.containsKey(value)) {
			paragraph.add(new Chunk(yesOrNoSymbol.get(value), symbolFont));
			paragraph.add(new Chunk("  (" + boolValues.get(value) + ")", resultsFont));
		} else {
			paragraph.add(new Chunk("  " + value, resultsFont));

		}

		return paragraph;

	}
	
	public static String showSaveDialog(String fileName,FileFilter fileType) {
		JFileChooser fileChooser = new JFileChooser();
		fileChooser.setAcceptAllFileFilterUsed(false);
        fileChooser.setSelectedFile(new File(fileName));
        fileChooser.setFileFilter(fileType);
		int returnValue = fileChooser.showSaveDialog(null);
		if (returnValue == JFileChooser.APPROVE_OPTION) {
			File outputFile = fileChooser.getSelectedFile();
			return outputFile.getAbsolutePath();
		}
		return "";
	}
	
	class TypeOfPDF extends FileFilter {
		public boolean accept(File file) {
			return file.isDirectory();
		}

		public String getDescription() {
			return ".pdf";
		}
	}

	
	
}<file_sep>package org.uva.sea.ql.output.generators.json;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;

import javax.swing.JFrame;
import javax.swing.filechooser.FileFilter;

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.uva.sea.ql.gui.qlform.output.QLOutputSelectorFrame;
import org.uva.sea.ql.output.generators.pdf.QLToPDF;
import org.uva.sea.ql.visitor.evaluator.values.Value;

public class QLToJSON {

	private final Map<String,Value> allRunTimeValues;
	private final JSONObject qlForm = new JSONObject();
	private final JFrame frame;

	private QLToJSON(Map<String,Value> allRunTimeValues, JFrame frame) {
		this.allRunTimeValues=allRunTimeValues;
		this.frame= frame;
	}

	public static void generateJson(JFrame frame,Map<String,Value> allRunTimeValues) {
		QLToJSON generator = new QLToJSON(allRunTimeValues, frame);
		generator.createForm(frame.getTitle());
		generator.writeToFile(frame.getTitle());

	}

	@SuppressWarnings("unchecked")
	private void createForm(String frameName) {
		JSONObject title = new JSONObject();
		title.put("formName", frameName);
		
		JSONArray structure = new JSONArray();
		structure.add(title);
		
		JSONObject content = getContentList();
		structure.add(content);
		qlForm.put("qlForm", structure);
	}

	private void writeToFile(String frameName) {
		try {
			String path = QLToPDF.showSaveDialog(frameName+".json", new TypeOfJson());
			if (path.isEmpty())
				return;
			File filePath = new File(path);
			FileWriter file = new FileWriter(filePath.getAbsolutePath());
			file.write(qlForm.toJSONString());
			file.flush();
			file.close();
			QLOutputSelectorFrame.showConfirmationMessage(frame, frame.getTitle()+".json file successful created!");

		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@SuppressWarnings("unchecked")
	private JSONObject getContentList() {
		JSONArray contentList = new JSONArray();
		Iterator<String> iterator = allRunTimeValues.keySet().iterator();

		while (iterator.hasNext()) {
			JSONObject question = new JSONObject();
			String key = iterator.next().toString();
			question.put("ident", key);
			question.put("answer",String.valueOf(allRunTimeValues.get(key).getValue()));
			contentList.add(question);

		}
		JSONObject questionsList = new JSONObject();
		questionsList.put("questions", contentList);
		return questionsList;
	}
	

	class TypeOfJson extends FileFilter {
		public boolean accept(File file) {
			return file.isDirectory();
		}

		public String getDescription() {
			return ".json";
		}
	}

}
<file_sep>package org.uva.sea.ql.gui.qlform;

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Map;
import java.util.Observable;
import java.util.Observer;

import javax.swing.JTextField;

import org.uva.sea.ql.gui.qlform.interpreter.VariableUpdater;
import org.uva.sea.ql.visitor.evaluator.values.StrValue;
import org.uva.sea.ql.visitor.evaluator.values.Value;

@SuppressWarnings("serial")
public class QLTextField extends JTextField implements ActionListener, Observer, QLAtomComponent{
	
	private final String varName;
	private final Map<String, Value> runTimeValues;
	private String value;
	private final static Color defaultColor= new Color(238,238,238);
	private final VariableUpdater varUpdater;



	
	public QLTextField(String varName,Map<String, Value> runTimeValues, VariableUpdater varUpdater){
		super(8);
		this.varName=varName;
		this.runTimeValues=runTimeValues;
		this.varUpdater=varUpdater;
		this.varUpdater.addObserver(this);
		setSettings();
	}
	
	private void setSettings(){
		value=((StrValue) runTimeValues.get(varName)).getValue();
		this.setBackground(defaultColor);
		this.addActionListener(this);
		this.setText(value);
	}
	
	

	@Override
	public void actionPerformed(ActionEvent e) {
		String input=this.getText();
		if(!QLInputVerifier.isStringChar(input)) return;
		
		 varUpdater.updateValueAndNotify(varName, runTimeValues, new StrValue(input));
		

	}
	
	

	@Override
	public void update(Observable arg0, Object arg1) {
		value=((StrValue) varUpdater.getUpdatedValues().get(varName)).getValue();
		this.setText(value);		
	}

	@Override
	public String getDisplayedValue() {
		return this.getText();
	}

	@Override
	public boolean isQuestionLabel() {
		return false;
	}

	@Override
	public boolean isAnswerHolder() {
		return true;
	}

	@Override
	public boolean isWarningLabel() {
		return false;
	}
	
	
	

}
<file_sep>package org.uva.sea.ql.gui.qlform.output;

import java.awt.Component;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

import org.uva.sea.ql.gui.qlform.QLAtomComponent;
import org.uva.sea.ql.gui.qlform.QLContainerComponent;
import org.uva.sea.ql.gui.qlform.QLInputVerifier;
import org.uva.sea.ql.gui.qlform.interpreter.VariableUpdater;

public class OutputData {
	private final List<JPanel> questionPanelList;
	private final QLOutputState outputState;
	private final JFrame frame;


	public OutputData(List<JPanel> questionPanelList, JFrame frame,VariableUpdater varUpdater) {
		this.questionPanelList = questionPanelList;
		this.frame = frame;
		outputState = new QLOutputState(varUpdater);
	}

	public QLOutputState getOutputData() {
		traverseFormsSubComponents(questionPanelList);
		return outputState;
	}
	
	/*
	 * Gathers the question label text and their respective answer
	 */

	private void gatherDataFromSubComponents(Component[] components) {
		for (int i = 0; i < components.length; i++) {
			QLAtomComponent component = (QLAtomComponent) components[i];
			if (component.isWarningLabel()) {
				setWarning(component);
			}
			else if (component.isQuestionLabel()) {
				outputState.addLabelText(component.getDisplayedValue());
			} 
			else if (component.isAnswerHolder()) {
				outputState.addValue(component.getDisplayedValue());
			} 

		}

	}
	
	private void traverseFormsSubComponents(List<JPanel> questionPanelList) {
		for (JPanel questionPanel : questionPanelList) {
			QLContainerComponent container =(QLContainerComponent) questionPanel;
			if (container.isConditionalBody()) {
				if (!isVisible(questionPanel))
					return;
				Component[] conditionalBodyPanel = questionPanel.getComponents();
				traverseConditionalBodysSubComponents(conditionalBodyPanel);

			} else {
				Component[] components = questionPanel.getComponents();
				gatherDataFromSubComponents(components);
			}

		}
	}
	
	private void traverseConditionalBodysSubComponents(Component[] conditionalBodyPanel){
		List<JPanel> panelList=new ArrayList<JPanel>();
		for (Component questionPanel : conditionalBodyPanel) {
			panelList.add((JPanel) questionPanel);
		}
		traverseFormsSubComponents(panelList);
	}
	
	private void setWarning(QLAtomComponent component) {
		QLInputVerifier label = (QLInputVerifier) component;
		if (!label.hasError())
			return;
		outputState.setErrorFlag(true);
		showWarning();

	}


	private void showWarning() {
		JOptionPane.showMessageDialog(frame,"Wrong input.Check input warnings!");

	}
	
	
	private boolean isVisible(Component component){
		return ((JPanel) component).isVisible();
	}
}
<file_sep>package org.uva.sea.ql.parser.test;

import static org.junit.Assert.assertEquals;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.junit.Test;
import org.uva.sea.ql.ast.types.BoolType;
import org.uva.sea.ql.ast.types.IntType;
import org.uva.sea.ql.ast.types.MoneyType;
import org.uva.sea.ql.ast.types.StringType;
import org.uva.sea.ql.ast.types.Type;
import org.uva.sea.ql.parser.antlr.ANTLRParser;
import org.uva.sea.ql.visitor.checkers.ExpressionChecker;
import org.uva.sea.ql.visitor.checkers.error.QLErrorMsg;

public class TestExpressionChecker {

		private ANTLRParser parser;
		private Map<String, Type> declaredVars;
		private List<QLErrorMsg> errorReport;

		public TestExpressionChecker() {
			parser = new ANTLRParser();
			errorReport = new ArrayList<QLErrorMsg>();
			declaredVars = new LinkedHashMap<String, Type>();
	
		}

		
		
		@Test
		public void testBoolExprType() throws ParseError {
			declaredVars.put("BoolVar", new BoolType());
			assertEquals(true,ExpressionChecker.check(parser.parseExpr("(4>9) && ((45==3) || BoolVar)"),declaredVars,errorReport));
			assertEquals(false,ExpressionChecker.check(parser.parseExpr("(4>\"UndefinedVar\") && ((45==3) || false)"),declaredVars,errorReport));
			assertEquals(false,ExpressionChecker.check(parser.parseExpr("(4+6) && ((45==3) || false)"),declaredVars,errorReport));
			assertEquals(true,ExpressionChecker.check(parser.parseExpr("(4>=6)!= (((45==3) == false))"),declaredVars,errorReport));
			assertEquals(false,ExpressionChecker.check(parser.parseExpr("(4!=6) &&(((45==3) * !false))"),declaredVars,errorReport));
		}
		
		@Test
		public void testIntExprType() throws ParseError {
			declaredVars.put("IntVar", new IntType());
			assertEquals(true,ExpressionChecker.check(parser.parseExpr("4+IntVar/(3*6-44)"),declaredVars,errorReport));
			assertEquals(false,ExpressionChecker.check(parser.parseExpr("4+\"UndefinedVar\"/(3*6-44)"),declaredVars,errorReport));
			assertEquals(false,ExpressionChecker.check(parser.parseExpr("6+9-2*7.9"),declaredVars,errorReport));
			assertEquals(false,ExpressionChecker.check(parser.parseExpr("6+9-2*!7.9"),declaredVars,errorReport));
            assertEquals(false,ExpressionChecker.check(parser.parseExpr("4+false"),declaredVars,errorReport));
		}
		
		
		@Test
		public void testMoneyExprType() throws ParseError {
			declaredVars.put("type of question", new MoneyType());
			assertEquals(true, ExpressionChecker.check(parser.parseExpr("4.8+9.3/3.2*2.7"),declaredVars, errorReport));
			assertEquals(false, ExpressionChecker.check(parser.parseExpr("4.8+9.3/3.2*!2.7"),declaredVars, errorReport));
			assertEquals(false,ExpressionChecker.check(parser.parseExpr("4.2+3"),declaredVars,errorReport));
			assertEquals(false,ExpressionChecker.check(parser.parseExpr("4.2+false"),declaredVars,errorReport));

		}
		
		
		
		@Test
		public void testStringExprType() throws ParseError {
			declaredVars.put("declaredVariable", new StringType());
			assertEquals(true,ExpressionChecker.check(parser.parseExpr("variable name"),declaredVars,errorReport));
			assertEquals(true,ExpressionChecker.check(parser.parseExpr("\"8+3\""),declaredVars,errorReport));
			assertEquals(false,ExpressionChecker.check(parser.parseExpr("8+3"),declaredVars,errorReport));
		}

	}<file_sep>package org.uva.sea.ql.gui.qlform;

import java.awt.Color;
import java.util.Map;
import java.util.Observable;
import java.util.Observer;

import javax.swing.BorderFactory;
import javax.swing.JTextField;

import org.uva.sea.ql.ast.expr.Expr;
import org.uva.sea.ql.ast.form.ComputedQuestion;
import org.uva.sea.ql.gui.qlform.interpreter.VariableUpdater;
import org.uva.sea.ql.visitor.evaluator.ExprEvaluator;
import org.uva.sea.ql.visitor.evaluator.values.Value;

@SuppressWarnings("serial")
public class QLComputedField extends JTextField implements Observer,QLAtomComponent {
	private final VariableUpdater varUpdater;
    private final Map<String,Value> runTimeValues;
    private final Expr expr;
    private final String varName;
	

	public QLComputedField(ComputedQuestion qlElement,VariableUpdater varUpdater,Map<String,Value> runTimeValues) {
		super(8);
		this.varUpdater=varUpdater;
		this.varUpdater.addObserver(this);
		this.expr=qlElement.getExpr();
		this.varName=qlElement.getId().getName();
		this.runTimeValues = runTimeValues;
		setSettings();
	}



	private void setSettings() {
		Value initValue = ExprEvaluator.eval(expr, runTimeValues);
		this.setText(String.valueOf(initValue.getValue()));
		this.setForeground(Color.orange);
		this.setBackground(Color.gray);
		this.setBorder(BorderFactory.createLineBorder(Color.white));
		this.setHorizontalAlignment(JTextField.CENTER);
		this.setEditable(false);
	}

	@Override
	public void update(Observable arg0, Object arg1) {
		Map<String,Value> currentValues = varUpdater.getUpdatedValues();
		Value newVal = ExprEvaluator.eval(expr, currentValues);
		varUpdater.updateValue(varName, currentValues, newVal);
		this.setText(String.valueOf(newVal.getValue()));

	}

	@Override
	public String getDisplayedValue() {
		return this.getText();
	}



	@Override
	public boolean isQuestionLabel() {
		return false;
	}



	@Override
	public boolean isAnswerHolder() {
		return true;
	}



	@Override
	public boolean isWarningLabel() {
		return false;
	}
	
	
	
	
	

	
		
	

}

<file_sep>package org.uva.sea.ql.gui.qlform.renderer;

import java.util.List;

import javax.swing.JFrame;
import javax.swing.JPanel;

import org.uva.sea.ql.gui.qlform.QLContentPanel;
import org.uva.sea.ql.gui.qlform.QLExportButton;
import org.uva.sea.ql.gui.qlform.QLScrollBar;
import org.uva.sea.ql.gui.qlform.interpreter.VariableUpdater;

public class Renderer  {
	private final List<JPanel> questionPanelList;
	private final JPanel contentPanel = new QLContentPanel();
	private final JFrame frame;
	private final VariableUpdater varUpdater;
	private final static QLScrollBar scrollBar = new QLScrollBar();
	

	public Renderer(List<JPanel> questionPanelList, JFrame frame,VariableUpdater varUpdater) {
		this.frame = frame;
		this.questionPanelList = questionPanelList;
		this.varUpdater=varUpdater;
	}
	
	
	public void addQuestionsToPanel() {
		for (JPanel question : questionPanelList) {
			contentPanel.add(question, "align label,wrap");
		}
		scrollBar.add(contentPanel);
		frame.add(scrollBar, "align center,wrap");
		frame.add(QLExportButton.responsiveButton(questionPanelList, frame, varUpdater),"align center");
		frame.setVisible(true);
	}

	
	



}
<file_sep>package org.uva.sea.ql.ast.expr.binary.bool;

import org.uva.sea.ql.ast.expr.Expr;
import org.uva.sea.ql.ast.expr.binary.Binary;

public abstract class Bool extends Binary{
	
	protected Bool (Expr leftExpr,Expr rightExpr){
		super(leftExpr,rightExpr);
	}

}
