/** Copyright (C) Conformiq Software Ltd.
 * All rights reserved.
 *
 * Created Wed Aug 27 16:49:21 2008.
 *
 * @file TTCNScripter.java
 *
 * @author Conformiq Software Ltd.
 *
 *
 */
package com.conformiq.adaptation.ttcn;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.Vector;

import com.conformiq.adaptation.ttcn.Utils.Banner;
import com.conformiq.adaptation.ttcn.Utils.CheckPointInfo;
import com.conformiq.adaptation.ttcn.Utils.TemplateDefinition;
import com.conformiq.qtronic2.Checkpoint;
import com.conformiq.qtronic2.MetaDataDictionary;
import com.conformiq.qtronic2.NotificationSink;
import com.conformiq.qtronic2.QMLArray;
import com.conformiq.qtronic2.QMLBoolean;
import com.conformiq.qtronic2.QMLNumber;
import com.conformiq.qtronic2.QMLOptional;
import com.conformiq.qtronic2.QMLRecord;
import com.conformiq.qtronic2.QMLRecordType;
import com.conformiq.qtronic2.QMLRecordTypeField;
import com.conformiq.qtronic2.QMLString;
import com.conformiq.qtronic2.QMLUnionType;
import com.conformiq.qtronic2.QMLValue;
import com.conformiq.qtronic2.QMLValueVisitor;
import com.conformiq.qtronic2.ScriptBackend;
import com.conformiq.qtronic2.TimeStamp;
import com.conformiq.qtronic2.Checkpoint.CheckpointStatus;

public class TTCNScripter extends ScriptBackend
{
    public TTCNScripter()
    {
        this.mTestCaseIndex = 0;
        this.mTemplateIndex = 0;
        this.mTimeStamp = new TimeStamp();
        this.mTimeStamp.seconds = 0;
        this.mTimeStamp.nanoseconds = 0;
        this.mIsFirstStep = false;
        this.mGeneratedTemplates = new HashMap<QMLRecord, Integer>();
        this.mPostponedTemplates = new Vector<TemplateDefinition>();
        this.mTestCaseNames = new Vector<String>();
        this.collectedCheckpoints = null;
    }

    @Override
    public void setNotificationSink(NotificationSink sink)
    {
        mNotifications = sink;
    }

    @Override
    public boolean setMetaData(MetaDataDictionary dict)
    {
        mMetadata = dict;
        extractPortsMetaData();
        return true;
    }

    @Override
    public boolean setConfigurationOption(java.lang.String property,
            java.lang.String value)
    {
        return mConfiguration.setConfigurationOption(property, value);
    }

    @Override
    public boolean beginScript(String testsuiteName)
    {
        this.mTestsuiteName = testsuiteName;
        if (mNotifications != null)
        {
            mNotifications.notify("info", mScripterName
                + ": Export test cases for test design configuration "
                + testsuiteName);
        }
        String msg = null;
        if (mConfiguration.getSuiteFile().getAbsolutePath().equals(""))
        {
            msg = "TTCN-3 backend must be configured with a file name.";
        }
        else
        {
            try
            {
                mOut = new PrettyPrinter(new BufferedWriter(new FileWriter(
                        mConfiguration.getSuiteFile())));
            } catch (IOException e)
            {
                StringBuffer msgbuf = new StringBuffer();
                msgbuf.append("Failed to open file '");
                msgbuf.append(mConfiguration.getSuiteFile());
                msgbuf.append("' for writing TTCN-3 script.");
                msg = msgbuf.toString();
            }
        }
        if (msg != null)
        {
            if (mNotifications != null)
            {
                mNotifications.notify("error", mScripterName + ": " + msg);
            }
            else
            {
                System.err.println(msg);
            }
            return false;
        }
        {
            String[] desc = {
                "This file contains all test cases generated from the "
                    + "Conformiq '" + mConfiguration.getProjectName()
                    + "' project",
                "with '" + testsuiteName + "' design configuration." };
            String[] remark = {
                "WARNING! This file has been automatically generated using the",
                "Conformiq TTCN-3 scripting backend. DO NOT EDIT." };
            printHeader(mConfiguration.getSuiteFile(), desc, remark);
        }
        mOut.print("module ");
        mOut.print(mConfiguration.getSuiteModuleName());
        mOut.endl();
        mOut.print("{");
        mOut.endl();
        mOut.print(mIndent);
        mOut.block();

        if (mConfiguration.getTestSystemModuleName() != null)
        {
        	mOut.print("import from ");
        	mOut.print(mConfiguration.getTestSystemModuleName());
        	mOut.print(" all;");
        	mOut.endl();
        }

        if (mConfiguration.getDataTypesModuleName() != null)
        {
        	mOut.print("import from ");
        	mOut.print(mConfiguration.getDataTypesModuleName());
        	mOut.print(" all;");
        	mOut.endl();
        }

        mOut.print("/* Customized imports begin */");
        mOut.endl();
        mOut.print(mConfiguration.getExtraImports());
        mOut.endl();
        mOut.println("/* Customized imports end */");
        mOut.emptyline();

        mOut.print("modulepar float " + mSlackVarName + " := ");
        mOut.print(mConfiguration.getCommSlack());
        mOut.println(";");
        mOut.emptyline();

        printDebugModulepars();

        mOut.emptyline();
        // print out the test harness template
        try
        {
            // should the harness template be written
            if (mConfiguration.isGenerateTestHarness())
            {
                PrettyPrinter harness = buildPrettyPrinter(mConfiguration
                        .getTestHarnessFile(), "harness template", false);
                if (harness != null)
                {
                    dumpTestHarness(harness);
                    if (mNotifications != null)
                    {
                        mNotifications.notify("info", mScripterName
                            + ": Generated TTCN-3 test harness template to "
                            + "<hyperlink=\""
                            + mConfiguration.getTestHarnessFile()
                                    .getAbsolutePath()
                            + "\">"
                            + mConfiguration.getTestHarnessFile()
                                    .getAbsolutePath() + "</hyperlink>.");
                    }
                }
            }
        } catch (Exception e)
        {
            mOut.print("/* EXCEPTION CAUGHT */");
            mOut.endl();
            if (mNotifications != null)
            {
                mNotifications.notify("error", mScripterName
                    + ": Caught exception while rendering TTCN test harness"
                    + " template. Please reload model and try again ("
                    + e.getMessage() + ")");
            }
            return false;
        }

        if (mConfiguration.isGenerateDataTypes())
        {
            /* First dump all the types used in the module. */
            try
            {
                dumpDataTypes();
            } catch (Exception e)
            {
                mOut.print("/* EXCEPTION CAUGHT */");
                mOut.endl();
                if (mNotifications != null)
                {
                    mNotifications.notify("error", mScripterName
                        + ": Caught exception while "
                        + "rendering TTCN type definitions. Please reload "
                        + "model and try again (" + e.getMessage() + ")");
                }
                return false;
            }
        }

        if (mConfiguration.isGenerateTestSystemFile())
        {
            /* First dump all the types used in the module. */
            try
            {
                dumpTestComponentFile();
            } catch (Exception e)
            {
                mOut.print("/* EXCEPTION CAUGHT */");
                mOut.endl();
                if (mNotifications != null)
                {
                    mNotifications.notify("error", mScripterName
                        + ": Caught exception while "
                        + "rendering TTCN type definitions. Please reload "
                        + "model and try again (" + e.getMessage() + ")");
                }
                return false;
            }
        }

        deleteCopies();
        mTemplateIndex = 0;
        mTestCaseIndex = 0;
        mIsFirstStep = false;
        return true;
    }

