@Test
  public void testToyTemplateInstantiation() {
    String path = UNIT_BASEDIR + "loc_init/";
    SpaceExDocument spaceExDoc =
        SpaceExImporter.importModels(path + "one_init.cfg", path + "model.xml");

    // 2. convert the SpaceEx data structures to template automata
    Map<String, Component> componentTemplates =
        TemplateImporter.createComponentTemplates(spaceExDoc);

    // 3. run any component template passes here (future)
    // 4. instantiate the component templates into a networked configuration
    Configuration c = ConfigurationMaker.fromSpaceEx(spaceExDoc, componentTemplates);

    Assert.assertTrue(
        "first configuration plot variable is t", c.settings.plotVariableNames[0].equals("t"));

    Assert.assertTrue("root is a network component", c.root instanceof NetworkComponent);
    NetworkComponent system = (NetworkComponent) c.root;

    Assert.assertTrue("root has one child", system.children.size() == 1);
    BaseComponent toy = (BaseComponent) system.children.values().iterator().next().child;

    Assert.assertTrue("child has two transitions", toy.transitions.size() == 2);
  }
  @Test
  public void testToyFullyQualified() {
    String path = UNIT_BASEDIR + "loc_init/";
    SpaceExDocument spaceExDoc =
        SpaceExImporter.importModels(path + "one_init.cfg", path + "model.xml");

    // 2. convert the SpaceEx data structures to template automata
    Map<String, Component> componentTemplates =
        TemplateImporter.createComponentTemplates(spaceExDoc);

    // 3. run any component template passes here (future)
    // 4. instantiate the component templates into a networked configuration
    Configuration c = ConfigurationMaker.fromSpaceEx(spaceExDoc, componentTemplates);

    FlattenRenameUtils.convertToFullyQualifiedParams(c.root);

    Assert.assertTrue("root is a network component", c.root instanceof NetworkComponent);
    NetworkComponent system = (NetworkComponent) c.root;

    Assert.assertTrue("root has one child", system.children.size() == 1);
    BaseComponent toy = (BaseComponent) system.children.values().iterator().next().child;

    Assert.assertTrue(
        "fully-qualified child (toy) has constant renamed to timeout",
        toy.constants.containsKey("timeout"));

    Assert.assertTrue("child has two transitions", toy.transitions.size() == 2);

    c.root.validate();
  }
  @Test
  public void testHeaterInstantiation() {
    String path = UNIT_BASEDIR + "controller_heater/";
    SpaceExDocument spaceExDoc =
        SpaceExImporter.importModels(
            path + "controller_heater.cfg", path + "controller_heater.xml");

    // 2. convert the SpaceEx data structures to template automata
    Map<String, Component> componentTemplates =
        TemplateImporter.createComponentTemplates(spaceExDoc);

    BaseComponent controller = (BaseComponent) componentTemplates.get("ControllerTemplate");
    Assert.assertTrue(
        "controller's first transition has a label", controller.transitions.get(0).label != null);
    Assert.assertTrue(
        "controller's first transition's label is 'turn_on'",
        controller.transitions.get(0).label.equals("turn_on"));

    BaseComponent heater = (BaseComponent) componentTemplates.get("HeaterTemplate");
    Assert.assertTrue(
        "heaters first transition has a label", heater.transitions.get(0).label != null);
    Assert.assertTrue(
        "heaters first transition's label is 'turn_on'",
        heater.transitions.get(0).label.equals("turn_on"));

    ConfigurationMaker.fromSpaceEx(spaceExDoc, componentTemplates);
  }
  public static Configuration flatten(SpaceExDocument spaceExDoc) {
    // 2. convert the SpaceEx data structures to template automata
    Map<String, Component> componentTemplates =
        TemplateImporter.createComponentTemplates(spaceExDoc);

    // 3. run any component template passes here (future)
    // 4. instantiate the component templates into a networked configuration
    Configuration config = ConfigurationMaker.fromSpaceEx(spaceExDoc, componentTemplates);

    FlattenAutomatonPass.flattenAndOptimize(config);

    return config;
  }
  @Test
  public void testPrintInitStates() {
    // Luan's import test. Init was printing as null when it wasn't null
    String cfgPath = UNIT_BASEDIR + "loc_init/one_init.cfg";
    String xmlPath = UNIT_BASEDIR + "loc_init/model.xml";

    SpaceExDocument doc = SpaceExImporter.importModels(cfgPath, xmlPath);
    Map<String, Component> componentTemplates = TemplateImporter.createComponentTemplates(doc);
    Configuration config =
        com.verivital.hyst.importer.ConfigurationMaker.fromSpaceEx(doc, componentTemplates);

    String initString = AutomatonUtil.getMapExpressionString(config.init);

    Assert.assertTrue("init string is not null", initString != null);
  }
  @Test
  public void testLocalVarsInstantiation() {
    String path = UNIT_BASEDIR + "local_vars/";
    SpaceExDocument spaceExDoc = SpaceExImporter.importModels(path + "sys.cfg", path + "sys.xml");

    Map<String, Component> componentTemplates =
        TemplateImporter.createComponentTemplates(spaceExDoc);

    Assert.assertTrue("two templates were imported", componentTemplates.size() == 2);
    Assert.assertTrue(
        "'template' template got imported", componentTemplates.containsKey("template"));
    Assert.assertTrue("system template got imported", componentTemplates.containsKey("system"));

    ConfigurationMaker.fromSpaceEx(spaceExDoc, componentTemplates);
  }
  @Test
  public void testInputOutputError() {
    // test illegal model with input and output (one of the automata
    // contains a variable that is not defined in all modes)
    String cfgPath = UNIT_BASEDIR + "comp_in_out_mismatch/sys.cfg";
    String xmlPath = UNIT_BASEDIR + "comp_in_out_mismatch/sys.xml";

    try {
      SpaceExDocument doc = SpaceExImporter.importModels(cfgPath, xmlPath);
      Map<String, Component> componentTemplates = TemplateImporter.createComponentTemplates(doc);
      ConfigurationMaker.fromSpaceEx(doc, componentTemplates);

      Assert.fail("Validation exception not raised on invalid input / output automaton");
    } catch (AutomatonValidationException e) {
      // expected
    }
  }
  @Test
  public void testBadInitComponent() {
    // model contains an init(X)=Y expression where component X is not an
    // instance in the model

    String cfgPath = UNIT_BASEDIR + "bad_init_comp/bad_init_comp.cfg";
    String xmlPath = UNIT_BASEDIR + "bad_init_comp/bad_init_comp.xml";

    try {
      SpaceExDocument doc = SpaceExImporter.importModels(cfgPath, xmlPath);
      Map<String, Component> componentTemplates = TemplateImporter.createComponentTemplates(doc);
      com.verivital.hyst.importer.ConfigurationMaker.fromSpaceEx(doc, componentTemplates);

      Assert.fail("no exception raised");
    } catch (AutomatonExportException e) {
      // expected
    }
  }
  @Test
  public void testDisjunctionForbidden() {
    // test model with input and output variables
    String cfgPath = UNIT_BASEDIR + "disjunction_forbidden/disjunction_forbidden.cfg";
    String xmlPath = UNIT_BASEDIR + "disjunction_forbidden/disjunction_forbidden.xml";

    SpaceExDocument doc = SpaceExImporter.importModels(cfgPath, xmlPath);
    Map<String, Component> componentTemplates = TemplateImporter.createComponentTemplates(doc);
    Configuration config = ConfigurationMaker.fromSpaceEx(doc, componentTemplates);

    // [[loc1]] with equation x >= 5
    // [[loc1]] with equation t >= 5
    // [[loc3]] with equation t <= 5
    Assert.assertEquals("two forbidden states", 2, config.forbidden.size());
    String loc1 = config.forbidden.get("loc1").toDefaultString();
    String loc3 = config.forbidden.get("loc3").toDefaultString();
    Assert.assertTrue(loc1.contains("x >= 5"));
    Assert.assertTrue(loc1.contains("t >= 5"));
    Assert.assertEquals(loc3, "t <= 5");
  }
  @Test
  public void testSixTank() {
    // network component inside another network component, all with renaming
    // & locals at each level
    // this is the 6 tank model

    // test illegal model with input and output (one of the automata
    // contains a variable that is not defined in all modes)
    String cfgPath = UNIT_BASEDIR + "three_hier/tank6.cfg";
    String xmlPath = UNIT_BASEDIR + "three_hier/tank6.xml";

    // 1. import spaceex doc
    SpaceExDocument doc = SpaceExImporter.importModels(cfgPath, xmlPath);

    // 2. convert the SpaceEx data structures to template automata
    Map<String, Component> componentTemplates = TemplateImporter.createComponentTemplates(doc);

    // 3. run any component template passes here (future)
    // 4. instantiate the component templates into a networked configuration
    Configuration c = ConfigurationMaker.fromSpaceEx(doc, componentTemplates);
    ArrayList<String> originalOrder = new ArrayList<String>();
    originalOrder.addAll(c.root.variables);

    FlattenAutomatonPass.flattenAndOptimize(c);

    Assert.assertEquals("Single mode after flattening", 1, ((BaseComponent) c.root).modes.size());

    // variable names should remain ordered after flattening
    for (int i = 0; i < 6; ++i) {
      String expectedVarName = originalOrder.get(i);
      String varName = c.root.variables.get(i);

      Assert.assertEquals(
          "variable name at index " + i + " was incorrect", expectedVarName, varName);
    }
  }
  @Test
  public void testInputOutput() {
    // test model with input and output variables
    String cfgPath = UNIT_BASEDIR + "comp_in_out/sys.cfg";
    String xmlPath = UNIT_BASEDIR + "comp_in_out/sys.xml";

    SpaceExDocument doc = SpaceExImporter.importModels(cfgPath, xmlPath);
    Map<String, Component> componentTemplates = TemplateImporter.createComponentTemplates(doc);
    Configuration config = ConfigurationMaker.fromSpaceEx(doc, componentTemplates);

    NetworkComponent nc = (NetworkComponent) config.root;

    BaseComponent bcX = (BaseComponent) nc.children.get("out_x_1").child;
    BaseComponent bcY = (BaseComponent) nc.children.get("out_y_1").child;

    Assert.assertEquals("two variables in out_x component", 2, bcX.variables.size());
    Assert.assertEquals(
        "one defined flow in out_x component",
        1,
        bcX.modes.values().iterator().next().flowDynamics.size());

    // also test AutomatonUtil.isOutputVariable()
    Assert.assertTrue(
        "x is an output variable of base component 'out_x_1'",
        AutomatonUtil.isOutputVariable(bcX, "x"));
    Assert.assertTrue(
        "y is NOT an output variable of base component 'out_x_1'",
        !AutomatonUtil.isOutputVariable(bcX, "y"));

    Assert.assertTrue(
        "x is NOT an output variable of base component 'out_y_1'",
        !AutomatonUtil.isOutputVariable(bcY, "x"));
    Assert.assertTrue(
        "y is an output variable of base component 'out_y_1'",
        AutomatonUtil.isOutputVariable(bcY, "y"));
  }
  @Test
  public void testConvertLinearDynamicTwoVarTwoHavocTwoInput() {
    String path = UNIT_BASEDIR + "linear_dynamic/";
    SpaceExDocument test1 =
        SpaceExImporter.importModels(
            path + "four_var_two_input.cfg", path + "four_var_two_input.xml");
    Map<String, Component> componentTemplates = TemplateImporter.createComponentTemplates(test1);

    Configuration c = ConfigurationMaker.fromSpaceEx(test1, componentTemplates);

    new FlattenAutomatonPass().runVanillaPass(c, null);
    BaseComponent ha = (BaseComponent) c.root;

    // Configuration c = flatten(test1);
    // BaseComponent ha = (BaseComponent)c.root;
    Classification cls = new Classification();
    Classification.ha = ha;
    cls.setVarID(ha);
    SimulinkStateflowPrinter sp = new SimulinkStateflowPrinter();
    sp.ha = ha;
    // sp.setVarID(ha);
    AutomatonMode mode = ha.modes.get("running");
    cls.setLinearMatrix(mode);
    // test A matrix
    String A = sp.convertFlowToAMatrix(mode);
    String resultA = "[1.0 4.0 ;0.5 -3.0 ;]";
    Assert.assertEquals(A, resultA);
    // test B matrix
    String B = sp.convertInputToBMatrix(mode);
    String resultB = "[0.5 -2.0 ;-0.2 3.0 ;]";
    Assert.assertEquals(B, resultB);
    // test A matrix
    String C = sp.convertInvToMatrix(mode);
    String resultC = "[1 2.0 ;0 1 ;]";
    Assert.assertEquals(C, resultC);
  }