    @Override
    public boolean beginCase(String testcaseName)
    {
        collectedCheckpoints = new LinkedList<CheckPointInfo>();
        mCaseStepIndex = 0;
        mIsFirstStep = true;
        mTestCaseIndex++;

        Banner banner = new Banner();
        banner.addTag("desc", "Generated test case #" + mTestCaseIndex);
        banner.print(mOut);
        mOut.print("testcase ");
        mCrrentTestCaseName = recordAndRenderTestCaseName(testcaseName);
        mOut.print(mCrrentTestCaseName);
        mOut.println("()");
        mOut.print("runs on ");
        mOut.print(mConfiguration.getRunsOnName());
        if (mConfiguration.getSystemTypeName() != null
            && !mConfiguration.getSystemTypeName().equals(""))
        {
            mOut.print(" system ");
            mOut.print(mConfiguration.getSystemTypeName());
        }
        mOut.endl();
        mOut.print("{");
        mOut.endl();

        mOut.print(mIndent);
        mOut.block();
        printLog(LogMessageType.DEBUG, "Starting execution of test case: '"
            + mCrrentTestCaseName + "'");

        mOut.print("var float " + mOldTimerName + " := "
            + Utils.TimeStampToString(mTimeStamp) + ";");
        mOut.endl();

        if (!mConfiguration.getDefaultName().equals(""))
        {
            mOut.print("var default " + mConfiguration.getDefaultRefName()
                + ";");
            mOut.endl();
        }

        if (!mConfiguration.getStartHook().equals(""))
        {
            mOut.emptyline();
            mOut.print("/***** set up test configuration, TTCN-3 harness, "
                + "and adapter *****/");
            mOut.endl();
            mOut.print(mConfiguration.getFunctionsPrefix()
                + mConfiguration.getStartHook());
            mOut.print(";");
            mOut.endl();
        }

        if (!mConfiguration.getDefaultName().equals(""))
        {
            mOut.println("// default handles waiting beyond maximum response "
                + "time and reception of any");
            mOut.println("// other than the expected message with setting a"
                + " fail verdict and stopping the test");
            mOut.print(mConfiguration.getDefaultRefName() + " := activate(");
            mOut.print(mConfiguration.getDefaultName());
            mOut.print(");");
            mOut.endl();
        }

        return true;
    }

    // @Override
    public void caseProbability(double probability)
    {
    }

    @Override
    public boolean checkpointInfo(Checkpoint checkpoint, int status,
            TimeStamp ts)
    {
        if (!mIsFirstStep || status == CheckpointStatus.UNCOVERED
            || status == CheckpointStatus.MAYBE_COVERED)
        {
            return true;
        }
        collectedCheckpoints.offer(new CheckPointInfo(checkpoint, status, ts));
        return true;
    }

    @Override
    public boolean endCase()
    {
    	printCheckpoints();
        mOut.emptyline();
        mOut.println("setverdict(pass);");

        /*
         * Default is used only if the provided name is different from "", so if
         * the default is not used let's not deactivate it either.
         */
        if (!mConfiguration.getDefaultName().equals(""))
        {
            mOut.print("deactivate(" + mConfiguration.getDefaultRefName()
                + ");");
            mOut.endl();
        }

        if (!mConfiguration.getEndHook().equals(""))
        {
            mOut.emptyline();
            mOut.print("/***** "
                + "tear down test configuration, TTCN-3 harness, and adapter"
                + " *****/");
            mOut.endl();
            mOut.print(mConfiguration.getFunctionsPrefix()
                + mConfiguration.getEndHook());
            mOut.print(";");
            mOut.endl();
        }
        mOut.emptyline();
        printLog(LogMessageType.DEBUG, "Ending execution of "
            + mCrrentTestCaseName);
        mOut.resume();
        mOut.print("}");
        mOut.endl();

        /* Generate templates out of the datums stored in the TestStep. */
        printTemplates();

        mPostponedTemplates.clear();
        return true;
    }

    @Override
    public boolean endScript()
    {
        prindAltstepDefaultDecl();
        printSleepFunction();
        mOut.emptyline();
        printDebugMessageTypeEnum();
        mOut.emptyline();
        printDebugFunctionDecl();
        printControl();
        mOut.resume();
        mOut.print("}");
        mOut.endl();
        try
        {
            mOut.flush();
            mOut.close();
        } catch (Exception e)
        {
            if (mNotifications != null)
            {
                mNotifications.notify("error", mScripterName + ": "
                    + e.toString());
            }
        }
        mOut = null;

        StringBuffer ss = new StringBuffer();
        ss.append("Generated TTCN-3 script to <hyperlink=\"");
        ss.append(mConfiguration.getSuiteFile().getAbsolutePath());
        ss.append("\">");
        ss.append(mConfiguration.getSuiteFile().getAbsolutePath());
        ss.append("</hyperlink>.");
        if (mNotifications != null)
        {
            mNotifications.notify("info", mScripterName + ": " + ss.toString());
        }
        else
        {
            System.out.println(ss.toString());
        }
        mTestCaseNames.clear();
        return true;
    }

    @Override
    public boolean testStep(QMLRecord r, String thread, String port,
            boolean isFromTester, TimeStamp ts)
    {
        /*
         * We have an altstep defined:
         * 
         * altstep CQDefaultAlt() runs on SystemType { [] any port.receive {
         * mytimer.stop; setverdict(fail); stop; } [] mytimer.timeout {
         * setverdict(fail); stop; } }
         * 
         * which removes the need for "[] any port.receive" and timeout from alt
         * statements.
         */
        mCaseStepIndex++;
        mOut.endl();
        mOut.emptyline();
        mOut.println("/***** Step " + mCaseStepIndex + "; t = "
            + Utils.TimeStampToString(ts) + " *****/");
        mOut.endl();

        printLog(LogMessageType.DEBUG, mCrrentTestCaseName + ": Step "
            + mCaseStepIndex);
        printCheckpoints();

        // Remember the datum so that we can generate a template out of it.
        // Generate a new template only if it has not been generated before.
        String name;
        Integer idx = mGeneratedTemplates.get(r);
        if (idx != null)
        {
            StringBuffer ss = new StringBuffer();
            ss.append(r.getName());
            ss.append("Template");
            ss.append(idx);
            name = ss.toString();
        }
        else
        {
            ++mTemplateIndex;
            StringBuffer ss = new StringBuffer();
            ss.append(r.getName());
            ss.append("Template");
            ss.append(mTemplateIndex);
            name = ss.toString();

            if (!isFromTester)
            {
                name = "expected" + name;
            }
            mPostponedTemplates.add(
                    new TemplateDefinition(r.getName(), name, r));
            mGeneratedTemplates.put(r, mTemplateIndex);
        }

        if (isFromTester)
        {
            /*
             * Send datum to SUT. Generate:
             * 
             * mytimer.start(<send time>); alt { [] mytimer.timeout { // OK } }
             * <port>.send(template_<index>);
             */
            if (ts.seconds > mTimeStamp.seconds
                || ts.nanoseconds > mTimeStamp.nanoseconds)
            {
                mOut.print(mConfiguration.getTimerName());
                mOut.print(".start(");
                mOut.print(ts.seconds);
                mOut.print(".");
                mOut.print(ts.nanoseconds);
                mOut.print(" - " + mOldTimerName + ");");
                mOut.endl();
                mOut.print("alt");
                mOut.endl();
                mOut.print("{");
                mOut.endl();
                mOut.print(mIndent);
                mOut.block();
                mOut.print("[] ");
                mOut.print(mConfiguration.getTimerName());
                mOut.print(".timeout");
                mOut.endl();
                mOut.print("{");
                mOut.endl();
                mOut.print("}");
                mOut.endl();
                mOut.resume();
                mOut.print("}");
                mOut.endl();
                mOut.print(mConfiguration.getTimerName());
                mOut.print(".stop;");
                mOut.endl();
            }
            mOut.endl();
            mOut.print(mConfiguration.getFunctionsPrefix() + "send_");
            mOut.print(r.getName());
            mOut.print("_to_");
            mOut.print(Utils.makeValidTTCN3Identifier(port));
            mOut.print("(");
            mOut.print("m_" + name);
            mOut.print(");");
            mOut.endl();
        }
        else
        {
            final String timeStamp = "" + ts.seconds + "." + ts.nanoseconds;
            if (!Utils.EqualTimeStamps(this.mTimeStamp, ts))
            {
                mOut.println(mConfiguration.getFunctionsPrefix()
                    + mSleepFunctionName + "(" + timeStamp + " - "
                    + mOldTimerName + ");");
            }
            mOut.println(mConfiguration.getTimerName() + ".start("
                + mSlackVarName + ");");
            mOut.println("// Note: In below receive " 
            		+ mConfiguration.getDefaultRefName() + "() is active!");
            mOut.print(mConfiguration.getFunctionsPrefix() + "receive_");
            mOut.print(r.getName());
            mOut.print("_from_");
            mOut.print(Utils.makeValidTTCN3Identifier(port));
            mOut.print("(");
            mOut.print("m_" + name);
            mOut.print(");");
            mOut.endl();
            mOut.print(mConfiguration.getTimerName());
            mOut.print(".stop;");
            mOut.endl();
        }

        if (!Utils.EqualTimeStamps(this.mTimeStamp, ts))
        {
            mOut.print(mOldTimerName + " := ");
            mOut.print(ts.seconds);
            mOut.print(".");
            mOut.print(ts.nanoseconds);
            mOut.println(";");
        }

        this.mTimeStamp.seconds = ts.seconds;
        this.mTimeStamp.nanoseconds = ts.nanoseconds;
        this.collectedCheckpoints = new LinkedList<CheckPointInfo>();
        return true;
    }

    @Override
    public boolean internalCommunicationsInfo(QMLRecord datum, String sender,
            String receiver, String port, TimeStamp time)
    {
        return true;
    }

    @Override
    public boolean trace(String message, TimeStamp time)
    {
        return true;
    }

    private PrettyPrinter buildPrettyPrinter(final File f, final String desc,
            final boolean overWrite)
    {
        String name = f.getAbsolutePath();
        if (f.exists() && !f.isDirectory() && !overWrite)
        {
            if (mNotifications != null)
            {
                mNotifications.notify("info", mScripterName + ": File  "
                    + "<hyperlink=\"" + name + "\">" + name + "</hyperlink>."
                    + " exists, NOT overwriting it.");
            }
            return null;
        }
        if (name.equals("") || f.isDirectory())
        {
            mNotifications.notify("error",
                    "TTCN-3 backend must be configured with a valid " + desc
                        + " file name.");
            return null;
        }
        try
        {
            return new PrettyPrinter(new BufferedWriter(new FileWriter(f)));
        } catch (IOException e)
        {
            mNotifications.notify("error", "Failed to open file '" + name
                + "' for writing" + desc + ".");
            return null;
        }
    }

    private void dumpTestComponentFile() throws Exception
    {
        String msg = null;
        Exception rethrowMe = null;
        PrettyPrinter oldOut = mOut;
        if (mConfiguration.getTestSystemFile().getAbsolutePath().equals(""))
        {
            msg = "TTCN-3 backend must be configured with a test system file "
                + "name.";
        }
        else
        {
            try
            {
                mOut = new PrettyPrinter(new BufferedWriter(new FileWriter(
                        mConfiguration.getTestSystemFile())));
            } catch (IOException e)
            {
                StringBuffer msgbuf = new StringBuffer();
                msgbuf.append("Failed to open file '");
                msgbuf.append(
                        mConfiguration.getTestSystemFile().getAbsolutePath());
                msgbuf.append("' for writing test system information.");
                msg = msgbuf.toString();
                rethrowMe = e;
            }
        }
        if (msg != null)
        {
            if (mNotifications != null)
            {
                mNotifications.notify("error", msg);
            }
            else
            {
                System.err.println(msg);
            }
            mOut = oldOut;
            // Pass the exception forward for proper error handling further
            // up the call stack.
            throw (rethrowMe);
        }
        {
            String[] desc = {
                "This file contains port type definitions and test component "
                    + "generated by Conformiq",
                "with '" + mTestsuiteName + "' design configuration for '"
                    + mConfiguration.getProjectName() + "' project." };
            String[] remark = {
                "WARNING! This file has been automatically generated using the",
                "Conformiq TTCN-3 scripting backend. DO NOT EDIT." };
            printHeader(mConfiguration.getDataTypesFile(), desc, remark);
        }
        mOut.print("module ");
        mOut.print(mConfiguration.getTestSystemModuleName());
        mOut.endl();
        mOut.print("{");
        mOut.endl();
        mOut.print(mIndent);
        mOut.block();

        if (mConfiguration.getDataTypesModuleName() != null)
        {
        	mOut.println("import from "
        			+ mConfiguration.getDataTypesModuleName() + " all;");
        	mOut.emptyline();
        }

        // system mapping
        if (!mConfiguration.getSystemTypeName().equals("") && !mConfiguration.isEptfEnable())
        {
            mOut.emptyline();
            Banner banner = new Banner();
            banner.addTag("desc", new String[] {
                "This TTCN-3 component type specifies the interface of the",
                "test cases towards the SUT more specifically the SUT "
                    + "adapter." });
            banner.print(mOut);

            mOut.print("type component ");
            mOut.print(mConfiguration.getSystemTypeName());
            mOut.endl();
            mOut.println("{");
            mOut.print(mIndent);
            mOut.block();
            mOut.println("// Add all port instances here");
            mOut.resume();
            mOut.println("}");
        }

        try
        {
            if (mConfiguration.isGenerateTestSystemFile())
            {
                for (Port p : externalPorts)
                {
                    if (mConfiguration.isEptfEnable() &&
                            (p.name.equals(mConfiguration.getEptfInboundPort()) || 
                             p.name.equals(mConfiguration.getEptfOutboundPort()))
                        )
                    {
                    }
                    else
                    {
                        mOut.print("type port ");
                        mOut.print(p.name);
                        mOut.print("Port message");
                        mOut.endl();
                        mOut.print("{");
                        mOut.endl();
                        mOut.print(mIndent);
                        mOut.block();
                        for (QMLRecordType record : p.records)
                        {
                            String dir = p.isInbound ? "in" : "out";
                            if (mConfiguration.isEptfBidirectionalPort())
                                dir = "inout";
                            mOut.println(dir + " " + record.getTypeName() + ";");
                        }
                        mOut.resume();
                        mOut.print("}");
                        if (!mConfiguration.getPortExtensions().equals(""))
                        {
                            mOut.print(" with {extension \"");
                            mOut.print(mConfiguration.getPortExtensions());
                            mOut.print("\"}");
                        }
                        mOut.emptyline();
                    }
                }
            }
            mOut.emptyline();
            Banner banner = new Banner();
            banner.addTag("desc", "The test component (MTC) on which all "
                + "generated test cases run on");
            banner.print(mOut);
            mOut.print("type component ");
            mOut.print(mConfiguration.getRunsOnName());
            if (!mConfiguration.getExtendsComponent().equals(""))
            {
                mOut.print(" extends ");
                mOut.print(mConfiguration.getExtendsComponent());
            }

            mOut.endl();
            mOut.print("{");
            mOut.endl();
            mOut.print(mIndent);
            mOut.block();
            for (Port p : externalPorts)
            {
                mOut.print("port ");
                mOut.print(p.name);
                mOut.print("Port ");
                mOut.print(p.name);
                mOut.print(";");
                mOut.endl();

            }
            mOut.print("timer ");
            mOut.print(mConfiguration.getTimerName());
            mOut.print(" := 0.0;");
            mOut.endl();
            mOut.resume();
            mOut.print("}");
            mOut.endl();
            mOut.resume();

            mOut.print("}");
            mOut.endl();
            mOut.flush();
            mOut.close();
            mOut = oldOut;
        } catch (Exception e)
        {
            mOut.flush();
            mOut.close();
            mOut = oldOut;
        }
        mNotifications.notify("info", mScripterName
            + ": Generated TTCN-3 port and component types file "
            + "<hyperlink=\""
            + mConfiguration.getTestSystemFile().getAbsolutePath() + "\">"
            + mConfiguration.getTestSystemFile().getAbsolutePath()
            + "</hyperlink>.");
    }

    /**
     * prints out the test harness template, that contains:
     * 
     * - import from CQTypes;
     * 
     * - type component for the harness system
     * 
     * - MTC component the tests should run on
     * 
     * - harness alt step
     * 
     * - start and end test hook calls
     * 
     * - port and message mapping functions
     */
    private void dumpTestHarness(final PrettyPrinter pp) throws Exception
    {
        assert (mMetadata != null);

        PrettyPrinter oldOut = this.mOut;
        this.mOut = pp;
        {

            String[] desc = {
                "This is a template file with TTCN-3 function stubs for the "
                    + "implementation ",
                "of test harness code for the test suites generated from the "
                    + "Conformiq '",
                mConfiguration.getProjectName() + "' project." };
            String[] remark = {
                "All function definitions must be edited as instructed in "
                    + "their comments in",
                " order for the test suite to execute properly." };
            printHeader(mConfiguration.getTestHarnessFile(), desc, remark);
        }
        mOut.print("module ");
        mOut.print(Utils.buildModuleNameFromFileName(
                mConfiguration.getTestHarnessFile()));
        mOut.endl();
        mOut.print("{");
        mOut.endl();

        // import all data types
        if (mConfiguration.getDataTypesModuleName() != null)
        {
        	mOut.print(mIndent);
        	mOut.print("import from ");
        	mOut.print(mConfiguration.getDataTypesModuleName());
        	mOut.print(" all;");
        	mOut.endl();
        }

        if (mConfiguration.getTestSystemModuleName() != null) 
        {
        	mOut.print(mIndent);
        	mOut.print("import from ");
        	mOut.print(mConfiguration.getTestSystemModuleName());
        	mOut.print(" all;");
        	mOut.endl();
        }
        mOut.emptyline();
        // debug function
        mOut.print(mIndent);
        mOut.block();

        // MTC port definitions
        if (!mConfiguration.getRunsOnName().equals(""))
        {
            mOut.resume();
            // default start and stop functions
            mOut.print(mIndent);
            mOut.block();
            if (!mConfiguration.getStartHook().equals("") && !mConfiguration.isEptfEnable())
            {
                mOut.emptyline();
                Banner banner = new Banner();
                banner.addTag("desc", new String[] {
                    "This function sets up the test configuration, maps all "
                        + "mtc",
                    "to system component ports, and configures (if needed)",
                    "TTCN-3 harness and test system adapter" });
                banner.print(mOut);
                mOut.print("function ");
                mOut.print(mConfiguration.getFunctionsPrefix()
                    + mConfiguration.getStartHook());
                mOut.print(" runs on ");
                mOut.print(mConfiguration.getRunsOnName());
                mOut.endl();
                mOut.print("{");
                mOut.endl();
                mOut.print(mIndent);
                mOut.block();
                mOut.println("// Specify here map operations between MTC and "
                    + "abstract test");
                mOut.println("// system interface or update and uncomment "
                    + "generated code below");
                for (Port p : externalPorts)
                {
                    mOut.println("// map(" + mConfiguration.getRunsOnName()
                        + ": " + p.name + ", system: <some port>);");
                }
                if (mConfiguration.isDoLogCQInfoMessages())
                {
                	mOut.println("// Remove or comment the following generated "
                			+ "code");
                }
                printLog(LogMessageType.INFO, "Warning: "
                    + mConfiguration.getFunctionsPrefix()
                    + mConfiguration.getStartHook() + ": "
                    + "function is not implemented");
                mOut.resume();
                mOut.println("}");
            }
            if (!mConfiguration.getEndHook().equals("") && !mConfiguration.isEptfEnable())
            {

                Banner banner = new Banner();
                banner.addTag("desc", new String[] {
                    "This function tears down the test configuration",
                    "and unmaps all mtc to system component ports" });
                banner.print(mOut);
                mOut.print("function  ");
                mOut.print(mConfiguration.getFunctionsPrefix()
                    + mConfiguration.getEndHook());
                mOut.print(" runs on ");
                mOut.println(mConfiguration.getRunsOnName());
                mOut.println("{");
                mOut.print(mIndent);
                mOut.block();
                mOut.println("//Specify here unmap operations between MTC and"
                    + " abstract test");
                mOut.println("// system interface or update and uncomment"
                    + " generated code below");

                for (Port p : externalPorts)
                {
                    mOut.println("// unmap(" + mConfiguration.getRunsOnName()
                        + ": " + p.name + ", system: <some port>);");
                }
                if (mConfiguration.isDoLogCQInfoMessages())
                {
                	mOut.println("// Remove or comment the following generated "
                			+ "code");
                }
                printLog(LogMessageType.INFO, "Warning: "
                    + mConfiguration.getFunctionsPrefix()
                    + mConfiguration.getEndHook() + ": "
                    + "function is not implemented");
                mOut.resume();
                mOut.println("}");
            }
            mOut.resume();
            // port mapping
            try
            {
                mOut.print(mIndent);
                mOut.block();

                for (Port p : externalPorts)
                {
                    for (QMLRecordType type : p.records)
                    {
                    	String record = type.getTypeName();
                        String argName = null;
                        if (p.isInbound)
                        {
                            argName = "p_" + "expected" + record;
                        }
                        else
                        {
                            argName = "p_" + record;
                        }
                        // (p.isInbound ? "tmplToMatch" : "msgToSend");
                        String functionName = 
                            mConfiguration.getFunctionsPrefix()
                            + (p.isInbound ? "receive_" : "send_")
                            + record
                            + (p.isInbound ? "_from_" : "_to_") + p.name;
                        String functionDecl = "function " + functionName
                            + "(template " + record + " " + argName + ")";
                        mOut.emptyline();
                        Banner banner = new Banner();
                        if (p.isInbound)
                        {
                            banner.addTag("desc", new String[] {
                                "This function receives a TTCN-3 value "
                                    + "corresponding to a " + record,
                                "via the abstract test system interface from "
                                    + "the SUT, performs any",
                                "manipulation and transformation needed to "
                                    + "convert it to a " + record,
                                "value, and then attempts to match it to the "
                                    + argName + " generated by CQ Designer" });
                            banner.addTag("param", new String[] { argName
                                + "Expected data generated by CQ Designer" });
                            // * from the SUT to */
                        }
                        else
                        {
                            banner.addTag("desc", new String[] {
                                "This function performs manipulation needed"
                                    + " and" + " sends a " + argName,
                                "via the abstract test interface to the"
                                    + " SUT." });
                            banner.addTag("param", argName
                                + " Message data generated by CQ Designer"
                                + "to be sent to the SUT");
                        }
                        banner.print(mOut);
                        mOut.println(functionDecl + " runs on "
                            + mConfiguration.getRunsOnName());
                        mOut.println("{");
                        mOut.print(mIndent);
                        mOut.block();

                        if (p.isInbound)
                        {
                            mOut.println("//Steps that need to be implemented"
                                + "    here are:");
                            mOut.println("//1. receive and store (any) TTCN-3"
                                + " data value via TTCN-3 port which "
                                + "corresponds to the " + p.name + " model "
                                + "port");
                            mOut.println("// var <T3_" + record
                                + "Type> v_recvT3" + record + ";");
                            mOut.println("// " + p.name + ".receive(<T3_"
                                + record + "Type>:?) -> value v_recvT3"
                                + record + ";");
                            mOut.println("// 2. replace real with symbolic "
                                + "values (if any) in the received TTCN-3 data"
                                + " value");
                            mOut.println("// 3. transform data from a TTCN-3 "
                                + "to " + record + " data value (if needed)");
                            mOut.println("// var" + record + "v_recv" + record
                                + " = " + "f_transform" + record
                                + "T3toCQ(v_recvT3" + record + ");");
                            mOut.println("// 4. set the verdict to fail if if"
                                + " there is a mismatch of the "
                                + "transformed value and " + argName);
                            mOut.println("// if ( !match( v_recv" + record
                                + " " + argName + ") {");
                            mOut.println("//  log(CQ_INFO: " + functionName
                                + ": FAIL: Mismatch in received and expected "
                                + record + " values. Stopping test case.â€�);");
                            mOut.println("//   setverdict(fail);");
                            mOut.println("//   " 
                            		+ mConfiguration.getFunctionsPrefix() 
                            		+ mConfiguration.getEndHook()
                            		+ ";");
                            mOut.println("//   stop; }");
                            if (mConfiguration.isEptfEnable())
                            {
                                if (p.name.equals(mConfiguration.getEptfInboundPort())
                                    || p.name.equals(mConfiguration.getEptfOutboundPort()))
                                {
                                    mOut.println("     EPTF_MBT_TESTER_PCO.receive("+argName+") from vc_lgen;");
                                }
                                else
                                {
                                    mOut.println("     " + p.name + ".receive("+argName+");");
                                }
                            }

                        }
                        else
                        {
                            mOut.println("// Steps that need to be implemented"
                                + " here are:");
                            mOut.println("// (modify and uncomment example "
                                + "code as needed)");
                            mOut.println("// 1. transform data from a "
                                + record + " to the TTCN-3 data value"
                                + " used by the test harness (if needed)");
                            mOut.println("// var <T3" + record + "Type> v_T3"
                                + record + " := " + "f_transform" + record
                                + "CQtoT3(" + argName + ");");
                            mOut.println("// 2. replace symbolic values "
                                + "(if any) with real values in TTCN-3"
                                + " data value");
                            mOut.println("// 3. send TTCN-3 data value via "
                                + "TTCN-3 port which corresponds to" + p.name
                                + "model port");
                            mOut.println("// " + p.name + ".send(v_T3" + record
                                + ");");
                            if (mConfiguration.isEptfEnable())
                            {
                                if (p.name.equals(mConfiguration.getEptfInboundPort())
                                    || p.name.equals(mConfiguration.getEptfOutboundPort()))
                                {
                                    mOut.println("     EPTF_MBT_TESTER_PCO.send("+argName+") to vc_lgen;");
                                }
                                else
                                {
                                    mOut.println("     " + p.name + ".send("+argName+");");
                                }
                            }
                        }
                        if (mConfiguration.isDoLogCQInfoMessages())
                        {
                        	mOut.println("// Remove or comment the following "
                        			+ "generated code");
                        }
                        printLog(LogMessageType.INFO, "Warning: "
                            + functionName + ": "
                            + "function is not implemented)");
                        mOut.resume();
                        mOut.println("}");
                    }
                }
                mOut.resume();
            } catch (Exception e)
            {
                mOut.print("/* EXCEPTION CAUGHT in dumpTestHarness */");
                mOut.flush();
                mOut.close();
                this.mOut = oldOut;
                throw e;
            }
        }
        // Must close the module block.
        mOut.print("}");
        mOut.endl();
        mOut.flush();
        mOut.close();
        this.mOut = oldOut;
    }

    private void dumpDataTypes() throws Exception
    {
        assert (mMetadata != null);

        PrettyPrinter oldOut = mOut;
        String msg = null;
        Exception rethrowMe = null;
        if (mConfiguration.getDataTypesFile().getAbsolutePath().equals(""))
        {
            msg = "TTCN-3 backend must be configured with a data type file "
                + "name.";
        }
        else
        {
            try
            {
                mOut = new PrettyPrinter(new BufferedWriter(new FileWriter(
                        mConfiguration.getDataTypesFile())));
            } catch (IOException e)
            {
                StringBuffer msgbuf = new StringBuffer();
                msgbuf.append("Failed to open file '");
                msgbuf.append(mConfiguration.getDataTypesFile()
                        .getAbsolutePath());
                msgbuf.append("' for writing data types.");
                msg = msgbuf.toString();
                rethrowMe = e;
            }
        }
        if (msg != null)
        {
            if (mNotifications != null)
            {
                mNotifications.notify("error", msg);
            }
            else
            {
                System.err.println(msg);
            }
            mOut = oldOut;
            // Pass the exception forward for proper error handling further
            // up the call stack.
            throw (rethrowMe);
        }
        {
            String[] desc = {
                "This file contains all data type definitions exported from "
                    + "the Conformiq " + mConfiguration.getProjectName() 
                    + "' project.",
                "with '" + mTestsuiteName + "' design configuration.'"};
            String[] remark = {
                "WARNING! This file has been automatically generated using the",
                "Conformiq TTCN-3 scripting backend. DO NOT EDIT." };
            printHeader(mConfiguration.getDataTypesFile(), desc, remark);
        }
        mOut.print("module ");
        mOut.print(Utils.buildModuleNameFromFileName(mConfiguration
                .getDataTypesFile()));
        mOut.endl();
        mOut.print("{");
        mOut.endl();
        mOut.print(mIndent);
        mOut.block();
        try
        {
            if (mConfiguration.isGenerateDataTypes())
            {
                final Set<QMLRecordType> alreadyDumped = 
                	new HashSet<QMLRecordType>();
                final Queue<QMLRecordType> workList = 
                	new LinkedList<QMLRecordType>();
                final Set<String> arrays = new HashSet<String>();

                for (Port p : externalPorts)
                {
                    for (QMLRecordType t : p.records)
                    {
                        workList.offer(t);
                    }
                }
                while (!workList.isEmpty())
                {
                    QMLRecordType type = workList.poll();
                    if (alreadyDumped.contains(type) ||
                        (
                           mConfiguration.isEptfEnable() &&
                           type.getTypeName().length() >= 5 &&
                           type.getTypeName().substring(0, 5).equals("EPTF_")
                         )    
                       )
                    {
                        // Skipping type generation
                    }
                    else
                    {
                        alreadyDumped.add(type);
                        if (type instanceof QMLUnionType)
                        {
                            mOut.print("type union ");
                        }
                        else
                        {
                            mOut.print("type record ");
                        }
                        mOut.println(type.getTypeName());
                        mOut.println("{");
                        mOut.print(mIndent);
                        mOut.block();
                        for (int i = 0; i < type.getNumberOfFields(); i++)
                        {
                            QMLRecordTypeField field = type.getField(i);
                            TTCNTypeName v = new TTCNTypeName(workList,
                                    alreadyDumped, arrays);
                            field.getType().accept(v);
                            if (field.getType() instanceof QMLRecordType)
                            {
                                String fieldType = 
                                    Utils.makeValidTTCN3Identifier(
                                            field.getType().getTypeName());
                                if (!alreadyDumped.contains(fieldType))
                                {
                                    workList.offer(
                                    		(QMLRecordType)field.getType());
                                }
                            }
                            assert (!v.getName().equals(""));
                            if (i != 0)
                            {
                                mOut.print(",");
                                mOut.endl();
                            }
                            mOut.print(v.getName());
                            mOut.print(" ");
                            mOut.print(Utils.makeValidTTCN3Identifier(
                                    field.getFieldName()));
                            if (v.getOptional())
                            {
                                mOut.print(" optional");
                            }
                        }
                        mOut.resume();
                        mOut.endl();
                        mOut.print("}");
                        mOut.endl();
                    }

                }
                Iterator<String> it = arrays.iterator();
                while (it.hasNext())
                {
                    String x = it.next();
                    // TODO: reconsider changing this because now both
                    // TTCNTypeName class and this piece of code here has
                    // to know how array names are constructed.
                    mOut.print("type record of ");
                    mOut.print(x);
                    mOut.print(" ");
                    mOut.print(x);
                    mOut.print("Array;");
                    mOut.endl();
                }
            }
            /*
             * altstep CQDefaultAlt() runs on SystemType { [] any port.receive {
             * mytimer.stop; setverdict(fail); stop; } [] mytimer.timeout {
             * setverdict(fail); stop; } }
             */
            // Must close the module block.
            mOut.resume();
            mOut.print("}");
            mOut.endl();
            mOut.flush();
            mOut.close();
            mOut = oldOut;
        } catch (Exception e)
        {
            mOut.flush();
            mOut.close();
            mOut = oldOut;
        }
        mNotifications.notify("info", mScripterName
            + ": Generated TTCN-3 type definitions " + "<hyperlink=\""
            + mConfiguration.getDataTypesFile() + "\">"
            + mConfiguration.getDataTypesFile() + "</hyperlink>.");
    }

    private void printControl()
    {
        mOut.print("control");
        mOut.endl();
        mOut.print("{");
        mOut.endl();
        mOut.print(mIndent);
        mOut.block();
        for (int i = 1; i <= mTestCaseIndex; i++)
        {
            mOut.print("execute(");
            mOut.print(getTestCaseName(i));
            mOut.print("());");
            mOut.endl();
        }
        mOut.resume();
        mOut.print("}");
        mOut.endl();
        mOut.emptyline();
    }

    public void reportError(String msg)
    {
        mNotifications.notify("error", mScripterName + ": " + msg);
    }

    public void reportInfo(String msg)
    {
        mNotifications.notify("info", mScripterName + ": " + msg);
    }

    private void extractPortsMetaData()
    {
        final String portinfo = "portinfo:";
        String key = mMetadata.getNextKey(portinfo);
        externalPorts = new LinkedList<Port>();
        while (key != null)
        {
            String data = key;
            if (!data.startsWith(portinfo))
            {
                break;
            }

            final QMLValue definition = mMetadata.get(key);
            assert (definition != null);
            QMLArray tuple = (QMLArray) definition;
            if (tuple != null)
            {
                Port port = new Port(key, tuple);
                externalPorts.add(port);
            }
            key = mMetadata.getNextKey(key);
        }
    }

    private void printSleepFunction()
    {
        Banner banner = new Banner();
        banner.addTag("desc",
                "This function blocks the execution for the specified time");
        banner.addTag("param", "p_duration The specified time in seconds");
        banner.print(mOut);
        mOut.println("function " + mConfiguration.getFunctionsPrefix()
            + mSleepFunctionName + "(float p_duration)");
        mOut.println("{");
        mOut.print(mIndent);
        mOut.block();
        mOut.println("timer t;");
        mOut.println("t.start(p_duration);");
        mOut.println("t.timeout; // Note that any active default behavior "
            + "may interrupt this waiting!");
        mOut.endl();
        mOut.resume();
        mOut.print("}");
        mOut.endl();
    }

    private void printAltStepBody()
    {
        mOut.print(mIndent);
        mOut.block();
        if (!mConfiguration.isEptfEnable())
        {
        mOut.print("[] any port.receive");
        mOut.endl();
        mOut.print("{");
        mOut.endl();
        mOut.print(mIndent);
        mOut.block();
        mOut.print(mConfiguration.getTimerName());
        mOut.print(".stop;");
        mOut.endl();
        mOut.print("setverdict(fail);");
        mOut.endl();
        printLog(LogMessageType.DEBUG, mConfiguration.getDefaultName()
            + ": FAIL: Stopping test case after receiving unexpected "
            + "message in default: " + mConfiguration.getDefaultName() + "!");
        if (!mConfiguration.getEndHook().equals(""))
        {
            mOut.print(mConfiguration.getFunctionsPrefix()
                + mConfiguration.getEndHook());
            mOut.print(";");
            mOut.endl();
        }
        mOut.print("stop;");
        mOut.endl();
        mOut.resume();
        mOut.print("}");
        mOut.endl();
        }
        mOut.print("[] ");
        mOut.print(mConfiguration.getTimerName());
        mOut.print(".timeout");
        mOut.endl();
        mOut.print("{");
        mOut.endl();
        mOut.print(mIndent);
        mOut.block();
        mOut.print("setverdict(fail);");
        mOut.endl();
        printLog(LogMessageType.DEBUG, mConfiguration.getDefaultName()
            + ": FAIL: Stopping test case after " + "time out of timer: "
            + mConfiguration.getTimerName() + "!");
        if (!mConfiguration.getEndHook().equals(""))
        {
            mOut.print(mConfiguration.getFunctionsPrefix()
                + mConfiguration.getEndHook());
            mOut.print(";");
            mOut.endl();
        }

        mOut.print("stop;");
        mOut.endl();
        mOut.resume();
        mOut.print("}");
        mOut.endl();
        mOut.resume();
        mOut.endl();
    }

    private void printTemplates()
    {
        if (!mPostponedTemplates.isEmpty())
        {
            mOut.println("/***** Template definitions generated for "
                + mCrrentTestCaseName + "*****/");
            Iterator<TemplateDefinition> it = mPostponedTemplates.iterator();
            while (it.hasNext())
            {
                final TemplateDefinition def = it.next();
                mOut.print("template ");
                mOut.print(Utils.makeValidTTCN3Identifier(def.getTypeName()));
                mOut.print(" ");
                mOut.print("m_" + def.getTemplateName());
                mOut.ws();
                mOut.print(":=");
                mOut.endl();
                QMLRecord r = def.getRecord();

                TemplateDumper t = new TemplateDumper(mOut, mConfiguration
                        .isUseFractions());
                r.accept(t);
                mOut.endl();
                mOut.emptyline();
            }
        }
    }

    private void prindAltstepDefaultDecl()
    {
        mOut.emptyline();
        Banner banner = new Banner();
        banner.addTag("desc", new String[] {
            "This altstep handles terminating after waiting up to",
            "the maximum response time and receiving any other",
            "than the expected message with setting a fail ",
            "verdict and stopping the test" });
        banner.print(mOut);
        mOut.print("altstep ");
        mOut.print(mConfiguration.getDefaultName());
        mOut.print(" runs on ");
        mOut.print(mConfiguration.getRunsOnName());
        mOut.endl();
        mOut.print("{");
        mOut.endl();
        mOut.print(mIndent);
        mOut.block();
        printAltStepBody();
        mOut.resume();
        mOut.println("}");
    }

    private void printDebugModulepars()
    {
        mOut.println("/***** Logging verbosity flags *****/");
        for (DebugMessageType t : DebugMessageType.enabledValues())
        {
            Banner banner = new Banner();
            banner.addTag("desc", t.modeuleparComment);
            banner.print(mOut);
            printModulepar("boolean", t.enablingFlag, "" + t.defaultFlagState);
        }
    }

    private void printModulepar(final String type, final String name,
            final String init)
    {
        mOut.println("modulepar " + type + " " + name + " := " + init + ";");
    }

    private void printDebugMessageTypeEnum()
    {
        mOut.println("type enumerated " + mDebugMessageTypeEnumName);
        mOut.println("{");
        mOut.print(mIndent);
        mOut.block();
        DebugMessageType[] debugMessageTypes = DebugMessageType.enabledValues();
        for (int i = 0; i < debugMessageTypes.length; i++)
        {
            mOut.print(debugMessageTypes[i].dispatchingEnumItemName);
            if (i != debugMessageTypes.length - 1)
            {
                mOut.print(",");
            }
            mOut.endl();
        }
        mOut.resume();
        mOut.endl();
        mOut.print("}");
        mOut.endl();
    }

    private void printDebugFunctionDecl()
    {
        String firstArg = "p_description";
        String secondArg = "p_" + mDebugMessageTypeEnumName;

        Banner banner = new Banner();
        List<String> descBody = new LinkedList<String>();
        descBody.add("This function logs target description if the module"
            + " parameter");
        descBody.add("related to the target type is set to true.");
        descBody.add("Module parameters and target type dependencies are"
            + " as follows:");

        for (DebugMessageType t : DebugMessageType.enabledValues())
        {
            descBody.add(mIndent + t.enablingFlag
                + " controls logging of targets type "
                + t.dispatchingEnumItemName);
        }

        banner.addTag("desc", descBody.toArray(new String[0]));
        banner.addTag("param", new String[] { firstArg
            + " The textual target description to be logged" });

        banner.addTag("param ", new String[] { secondArg
            + " The type of target covered by a test" });
        banner.print(mOut);
        mOut.print("function " + mConfiguration.getFunctionsPrefix()
            + mSmartLogCommand + " (");
        mOut.print("charstring " + firstArg + ", " + mDebugMessageTypeEnumName
            + " " + secondArg);
        mOut.print(") runs on " + mConfiguration.getRunsOnName());
        mOut.endl();
        mOut.println("{");
        mOut.print(mIndent);
        mOut.block();

        DebugMessageType types[] = DebugMessageType.enabledValues();
        for (int i = 0; i < types.length; i++)
        {
            DebugMessageType t = types[i];
            mOut.print("if ((" + secondArg + " == " + t.dispatchingEnumItemName
                + ")");
            mOut.print(" and ");
            mOut.print(t.enablingFlag + ")");
            mOut.endl();
            mOut.println("{");
            mOut.print(mIndent);
            mOut.block();
            printLogVar(firstArg);
            mOut.resume();
            mOut.println("}");
            if (i != types.length - 1)
            {
                mOut.println("else");
            }
        }
        mOut.resume();
        mOut.print("}");
        mOut.endl();
    }

    private void printLog(LogMessageType type, String msg)
    {
        String messageHeader;
        switch (type) {
        case DEBUG:
            if (!mConfiguration.isDoLogCQDEbugMessages())
            {
                return;
            }
            messageHeader = "DEBUG";
            break;

        case INFO:
            if (!mConfiguration.isDoLogCQInfoMessages())
            {
                return;
            }
            messageHeader = "INFO";
            break;
        default:
            return;
        }
        mOut.print("log");
        mOut.print("(\"CQ_" + messageHeader + ": " + msg + "\");");
        mOut.endl();

    }

    private void printLogVar(String varName)
    {
        mOut.print("log");
        mOut.print("(\"CQ_INFO: \" & " + varName + ");");
        mOut.endl();
    }

    private void printHeader(File file, String[] desc, String[] remark)
    {
        assert (mOut != null);

        mOut.print("/* -*- ttcn-3 -*- */");
        mOut.endl();
        mOut.emptyline();

        Banner banner = new Banner();

        banner.addTag("file", file.getAbsolutePath());
        banner.addTag("author", "Conformiq TTCN-3 scripting backend");
        banner.addTag("version", new Date().toString());

        if (desc != null)
        {
            banner.addTag("desc", desc);
        }

        if (remark != null)
        {
            banner.addTag("remark", remark);
        }
        banner.print(mOut);
    }

    private void deleteCopies()
    {
        mGeneratedTemplates.clear();
    }

    private void printCheckpoints()
    {
        for (CheckPointInfo cp : collectedCheckpoints)
        {
            printCheckPoint(cp);
        }
    }

    private void printCheckPoint(CheckPointInfo cp)
    {
        String name = cp.checkpoint.getName();
        for (DebugMessageType t : DebugMessageType.values())
        {
            for (String p : t.checkpointPrefixes)
            {
                if (name.startsWith(p) && t.enabled)
                {
                    mOut.print(mConfiguration.getFunctionsPrefix() + 
                    		mSmartLogCommand);
                    mOut.print("(\"Covered ");
                    mOut.print(Utils.escapeString(name));
                    mOut.print("\"");
                    mOut.print(", ");
                    mOut.print(t.dispatchingEnumItemName);
                    mOut.print(");");
                    mOut.endl();
                    return;
                }
            }
        }
    }

    private String recordAndRenderTestCaseName(String testCaseName)
    {
        // Remove whitespace
        StringBuffer rendered = new StringBuffer("tc_");
        for (int i = 0; i < testCaseName.length(); i++)
        {
            // Inverted the logic here to be safer by replacing everything
            // but valid identifier chars with an underscore. According to the
            // spec: "TTCN-3 identifiers are case sensitive and may
            // only contain lowercase letters (a-z) uppercase letters
            // (A-Z) and numeric digits (0-9). Use of the underscore (
            // _ ) symbol is also allowed. An identifier shall begin
            // with a letter (i.e., not a number and not an
            // underscore)."
            char c = testCaseName.substring(i, i + 1).charAt(0);
            // If the original test case name starts with a digit, we want
            // to preserve that but need to prefix the test case name with
            // an underscore.
            if (c >= '0' && c <= '9' && i == 0)
                rendered.append('_');
            if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')
                || (c >= '0' && c <= '9') || c == '_')
                rendered.append(c);
            else
                rendered.append('_');
        }
        // Put into test case name list
        mTestCaseNames.add(rendered.toString());
        return rendered.toString();
    }

    private String getTestCaseName(int i)
    {
        // Get test case name at index i of the test case list
        return mTestCaseNames.get(i - 1);
    }

    private static final String mIndent = "    ";
    private static final String mDebugMessageTypeEnumName = "target_type";
    private static final String mSmartLogCommand = "log_target";
    static public final String mScripterName = "TTCN-3 scripter";
    static private final String mSlackVarName = "mp_max_response_time";
    static private final String mOldTimerName = "v_last_wait_timeout";
    static private final String mSleepFunctionName = "sleep";
    private PrettyPrinter mOut;
    private NotificationSink mNotifications;
    private MetaDataDictionary mMetadata;
    private int mTestCaseIndex;
    private int mTemplateIndex;
    private String mCrrentTestCaseName;
    private int mCaseStepIndex;

    private TimeStamp mTimeStamp;
    private boolean mIsFirstStep;
    private Map<QMLRecord, Integer> mGeneratedTemplates;
    private Vector<TemplateDefinition> mPostponedTemplates;
    private Vector<String> mTestCaseNames;

    private Configuration mConfiguration = new Configuration();

    private String mTestsuiteName;

    private Queue<Utils.CheckPointInfo> collectedCheckpoints;

    enum LogMessageType {
        DEBUG, INFO
    }

    public class Port
    {
        public Port(final String key, final QMLArray tuple)
        {
            final StringTokenizer tokenizer = new StringTokenizer(key, ":");
            final String potinfo = tokenizer.nextToken();
            assert potinfo == "portinfo";
            final String dir = tokenizer.nextToken();
            isInbound = !dir.equals("inbound");
            final boolean isOutbound = !dir.equals("outbound");
            assert isInbound != isOutbound;
            final String origname = tokenizer.nextToken();
            name = Utils.makeValidTTCN3Identifier(origname);
            assert !tokenizer.hasMoreElements();

            this.records = new LinkedList<QMLRecordType>();
            tuple.accept(new PortDataExtractor());
        }

        final List<QMLRecordType> records;
        final boolean isInbound;
        final String name;

        private class PortDataExtractor implements QMLValueVisitor
        {
            public PortDataExtractor()
            {

            }

            @Override
            public void visit(QMLArray x)
            {
                final int size = x.getNumberOfElements();
                for (int i = 0; i < size; i++)
                {
                    QMLString portname = (QMLString) x.getValue(i);
                    if (portname != null)
                    {
                        final String origname = portname.getValue();
                        QMLRecordType type = mMetadata.getType(origname);
                        if (type == null)
                    	{
                    		mNotifications.notify("info", "Warning: Nested r" +
                    				"records in port declarations types are " +
                    				"not yet supported by the scripter");
							continue;
                    	}
                        records.add(type);
                    }
                }
            }

            @Override
            public void visit(QMLBoolean b)
            {
            }

            @Override
            public void visit(QMLNumber n)
            {
            }

            @Override
            public void visit(QMLRecord r)
            {
            }

            @Override
            public void visit(QMLString s)
            {
            }

            @Override
            public void visit(QMLOptional p)
            {
            }
        }
    }
    private List<Port> externalPorts;
}
