Undo delete
diff --git a/modelgen/org.eclipse.stem.model.ctdl/xtend-gen/org/eclipse/stem/model/ctdl/generator/CTDLGenerator.java b/modelgen/org.eclipse.stem.model.ctdl/xtend-gen/org/eclipse/stem/model/ctdl/generator/CTDLGenerator.java
new file mode 100644
index 0000000..9aae700
--- /dev/null
+++ b/modelgen/org.eclipse.stem.model.ctdl/xtend-gen/org/eclipse/stem/model/ctdl/generator/CTDLGenerator.java
@@ -0,0 +1,582 @@
+package org.eclipse.stem.model.ctdl.generator;
+
+import com.google.common.base.Objects;
+import com.google.common.collect.Iterables;
+import java.util.Arrays;
+import org.eclipse.emf.codegen.ecore.genmodel.GenClass;
+import org.eclipse.emf.codegen.ecore.genmodel.GenModel;
+import org.eclipse.emf.common.notify.Notifier;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.common.util.TreeIterator;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.stem.model.ctdl.ctdl.AbsoluteCompartmentValueReference;
+import org.eclipse.stem.model.ctdl.ctdl.Block;
+import org.eclipse.stem.model.ctdl.ctdl.BooleanLiteral;
+import org.eclipse.stem.model.ctdl.ctdl.CompartmentTransitionDefinitions;
+import org.eclipse.stem.model.ctdl.ctdl.DefStatement;
+import org.eclipse.stem.model.ctdl.ctdl.Div;
+import org.eclipse.stem.model.ctdl.ctdl.Evaluation;
+import org.eclipse.stem.model.ctdl.ctdl.Expression;
+import org.eclipse.stem.model.ctdl.ctdl.ExternalFunctionReference;
+import org.eclipse.stem.model.ctdl.ctdl.FunctionCall;
+import org.eclipse.stem.model.ctdl.ctdl.FunctionReference;
+import org.eclipse.stem.model.ctdl.ctdl.GlobalVariableReference;
+import org.eclipse.stem.model.ctdl.ctdl.LocalVariableReference;
+import org.eclipse.stem.model.ctdl.ctdl.MetamodelResource;
+import org.eclipse.stem.model.ctdl.ctdl.Minus;
+import org.eclipse.stem.model.ctdl.ctdl.ModelParamReference;
+import org.eclipse.stem.model.ctdl.ctdl.Multi;
+import org.eclipse.stem.model.ctdl.ctdl.NumberLiteral;
+import org.eclipse.stem.model.ctdl.ctdl.Plus;
+import org.eclipse.stem.model.ctdl.ctdl.PrimaryExpression;
+import org.eclipse.stem.model.ctdl.ctdl.RelativeCompartmentValueReference;
+import org.eclipse.stem.model.ctdl.ctdl.ReturnStatement;
+import org.eclipse.stem.model.ctdl.ctdl.ScopedVariableReference;
+import org.eclipse.stem.model.ctdl.ctdl.StringLiteral;
+import org.eclipse.stem.model.ctdl.ctdl.TransitionBlock;
+import org.eclipse.stem.model.ctdl.ctdl.VariableReference;
+import org.eclipse.stem.model.ctdl.functions.ExternalFunctionDefinition;
+import org.eclipse.stem.model.ctdl.functions.FunctionArgumentReference;
+import org.eclipse.stem.model.ctdl.functions.JavaMethodArgument;
+import org.eclipse.stem.model.ctdl.functions.SystemArgumentReference;
+import org.eclipse.stem.model.ctdl.serializer.ITypeSerializer;
+import org.eclipse.stem.model.ctdl.serializer.TypeSerializerFactory;
+import org.eclipse.stem.model.metamodel.Compartment;
+import org.eclipse.stem.model.metamodel.CompartmentGroup;
+import org.eclipse.stem.model.metamodel.Model;
+import org.eclipse.stem.model.metamodel.ModelParam;
+import org.eclipse.stem.model.metamodel.Transition;
+import org.eclipse.xtend2.lib.StringConcatenation;
+import org.eclipse.xtext.generator.IFileSystemAccess;
+import org.eclipse.xtext.generator.IGenerator;
+import org.eclipse.xtext.xbase.lib.IterableExtensions;
+import org.eclipse.xtext.xbase.lib.IteratorExtensions;
+import org.eclipse.xtext.xbase.lib.StringExtensions;
+
+@SuppressWarnings("all")
+public class CTDLGenerator implements IGenerator {
+  private GenClass _modelGenClass;
+  
+  public GenClass getModelGenClass() {
+    return this._modelGenClass;
+  }
+  
+  public void setModelGenClass(final GenClass modelGenClass) {
+    this._modelGenClass = modelGenClass;
+  }
+  
+  private GenClass _labelValueGenClass;
+  
+  public GenClass getLabelValueGenClass() {
+    return this._labelValueGenClass;
+  }
+  
+  public void setLabelValueGenClass(final GenClass labelValueGenClass) {
+    this._labelValueGenClass = labelValueGenClass;
+  }
+  
+  public String addImport(final String fqn) {
+    GenClass _modelGenClass = this.getModelGenClass();
+    boolean _notEquals = (!Objects.equal(_modelGenClass, null));
+    if (_notEquals) {
+      GenClass _modelGenClass_1 = this.getModelGenClass();
+      GenModel _genModel = _modelGenClass_1.getGenModel();
+      return _genModel.getImportedName(fqn);
+    } else {
+      return fqn;
+    }
+  }
+  
+  public void doGenerate(final Resource resource, final IFileSystemAccess fsa) {
+    TreeIterator<EObject> _allContents = resource.getAllContents();
+    Iterable<EObject> _iterable = IteratorExtensions.<EObject>toIterable(_allContents);
+    Iterable<CompartmentTransitionDefinitions> _filter = Iterables.<CompartmentTransitionDefinitions>filter(_iterable, CompartmentTransitionDefinitions.class);
+    CompartmentTransitionDefinitions ctd = IterableExtensions.<CompartmentTransitionDefinitions>head(_filter);
+    MetamodelResource mm = ctd.getMetamodel();
+    Transition trans = mm.getTransition();
+    Compartment _source = trans.getSource();
+    String _name = _source.getName();
+    String _plus = (_name + "_");
+    Compartment _target = trans.getTarget();
+    String _name_1 = _target.getName();
+    String fname = (_plus + _name_1);
+    CharSequence _compile = this.compile(resource);
+    fsa.generateFile(fname, _compile);
+  }
+  
+  protected CharSequence _compile(final Resource r) {
+    StringConcatenation _builder = new StringConcatenation();
+    TreeIterator<EObject> _allContents = r.getAllContents();
+    Iterable<EObject> _iterable = IteratorExtensions.<EObject>toIterable(_allContents);
+    Iterable<TransitionBlock> _filter = Iterables.<TransitionBlock>filter(_iterable, TransitionBlock.class);
+    TransitionBlock _head = IterableExtensions.<TransitionBlock>head(_filter);
+    CharSequence _compile = this.compile(_head);
+    _builder.append(_compile, "");
+    return _builder;
+  }
+  
+  protected CharSequence _compile(final TransitionBlock t) {
+    EObject _eContainer = t.eContainer();
+    CompartmentTransitionDefinitions ctd = ((CompartmentTransitionDefinitions) _eContainer);
+    MetamodelResource _metamodel = ctd.getMetamodel();
+    Model _model = _metamodel.getModel();
+    EClass _class_ = _model.getClass_();
+    String modelClass = _class_.getInstanceTypeName();
+    boolean _equals = Objects.equal(modelClass, null);
+    if (_equals) {
+      MetamodelResource _metamodel_1 = ctd.getMetamodel();
+      Model _model_1 = _metamodel_1.getModel();
+      EClass _class__1 = _model_1.getClass_();
+      String _name = _class__1.getName();
+      modelClass = _name;
+    }
+    MetamodelResource _metamodel_2 = ctd.getMetamodel();
+    Model _model_2 = _metamodel_2.getModel();
+    CompartmentGroup _compartments = _model_2.getCompartments();
+    EClass _class__2 = _compartments.getClass_();
+    String labelClass = _class__2.getInstanceTypeName();
+    boolean _equals_1 = Objects.equal(labelClass, null);
+    if (_equals_1) {
+      MetamodelResource _metamodel_3 = ctd.getMetamodel();
+      Model _model_3 = _metamodel_3.getModel();
+      CompartmentGroup _compartments_1 = _model_3.getCompartments();
+      EClass _class__3 = _compartments_1.getClass_();
+      String _name_1 = _class__3.getName();
+      labelClass = _name_1;
+    } else {
+      String _addImport = this.addImport(labelClass);
+      labelClass = _addImport;
+    }
+    MetamodelResource _metamodel_4 = ctd.getMetamodel();
+    Model _model_4 = _metamodel_4.getModel();
+    CompartmentGroup _compartments_2 = _model_4.getCompartments();
+    EClass _valueClass = _compartments_2.getValueClass();
+    String labelValueClass = _valueClass.getInstanceTypeName();
+    boolean _equals_2 = Objects.equal(labelValueClass, null);
+    if (_equals_2) {
+      MetamodelResource _metamodel_5 = ctd.getMetamodel();
+      Model _model_5 = _metamodel_5.getModel();
+      CompartmentGroup _compartments_3 = _model_5.getCompartments();
+      EClass _valueClass_1 = _compartments_3.getValueClass();
+      String _name_2 = _valueClass_1.getName();
+      labelValueClass = _name_2;
+    } else {
+      String _addImport_1 = this.addImport(labelValueClass);
+      labelValueClass = _addImport_1;
+    }
+    MetamodelResource _metamodel_6 = ctd.getMetamodel();
+    Transition transition = _metamodel_6.getTransition();
+    StringConcatenation _builder = new StringConcatenation();
+    _builder.append("protected double ");
+    Compartment _source = transition.getSource();
+    String _name_3 = _source.getName();
+    String _plus = (_name_3 + "_");
+    Compartment _target = transition.getTarget();
+    String _name_4 = _target.getName();
+    String _plus_1 = (_plus + _name_4);
+    _builder.append(_plus_1, "");
+    _builder.append(" (");
+    _builder.newLineIfNotEmpty();
+    _builder.append("double t, ");
+    _builder.newLine();
+    _builder.append("long timeDelta, ");
+    _builder.newLine();
+    String _addImport_2 = this.addImport("org.eclipse.stem.core.model.STEMTime");
+    _builder.append(_addImport_2, "");
+    _builder.append(" time,");
+    _builder.newLineIfNotEmpty();
+    _builder.append(modelClass, "");
+    _builder.append(" model,");
+    _builder.newLineIfNotEmpty();
+    _builder.append(labelClass, "");
+    _builder.append(" label,");
+    _builder.newLineIfNotEmpty();
+    _builder.append(labelValueClass, "");
+    _builder.append(" labelValue,");
+    _builder.newLineIfNotEmpty();
+    String _addImport_3 = this.addImport("org.eclipse.stem.core.graph.Node");
+    _builder.append(_addImport_3, "");
+    _builder.append(" node) {");
+    _builder.newLineIfNotEmpty();
+    _builder.append("\t");
+    {
+      Block _block = t.getBlock();
+      EList<DefStatement> _statements = _block.getStatements();
+      for(final DefStatement s : _statements) {
+        CharSequence _compile = this.compile(s);
+        _builder.append(_compile, "	");
+      }
+    }
+    _builder.newLineIfNotEmpty();
+    _builder.append("\t");
+    _builder.append("return ");
+    Block _block_1 = t.getBlock();
+    ReturnStatement _ret = _block_1.getRet();
+    CharSequence _compile_1 = this.compile(_ret);
+    _builder.append(_compile_1, "	");
+    _builder.append(";");
+    _builder.newLineIfNotEmpty();
+    _builder.append("}");
+    _builder.newLine();
+    return ((CharSequence) _builder);
+  }
+  
+  protected CharSequence _compile(final DefStatement d) {
+    StringConcatenation _builder = new StringConcatenation();
+    _builder.append("double ");
+    String _varname = d.getVarname();
+    _builder.append(_varname, "");
+    _builder.append("=");
+    Evaluation _expr = d.getExpr();
+    CharSequence _compile = this.compile(_expr);
+    _builder.append(_compile, "");
+    _builder.append(";");
+    return _builder;
+  }
+  
+  protected CharSequence _compile(final Evaluation e) {
+    StringConcatenation _builder = new StringConcatenation();
+    Expression _expression = e.getExpression();
+    CharSequence _compile = this.compile(_expression, Double.TYPE);
+    _builder.append(_compile, "");
+    return _builder;
+  }
+  
+  protected CharSequence _compile(final PrimaryExpression pe, final Class<? extends Object> expectedType) {
+    String neg = "";
+    boolean _isNegate = pe.isNegate();
+    if (_isNegate) {
+      neg = "-";
+    }
+    StringConcatenation _builder = new StringConcatenation();
+    _builder.append("(");
+    _builder.append(neg, "");
+    Expression _exp = pe.getExp();
+    CharSequence _compile = this.compile(_exp, expectedType);
+    _builder.append(_compile, "");
+    _builder.append(")");
+    _builder.newLineIfNotEmpty();
+    return ((CharSequence) _builder);
+  }
+  
+  protected CharSequence _compile(final Plus p, final Class<? extends Object> expectedType) {
+    StringConcatenation _builder = new StringConcatenation();
+    _builder.append("(");
+    Expression _left = p.getLeft();
+    CharSequence _compile = this.compile(_left, Double.TYPE);
+    _builder.append(_compile, "");
+    _builder.append("+");
+    Expression _right = p.getRight();
+    CharSequence _compile_1 = this.compile(_right, Double.TYPE);
+    _builder.append(_compile_1, "");
+    _builder.append(")");
+    return _builder;
+  }
+  
+  protected CharSequence _compile(final Minus m, final Class<? extends Object> expectedType) {
+    StringConcatenation _builder = new StringConcatenation();
+    _builder.append("(");
+    Expression _left = m.getLeft();
+    CharSequence _compile = this.compile(_left, Double.TYPE);
+    _builder.append(_compile, "");
+    _builder.append("-");
+    Expression _right = m.getRight();
+    CharSequence _compile_1 = this.compile(_right, Double.TYPE);
+    _builder.append(_compile_1, "");
+    _builder.append(")");
+    return _builder;
+  }
+  
+  protected CharSequence _compile(final Multi m, final Class<? extends Object> expectedType) {
+    StringConcatenation _builder = new StringConcatenation();
+    Expression _left = m.getLeft();
+    CharSequence _compile = this.compile(_left, Double.TYPE);
+    _builder.append(_compile, "");
+    _builder.append("*");
+    Expression _right = m.getRight();
+    CharSequence _compile_1 = this.compile(_right, Double.TYPE);
+    _builder.append(_compile_1, "");
+    return _builder;
+  }
+  
+  protected CharSequence _compile(final Div d, final Class<? extends Object> expectedType) {
+    StringConcatenation _builder = new StringConcatenation();
+    Expression _left = d.getLeft();
+    CharSequence _compile = this.compile(_left, Double.TYPE);
+    _builder.append(_compile, "");
+    _builder.append("/");
+    Expression _right = d.getRight();
+    CharSequence _compile_1 = this.compile(_right, Double.TYPE);
+    _builder.append(_compile_1, "");
+    return _builder;
+  }
+  
+  protected CharSequence _compileReference(final GlobalVariableReference rf, final Class<? extends Object> expectedType) {
+    StringConcatenation _builder = new StringConcatenation();
+    String _name = rf.getName();
+    _builder.append(_name, "");
+    return _builder;
+  }
+  
+  protected CharSequence _compileReference(final LocalVariableReference rf, final Class<? extends Object> expectedType) {
+    StringConcatenation _builder = new StringConcatenation();
+    String _name = rf.getName();
+    _builder.append(_name, "");
+    return _builder;
+  }
+  
+  protected CharSequence _compileReference(final AbsoluteCompartmentValueReference rf, final Class<? extends Object> expectedType) {
+    GenClass _labelValueGenClass = this.getLabelValueGenClass();
+    ITypeSerializer serializer = TypeSerializerFactory.getSerializer(rf, expectedType, _labelValueGenClass);
+    boolean _notEquals = (!Objects.equal(serializer, null));
+    if (_notEquals) {
+      return serializer.serialize();
+    }
+    StringConcatenation _builder = new StringConcatenation();
+    _builder.append("labelValue.get");
+    Compartment _obj = rf.getObj();
+    String _name = _obj.getName();
+    String _firstUpper = StringExtensions.toFirstUpper(_name);
+    _builder.append(_firstUpper, "");
+    _builder.append("()");
+    return ((CharSequence) _builder);
+  }
+  
+  protected CharSequence _compileReference(final RelativeCompartmentValueReference rf, final Class<? extends Object> expectedType) {
+    GenClass _labelValueGenClass = this.getLabelValueGenClass();
+    ITypeSerializer serializer = TypeSerializerFactory.getSerializer(rf, expectedType, _labelValueGenClass);
+    boolean _notEquals = (!Objects.equal(serializer, null));
+    if (_notEquals) {
+      return serializer.serialize();
+    }
+    StringConcatenation _builder = new StringConcatenation();
+    _builder.append("labelValue.get");
+    Compartment _obj = rf.getObj();
+    String _name = _obj.getName();
+    String _firstUpper = StringExtensions.toFirstUpper(_name);
+    _builder.append(_firstUpper, "");
+    _builder.append("()/labelValue.getPopulationCount()");
+    return ((CharSequence) _builder);
+  }
+  
+  protected CharSequence _compileReference(final ModelParamReference rf, final Class<? extends Object> expectedType) {
+    StringConcatenation _builder = new StringConcatenation();
+    _builder.append("get");
+    ModelParam _obj = rf.getObj();
+    String _name = _obj.getName();
+    String _firstUpper = StringExtensions.toFirstUpper(_name);
+    _builder.append(_firstUpper, "");
+    _builder.append("()");
+    return _builder;
+  }
+  
+  protected CharSequence _compile(final VariableReference rf, final Class<? extends Object> expectedType) {
+    StringConcatenation _builder = new StringConcatenation();
+    ScopedVariableReference _ref = rf.getRef();
+    CharSequence _compileReference = this.compileReference(_ref, expectedType);
+    _builder.append(_compileReference, "");
+    return _builder;
+  }
+  
+  protected CharSequence _compile(final NumberLiteral nl, final Class<? extends Object> expectedType) {
+    StringConcatenation _builder = new StringConcatenation();
+    double _value = nl.getValue();
+    _builder.append(_value, "");
+    return _builder;
+  }
+  
+  protected CharSequence _compile(final StringLiteral sl, final Class<? extends Object> expectedType) {
+    StringConcatenation _builder = new StringConcatenation();
+    _builder.append("\"");
+    String _value = sl.getValue();
+    _builder.append(_value, "");
+    _builder.append("\"");
+    return _builder;
+  }
+  
+  protected CharSequence _compile(final BooleanLiteral bl, final Class<? extends Object> expectedType) {
+    StringConcatenation _builder = new StringConcatenation();
+    boolean _isValue = bl.isValue();
+    _builder.append(_isValue, "");
+    return _builder;
+  }
+  
+  protected CharSequence _compileArgument(final SystemArgumentReference arg, final FunctionCall fc) {
+    StringConcatenation _builder = new StringConcatenation();
+    String _mapsFrom = arg.getMapsFrom();
+    _builder.append(_mapsFrom, "");
+    return _builder;
+  }
+  
+  protected CharSequence _compileArgument(final FunctionArgumentReference arg, final FunctionCall fc) {
+    StringConcatenation _builder = new StringConcatenation();
+    EList<Expression> _args = fc.getArgs();
+    int _argIndex = arg.getArgIndex();
+    Expression _get = _args.get(_argIndex);
+    Class<? extends Object> _javaType = arg.getJavaType();
+    CharSequence _compile = this.compile(_get, _javaType);
+    _builder.append(_compile, "");
+    return _builder;
+  }
+  
+  protected CharSequence _compileFunction(final ExternalFunctionReference fcr, final FunctionCall fc) {
+    StringConcatenation _builder = new StringConcatenation();
+    ExternalFunctionDefinition _func = fcr.getFunc();
+    String _className = _func.getClassName();
+    String _addImport = this.addImport(_className);
+    _builder.append(_addImport, "");
+    _builder.append(".");
+    ExternalFunctionDefinition _func_1 = fcr.getFunc();
+    String _methodName = _func_1.getMethodName();
+    _builder.append(_methodName, "");
+    _builder.append("(");
+    _builder.newLineIfNotEmpty();
+    {
+      ExternalFunctionDefinition _func_2 = fcr.getFunc();
+      EList<JavaMethodArgument> _javaMethodArguments = _func_2.getJavaMethodArguments();
+      for(final JavaMethodArgument arg : _javaMethodArguments) {
+        _builder.append("\t\t");
+        {
+          ExternalFunctionDefinition _func_3 = fcr.getFunc();
+          EList<JavaMethodArgument> _javaMethodArguments_1 = _func_3.getJavaMethodArguments();
+          JavaMethodArgument _head = IterableExtensions.<JavaMethodArgument>head(_javaMethodArguments_1);
+          boolean _notEquals = (!Objects.equal(arg, _head));
+          if (_notEquals) {
+            _builder.append(",");
+          }
+        }
+        _builder.newLineIfNotEmpty();
+        _builder.append("\t\t");
+        CharSequence _compileArgument = this.compileArgument(arg, fc);
+        _builder.append(_compileArgument, "		");
+        _builder.newLineIfNotEmpty();
+        _builder.append("\t\t");
+      }
+    }
+    _builder.append(")");
+    return _builder;
+  }
+  
+  protected CharSequence _compileFunction(final FunctionReference fcr, final FunctionCall fc) {
+    StringConcatenation _builder = new StringConcatenation();
+    String _name = fcr.getName();
+    _builder.append(_name, "");
+    _builder.append("(");
+    {
+      EList<Expression> _args = fc.getArgs();
+      for(final Expression e : _args) {
+        _builder.append(" ");
+        _builder.newLineIfNotEmpty();
+        {
+          EList<Expression> _args_1 = fc.getArgs();
+          Expression _head = IterableExtensions.<Expression>head(_args_1);
+          boolean _equals = Objects.equal(e, _head);
+          if (_equals) {
+            CharSequence _compile = this.compile(e);
+            _builder.append(_compile, "");
+            _builder.newLineIfNotEmpty();
+          } else {
+            _builder.append(",");
+            CharSequence _compile_1 = this.compile(e);
+            _builder.append(_compile_1, "");
+            _builder.newLineIfNotEmpty();
+          }
+        }
+        _builder.append("\t\t\t");
+      }
+    }
+    _builder.append(")");
+    return _builder;
+  }
+  
+  protected CharSequence _compile(final FunctionCall fc, final Class<? extends Object> expectedType) {
+    StringConcatenation _builder = new StringConcatenation();
+    FunctionReference _ref = fc.getRef();
+    CharSequence _compileFunction = this.compileFunction(_ref, fc);
+    _builder.append(_compileFunction, "");
+    return _builder;
+  }
+  
+  public CharSequence compile(final Notifier e) {
+    if (e instanceof Evaluation) {
+      return _compile((Evaluation)e);
+    } else if (e instanceof DefStatement) {
+      return _compile((DefStatement)e);
+    } else if (e instanceof TransitionBlock) {
+      return _compile((TransitionBlock)e);
+    } else if (e instanceof Resource) {
+      return _compile((Resource)e);
+    } else {
+      throw new IllegalArgumentException("Unhandled parameter types: " +
+        Arrays.<Object>asList(e).toString());
+    }
+  }
+  
+  public CharSequence compile(final Expression bl, final Class<? extends Object> expectedType) {
+    if (bl instanceof BooleanLiteral) {
+      return _compile((BooleanLiteral)bl, expectedType);
+    } else if (bl instanceof Div) {
+      return _compile((Div)bl, expectedType);
+    } else if (bl instanceof FunctionCall) {
+      return _compile((FunctionCall)bl, expectedType);
+    } else if (bl instanceof Minus) {
+      return _compile((Minus)bl, expectedType);
+    } else if (bl instanceof Multi) {
+      return _compile((Multi)bl, expectedType);
+    } else if (bl instanceof NumberLiteral) {
+      return _compile((NumberLiteral)bl, expectedType);
+    } else if (bl instanceof Plus) {
+      return _compile((Plus)bl, expectedType);
+    } else if (bl instanceof PrimaryExpression) {
+      return _compile((PrimaryExpression)bl, expectedType);
+    } else if (bl instanceof StringLiteral) {
+      return _compile((StringLiteral)bl, expectedType);
+    } else if (bl instanceof VariableReference) {
+      return _compile((VariableReference)bl, expectedType);
+    } else {
+      throw new IllegalArgumentException("Unhandled parameter types: " +
+        Arrays.<Object>asList(bl, expectedType).toString());
+    }
+  }
+  
+  public CharSequence compileReference(final ScopedVariableReference rf, final Class<? extends Object> expectedType) {
+    if (rf instanceof AbsoluteCompartmentValueReference) {
+      return _compileReference((AbsoluteCompartmentValueReference)rf, expectedType);
+    } else if (rf instanceof RelativeCompartmentValueReference) {
+      return _compileReference((RelativeCompartmentValueReference)rf, expectedType);
+    } else if (rf instanceof GlobalVariableReference) {
+      return _compileReference((GlobalVariableReference)rf, expectedType);
+    } else if (rf instanceof LocalVariableReference) {
+      return _compileReference((LocalVariableReference)rf, expectedType);
+    } else if (rf instanceof ModelParamReference) {
+      return _compileReference((ModelParamReference)rf, expectedType);
+    } else {
+      throw new IllegalArgumentException("Unhandled parameter types: " +
+        Arrays.<Object>asList(rf, expectedType).toString());
+    }
+  }
+  
+  public CharSequence compileArgument(final JavaMethodArgument arg, final FunctionCall fc) {
+    if (arg instanceof FunctionArgumentReference) {
+      return _compileArgument((FunctionArgumentReference)arg, fc);
+    } else if (arg instanceof SystemArgumentReference) {
+      return _compileArgument((SystemArgumentReference)arg, fc);
+    } else {
+      throw new IllegalArgumentException("Unhandled parameter types: " +
+        Arrays.<Object>asList(arg, fc).toString());
+    }
+  }
+  
+  public CharSequence compileFunction(final FunctionReference fcr, final FunctionCall fc) {
+    if (fcr instanceof ExternalFunctionReference) {
+      return _compileFunction((ExternalFunctionReference)fcr, fc);
+    } else if (fcr != null) {
+      return _compileFunction(fcr, fc);
+    } else {
+      throw new IllegalArgumentException("Unhandled parameter types: " +
+        Arrays.<Object>asList(fcr, fc).toString());
+    }
+  }
+}
diff --git a/modelgen/org.eclipse.stem.model.ctdl/xtend-gen/org/eclipse/stem/model/ctdl/generator/CTDLGenerator2.java b/modelgen/org.eclipse.stem.model.ctdl/xtend-gen/org/eclipse/stem/model/ctdl/generator/CTDLGenerator2.java
new file mode 100644
index 0000000..ce0af8c
--- /dev/null
+++ b/modelgen/org.eclipse.stem.model.ctdl/xtend-gen/org/eclipse/stem/model/ctdl/generator/CTDLGenerator2.java
@@ -0,0 +1,637 @@
+package org.eclipse.stem.model.ctdl.generator;
+
+import com.google.common.base.Objects;
+import com.google.common.collect.Iterables;
+import java.util.Arrays;
+import java.util.List;
+import org.eclipse.emf.codegen.ecore.genmodel.GenClass;
+import org.eclipse.emf.codegen.ecore.genmodel.GenPackage;
+import org.eclipse.emf.common.notify.Notifier;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.common.util.TreeIterator;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.stem.model.ctdl.ctdl.AbsoluteCompartmentValueReference;
+import org.eclipse.stem.model.ctdl.ctdl.Block;
+import org.eclipse.stem.model.ctdl.ctdl.BooleanLiteral;
+import org.eclipse.stem.model.ctdl.ctdl.CompartmentTransitionDefinitions;
+import org.eclipse.stem.model.ctdl.ctdl.DefStatement;
+import org.eclipse.stem.model.ctdl.ctdl.Div;
+import org.eclipse.stem.model.ctdl.ctdl.Evaluation;
+import org.eclipse.stem.model.ctdl.ctdl.Expression;
+import org.eclipse.stem.model.ctdl.ctdl.ExternalFunctionReference;
+import org.eclipse.stem.model.ctdl.ctdl.FunctionCall;
+import org.eclipse.stem.model.ctdl.ctdl.FunctionReference;
+import org.eclipse.stem.model.ctdl.ctdl.GlobalVariableReference;
+import org.eclipse.stem.model.ctdl.ctdl.LocalVariableReference;
+import org.eclipse.stem.model.ctdl.ctdl.MetamodelResource;
+import org.eclipse.stem.model.ctdl.ctdl.Minus;
+import org.eclipse.stem.model.ctdl.ctdl.ModelParamReference;
+import org.eclipse.stem.model.ctdl.ctdl.Multi;
+import org.eclipse.stem.model.ctdl.ctdl.NumberLiteral;
+import org.eclipse.stem.model.ctdl.ctdl.Plus;
+import org.eclipse.stem.model.ctdl.ctdl.PrimaryExpression;
+import org.eclipse.stem.model.ctdl.ctdl.RelativeCompartmentValueReference;
+import org.eclipse.stem.model.ctdl.ctdl.ReturnStatement;
+import org.eclipse.stem.model.ctdl.ctdl.ScopedVariableReference;
+import org.eclipse.stem.model.ctdl.ctdl.StringLiteral;
+import org.eclipse.stem.model.ctdl.ctdl.TransitionBlock;
+import org.eclipse.stem.model.ctdl.ctdl.VariableReference;
+import org.eclipse.stem.model.ctdl.functions.ExternalFunctionDefinition;
+import org.eclipse.stem.model.ctdl.functions.FunctionArgumentReference;
+import org.eclipse.stem.model.ctdl.functions.JavaMethodArgument;
+import org.eclipse.stem.model.ctdl.functions.SystemArgumentReference;
+import org.eclipse.stem.model.ctdl.generator.ModelExpressionGenerator;
+import org.eclipse.stem.model.ctdl.serializer.ITypeSerializer;
+import org.eclipse.stem.model.ctdl.serializer.TypeSerializerFactory;
+import org.eclipse.stem.model.metamodel.Compartment;
+import org.eclipse.stem.model.metamodel.ModelParam;
+import org.eclipse.stem.model.metamodel.Transition;
+import org.eclipse.xtend2.lib.StringConcatenation;
+import org.eclipse.xtext.generator.IFileSystemAccess;
+import org.eclipse.xtext.resource.XtextResource;
+import org.eclipse.xtext.xbase.lib.IterableExtensions;
+import org.eclipse.xtext.xbase.lib.IteratorExtensions;
+import org.eclipse.xtext.xbase.lib.StringExtensions;
+
+@SuppressWarnings("all")
+public class CTDLGenerator2 extends ModelExpressionGenerator {
+  private GenClass _modelGenClass;
+  
+  public GenClass getModelGenClass() {
+    return this._modelGenClass;
+  }
+  
+  public void setModelGenClass(final GenClass modelGenClass) {
+    this._modelGenClass = modelGenClass;
+  }
+  
+  private GenClass _labelGenClass;
+  
+  public GenClass getLabelGenClass() {
+    return this._labelGenClass;
+  }
+  
+  public void setLabelGenClass(final GenClass labelGenClass) {
+    this._labelGenClass = labelGenClass;
+  }
+  
+  private GenClass _labelValueGenClass;
+  
+  public GenClass getLabelValueGenClass() {
+    return this._labelValueGenClass;
+  }
+  
+  public void setLabelValueGenClass(final GenClass labelValueGenClass) {
+    this._labelValueGenClass = labelValueGenClass;
+  }
+  
+  public void doGenerate(final List<XtextResource> resources, final IFileSystemAccess fsa) {
+    GenClass _modelGenClass = this.getModelGenClass();
+    String _name = _modelGenClass.getName();
+    String fileName = (_name + "Expressions.java");
+    CharSequence _build = this.build(resources);
+    fsa.generateFile(fileName, _build);
+  }
+  
+  public void doGenerate(final Resource resource, final IFileSystemAccess fsa) {
+    TreeIterator<EObject> _allContents = resource.getAllContents();
+    Iterable<EObject> _iterable = IteratorExtensions.<EObject>toIterable(_allContents);
+    Iterable<CompartmentTransitionDefinitions> _filter = Iterables.<CompartmentTransitionDefinitions>filter(_iterable, CompartmentTransitionDefinitions.class);
+    CompartmentTransitionDefinitions ctd = IterableExtensions.<CompartmentTransitionDefinitions>head(_filter);
+    MetamodelResource mm = ctd.getMetamodel();
+    Transition trans = mm.getTransition();
+    Compartment _source = trans.getSource();
+    String _name = _source.getName();
+    String _plus = (_name + "_");
+    Compartment _target = trans.getTarget();
+    String _name_1 = _target.getName();
+    String fname = (_plus + _name_1);
+    CharSequence _compile = this.compile(resource);
+    fsa.generateFile(fname, _compile);
+  }
+  
+  public CharSequence build(final List<XtextResource> r) {
+    StringConcatenation _builder = new StringConcatenation();
+    _builder.append("package ");
+    GenClass _modelGenClass = this.getModelGenClass();
+    GenPackage _genPackage = _modelGenClass.getGenPackage();
+    String _classPackageName = _genPackage.getClassPackageName();
+    _builder.append(_classPackageName, "");
+    _builder.append(";");
+    CharSequence pkg = _builder;
+    StringConcatenation _builder_1 = new StringConcatenation();
+    _builder_1.append("\t\t");
+    _builder_1.append("/**");
+    _builder_1.newLine();
+    _builder_1.append("\t\t ");
+    _builder_1.append("* Generated expressions class for ");
+    GenClass _modelGenClass_1 = this.getModelGenClass();
+    String _name = _modelGenClass_1.getName();
+    _builder_1.append(_name, "		 ");
+    _builder_1.append(".");
+    _builder_1.newLineIfNotEmpty();
+    _builder_1.append("\t\t ");
+    _builder_1.append("* DO NOT EDIT DIRECTLY.  Use extended class and override methods for transitions as desired.");
+    _builder_1.newLine();
+    _builder_1.append("\t\t ");
+    _builder_1.append("* @generated");
+    _builder_1.newLine();
+    _builder_1.append("\t\t ");
+    _builder_1.append("*/");
+    _builder_1.newLine();
+    _builder_1.append("\t\t");
+    _builder_1.append("public class ");
+    GenClass _modelGenClass_2 = this.getModelGenClass();
+    String _name_1 = _modelGenClass_2.getName();
+    _builder_1.append(_name_1, "		");
+    _builder_1.append("Expressions {");
+    _builder_1.newLineIfNotEmpty();
+    _builder_1.append("\t");
+    _builder_1.append("public void calculate(double t, long timeDelta, ");
+    String _importedName = this.getImportedName("org.eclipse.stem.core.model.STEMTime");
+    _builder_1.append(_importedName, "	");
+    _builder_1.append(" time, ");
+    GenClass _modelGenClass_3 = this.getModelGenClass();
+    String _importGenClassInterface = this.importGenClassInterface(_modelGenClass_3);
+    _builder_1.append(_importGenClassInterface, "	");
+    _builder_1.append(" model, ");
+    GenClass _labelGenClass = this.getLabelGenClass();
+    String _importGenClassInterface_1 = this.importGenClassInterface(_labelGenClass);
+    _builder_1.append(_importGenClassInterface_1, "	");
+    _builder_1.append(" label, ");
+    GenClass _labelValueGenClass = this.getLabelValueGenClass();
+    String _importGenClassInterface_2 = this.importGenClassInterface(_labelValueGenClass);
+    _builder_1.append(_importGenClassInterface_2, "	");
+    _builder_1.append(" labelValue, ");
+    String _importedName_1 = this.getImportedName("org.eclipse.stem.core.graph.Node");
+    _builder_1.append(_importedName_1, "	");
+    _builder_1.append(" node) {");
+    _builder_1.newLineIfNotEmpty();
+    _builder_1.append("\t");
+    _builder_1.append("}");
+    _builder_1.newLine();
+    _builder_1.append("\t\t\t");
+    _builder_1.newLine();
+    {
+      for(final XtextResource e : r) {
+        CharSequence _compile = this.compile(e);
+        _builder_1.append(_compile, "");
+        _builder_1.newLineIfNotEmpty();
+      }
+    }
+    _builder_1.append("} //");
+    CharSequence body = _builder_1;
+    String imports = this.getSortedImports();
+    StringConcatenation _builder_2 = new StringConcatenation();
+    _builder_2.append(pkg, "");
+    _builder_2.newLineIfNotEmpty();
+    _builder_2.newLine();
+    _builder_2.append(imports, "");
+    _builder_2.newLineIfNotEmpty();
+    _builder_2.newLine();
+    _builder_2.append(body, "");
+    return ((CharSequence) _builder_2);
+  }
+  
+  protected CharSequence _compile(final Resource r) {
+    StringConcatenation _builder = new StringConcatenation();
+    TreeIterator<EObject> _allContents = r.getAllContents();
+    Iterable<EObject> _iterable = IteratorExtensions.<EObject>toIterable(_allContents);
+    Iterable<TransitionBlock> _filter = Iterables.<TransitionBlock>filter(_iterable, TransitionBlock.class);
+    TransitionBlock _head = IterableExtensions.<TransitionBlock>head(_filter);
+    CharSequence _compile = this.compile(_head);
+    _builder.append(_compile, "");
+    return _builder;
+  }
+  
+  protected CharSequence _compile(final TransitionBlock t) {
+    EObject _eContainer = t.eContainer();
+    CompartmentTransitionDefinitions ctd = ((CompartmentTransitionDefinitions) _eContainer);
+    MetamodelResource _metamodel = ctd.getMetamodel();
+    Transition transition = _metamodel.getTransition();
+    StringConcatenation _builder = new StringConcatenation();
+    _builder.append("/**");
+    _builder.newLine();
+    _builder.append(" ");
+    _builder.append("* Computes delta for transition ");
+    Compartment _source = transition.getSource();
+    String _name = _source.getName();
+    _builder.append(_name, " ");
+    _builder.append(" -> ");
+    Compartment _target = transition.getTarget();
+    String _name_1 = _target.getName();
+    _builder.append(_name_1, " ");
+    _builder.newLineIfNotEmpty();
+    _builder.append(" ");
+    _builder.append("* @generated");
+    _builder.newLine();
+    _builder.append(" ");
+    _builder.append("*/");
+    _builder.newLine();
+    _builder.append("protected double ");
+    Compartment _source_1 = transition.getSource();
+    String _name_2 = _source_1.getName();
+    _builder.append(_name_2, "");
+    _builder.append("_");
+    Compartment _target_1 = transition.getTarget();
+    String _name_3 = _target_1.getName();
+    _builder.append(_name_3, "");
+    _builder.append(" (double t, long timeDelta, ");
+    String _importedName = this.getImportedName("org.eclipse.stem.core.model.STEMTime");
+    _builder.append(_importedName, "");
+    _builder.append(" time, ");
+    GenClass _modelGenClass = this.getModelGenClass();
+    String _importGenClassInterface = this.importGenClassInterface(_modelGenClass);
+    _builder.append(_importGenClassInterface, "");
+    _builder.append(" model, ");
+    GenClass _labelGenClass = this.getLabelGenClass();
+    String _importGenClassInterface_1 = this.importGenClassInterface(_labelGenClass);
+    _builder.append(_importGenClassInterface_1, "");
+    _builder.append(" label, ");
+    GenClass _labelValueGenClass = this.getLabelValueGenClass();
+    String _importGenClassInterface_2 = this.importGenClassInterface(_labelValueGenClass);
+    _builder.append(_importGenClassInterface_2, "");
+    _builder.append(" labelValue, ");
+    String _importedName_1 = this.getImportedName("org.eclipse.stem.core.graph.Node");
+    _builder.append(_importedName_1, "");
+    _builder.append(" node) {");
+    _builder.newLineIfNotEmpty();
+    {
+      Block _block = t.getBlock();
+      EList<DefStatement> _statements = _block.getStatements();
+      for(final DefStatement s : _statements) {
+        CharSequence _compile = this.compile(s);
+        _builder.append(_compile, "");
+      }
+    }
+    _builder.newLineIfNotEmpty();
+    _builder.append("return ");
+    Block _block_1 = t.getBlock();
+    ReturnStatement _ret = _block_1.getRet();
+    CharSequence _compile_1 = this.compile(_ret);
+    _builder.append(_compile_1, "");
+    _builder.append(";");
+    _builder.newLineIfNotEmpty();
+    _builder.append("}");
+    _builder.newLine();
+    return ((CharSequence) _builder);
+  }
+  
+  protected CharSequence _compile(final DefStatement d) {
+    StringConcatenation _builder = new StringConcatenation();
+    _builder.append("double ");
+    String _varname = d.getVarname();
+    _builder.append(_varname, "");
+    _builder.append("=");
+    Evaluation _expr = d.getExpr();
+    CharSequence _compile = this.compile(_expr);
+    _builder.append(_compile, "");
+    _builder.append(";");
+    return _builder;
+  }
+  
+  protected CharSequence _compile(final Evaluation e) {
+    StringConcatenation _builder = new StringConcatenation();
+    Expression _expression = e.getExpression();
+    CharSequence _compile = this.compile(_expression, Double.TYPE);
+    _builder.append(_compile, "");
+    return _builder;
+  }
+  
+  protected CharSequence _compile(final PrimaryExpression pe, final Class<? extends Object> expectedType) {
+    String neg = "";
+    boolean _isNegate = pe.isNegate();
+    if (_isNegate) {
+      neg = "-";
+    }
+    StringConcatenation _builder = new StringConcatenation();
+    _builder.append("(");
+    _builder.append(neg, "");
+    Expression _exp = pe.getExp();
+    CharSequence _compile = this.compile(_exp, expectedType);
+    _builder.append(_compile, "");
+    _builder.append(")");
+    _builder.newLineIfNotEmpty();
+    return ((CharSequence) _builder);
+  }
+  
+  protected CharSequence _compile(final Plus p, final Class<? extends Object> expectedType) {
+    StringConcatenation _builder = new StringConcatenation();
+    _builder.append("(");
+    Expression _left = p.getLeft();
+    CharSequence _compile = this.compile(_left, Double.TYPE);
+    _builder.append(_compile, "");
+    _builder.append("+");
+    Expression _right = p.getRight();
+    CharSequence _compile_1 = this.compile(_right, Double.TYPE);
+    _builder.append(_compile_1, "");
+    _builder.append(")");
+    return _builder;
+  }
+  
+  protected CharSequence _compile(final Minus m, final Class<? extends Object> expectedType) {
+    StringConcatenation _builder = new StringConcatenation();
+    _builder.append("(");
+    Expression _left = m.getLeft();
+    CharSequence _compile = this.compile(_left, Double.TYPE);
+    _builder.append(_compile, "");
+    _builder.append("-");
+    Expression _right = m.getRight();
+    CharSequence _compile_1 = this.compile(_right, Double.TYPE);
+    _builder.append(_compile_1, "");
+    _builder.append(")");
+    return _builder;
+  }
+  
+  protected CharSequence _compile(final Multi m, final Class<? extends Object> expectedType) {
+    StringConcatenation _builder = new StringConcatenation();
+    Expression _left = m.getLeft();
+    CharSequence _compile = this.compile(_left, Double.TYPE);
+    _builder.append(_compile, "");
+    _builder.append("*");
+    Expression _right = m.getRight();
+    CharSequence _compile_1 = this.compile(_right, Double.TYPE);
+    _builder.append(_compile_1, "");
+    return _builder;
+  }
+  
+  protected CharSequence _compile(final Div d, final Class<? extends Object> expectedType) {
+    StringConcatenation _builder = new StringConcatenation();
+    Expression _left = d.getLeft();
+    CharSequence _compile = this.compile(_left, Double.TYPE);
+    _builder.append(_compile, "");
+    _builder.append("/");
+    Expression _right = d.getRight();
+    CharSequence _compile_1 = this.compile(_right, Double.TYPE);
+    _builder.append(_compile_1, "");
+    return _builder;
+  }
+  
+  protected CharSequence _compileReference(final GlobalVariableReference rf, final Class<? extends Object> expectedType) {
+    StringConcatenation _builder = new StringConcatenation();
+    String _name = rf.getName();
+    _builder.append(_name, "");
+    return _builder;
+  }
+  
+  protected CharSequence _compileReference(final LocalVariableReference rf, final Class<? extends Object> expectedType) {
+    StringConcatenation _builder = new StringConcatenation();
+    String _name = rf.getName();
+    _builder.append(_name, "");
+    return _builder;
+  }
+  
+  protected CharSequence _compileReference(final AbsoluteCompartmentValueReference rf, final Class<? extends Object> expectedType) {
+    GenClass _labelValueGenClass = this.getLabelValueGenClass();
+    ITypeSerializer serializer = TypeSerializerFactory.getSerializer(rf, expectedType, _labelValueGenClass);
+    boolean _notEquals = (!Objects.equal(serializer, null));
+    if (_notEquals) {
+      return serializer.serialize();
+    }
+    StringConcatenation _builder = new StringConcatenation();
+    _builder.append("labelValue.get");
+    Compartment _obj = rf.getObj();
+    String _name = _obj.getName();
+    String _firstUpper = StringExtensions.toFirstUpper(_name);
+    _builder.append(_firstUpper, "");
+    _builder.append("()");
+    return ((CharSequence) _builder);
+  }
+  
+  protected CharSequence _compileReference(final RelativeCompartmentValueReference rf, final Class<? extends Object> expectedType) {
+    GenClass _labelValueGenClass = this.getLabelValueGenClass();
+    ITypeSerializer serializer = TypeSerializerFactory.getSerializer(rf, expectedType, _labelValueGenClass);
+    boolean _notEquals = (!Objects.equal(serializer, null));
+    if (_notEquals) {
+      return serializer.serialize();
+    }
+    StringConcatenation _builder = new StringConcatenation();
+    _builder.append("labelValue.get");
+    Compartment _obj = rf.getObj();
+    String _name = _obj.getName();
+    String _firstUpper = StringExtensions.toFirstUpper(_name);
+    _builder.append(_firstUpper, "");
+    _builder.append("()/labelValue.getPopulationCount()");
+    return ((CharSequence) _builder);
+  }
+  
+  protected CharSequence _compileReference(final ModelParamReference rf, final Class<? extends Object> expectedType) {
+    StringConcatenation _builder = new StringConcatenation();
+    _builder.append("get");
+    ModelParam _obj = rf.getObj();
+    String _name = _obj.getName();
+    String _firstUpper = StringExtensions.toFirstUpper(_name);
+    _builder.append(_firstUpper, "");
+    _builder.append("()");
+    return _builder;
+  }
+  
+  protected CharSequence _compile(final VariableReference rf, final Class<? extends Object> expectedType) {
+    StringConcatenation _builder = new StringConcatenation();
+    ScopedVariableReference _ref = rf.getRef();
+    CharSequence _compileReference = this.compileReference(_ref, expectedType);
+    _builder.append(_compileReference, "");
+    return _builder;
+  }
+  
+  protected CharSequence _compile(final NumberLiteral nl, final Class<? extends Object> expectedType) {
+    StringConcatenation _builder = new StringConcatenation();
+    double _value = nl.getValue();
+    _builder.append(_value, "");
+    return _builder;
+  }
+  
+  protected CharSequence _compile(final StringLiteral sl, final Class<? extends Object> expectedType) {
+    StringConcatenation _builder = new StringConcatenation();
+    _builder.append("\"");
+    String _value = sl.getValue();
+    _builder.append(_value, "");
+    _builder.append("\"");
+    return _builder;
+  }
+  
+  protected CharSequence _compile(final BooleanLiteral bl, final Class<? extends Object> expectedType) {
+    StringConcatenation _builder = new StringConcatenation();
+    boolean _isValue = bl.isValue();
+    _builder.append(_isValue, "");
+    return _builder;
+  }
+  
+  protected CharSequence _compileArgument(final SystemArgumentReference arg, final FunctionCall fc) {
+    StringConcatenation _builder = new StringConcatenation();
+    String _mapsFrom = arg.getMapsFrom();
+    _builder.append(_mapsFrom, "");
+    return _builder;
+  }
+  
+  protected CharSequence _compileArgument(final FunctionArgumentReference arg, final FunctionCall fc) {
+    StringConcatenation _builder = new StringConcatenation();
+    EList<Expression> _args = fc.getArgs();
+    int _argIndex = arg.getArgIndex();
+    Expression _get = _args.get(_argIndex);
+    Class<? extends Object> _javaType = arg.getJavaType();
+    CharSequence _compile = this.compile(_get, _javaType);
+    _builder.append(_compile, "");
+    return _builder;
+  }
+  
+  protected CharSequence _compileFunction(final ExternalFunctionReference fcr, final FunctionCall fc) {
+    StringConcatenation _builder = new StringConcatenation();
+    ExternalFunctionDefinition _func = fcr.getFunc();
+    String _className = _func.getClassName();
+    String _importedName = this.getImportedName(_className);
+    _builder.append(_importedName, "");
+    _builder.append(".");
+    ExternalFunctionDefinition _func_1 = fcr.getFunc();
+    String _methodName = _func_1.getMethodName();
+    _builder.append(_methodName, "");
+    _builder.append("(");
+    _builder.newLineIfNotEmpty();
+    {
+      ExternalFunctionDefinition _func_2 = fcr.getFunc();
+      EList<JavaMethodArgument> _javaMethodArguments = _func_2.getJavaMethodArguments();
+      for(final JavaMethodArgument arg : _javaMethodArguments) {
+        _builder.append("\t\t");
+        {
+          ExternalFunctionDefinition _func_3 = fcr.getFunc();
+          EList<JavaMethodArgument> _javaMethodArguments_1 = _func_3.getJavaMethodArguments();
+          JavaMethodArgument _head = IterableExtensions.<JavaMethodArgument>head(_javaMethodArguments_1);
+          boolean _notEquals = (!Objects.equal(arg, _head));
+          if (_notEquals) {
+            _builder.append(",");
+          }
+        }
+        _builder.newLineIfNotEmpty();
+        _builder.append("\t\t");
+        CharSequence _compileArgument = this.compileArgument(arg, fc);
+        _builder.append(_compileArgument, "		");
+        _builder.newLineIfNotEmpty();
+        _builder.append("\t\t");
+      }
+    }
+    _builder.append(")");
+    return _builder;
+  }
+  
+  protected CharSequence _compileFunction(final FunctionReference fcr, final FunctionCall fc) {
+    StringConcatenation _builder = new StringConcatenation();
+    String _name = fcr.getName();
+    _builder.append(_name, "");
+    _builder.append("(");
+    {
+      EList<Expression> _args = fc.getArgs();
+      for(final Expression e : _args) {
+        _builder.append(" ");
+        _builder.newLineIfNotEmpty();
+        {
+          EList<Expression> _args_1 = fc.getArgs();
+          Expression _head = IterableExtensions.<Expression>head(_args_1);
+          boolean _equals = Objects.equal(e, _head);
+          if (_equals) {
+            CharSequence _compile = this.compile(e);
+            _builder.append(_compile, "");
+            _builder.newLineIfNotEmpty();
+          } else {
+            _builder.append(",");
+            CharSequence _compile_1 = this.compile(e);
+            _builder.append(_compile_1, "");
+            _builder.newLineIfNotEmpty();
+          }
+        }
+        _builder.append("\t\t\t");
+      }
+    }
+    _builder.append(")");
+    return _builder;
+  }
+  
+  protected CharSequence _compile(final FunctionCall fc, final Class<? extends Object> expectedType) {
+    StringConcatenation _builder = new StringConcatenation();
+    FunctionReference _ref = fc.getRef();
+    CharSequence _compileFunction = this.compileFunction(_ref, fc);
+    _builder.append(_compileFunction, "");
+    return _builder;
+  }
+  
+  public CharSequence compile(final Notifier e) {
+    if (e instanceof Evaluation) {
+      return _compile((Evaluation)e);
+    } else if (e instanceof DefStatement) {
+      return _compile((DefStatement)e);
+    } else if (e instanceof TransitionBlock) {
+      return _compile((TransitionBlock)e);
+    } else if (e instanceof Resource) {
+      return _compile((Resource)e);
+    } else {
+      throw new IllegalArgumentException("Unhandled parameter types: " +
+        Arrays.<Object>asList(e).toString());
+    }
+  }
+  
+  public CharSequence compile(final Expression bl, final Class<? extends Object> expectedType) {
+    if (bl instanceof BooleanLiteral) {
+      return _compile((BooleanLiteral)bl, expectedType);
+    } else if (bl instanceof Div) {
+      return _compile((Div)bl, expectedType);
+    } else if (bl instanceof FunctionCall) {
+      return _compile((FunctionCall)bl, expectedType);
+    } else if (bl instanceof Minus) {
+      return _compile((Minus)bl, expectedType);
+    } else if (bl instanceof Multi) {
+      return _compile((Multi)bl, expectedType);
+    } else if (bl instanceof NumberLiteral) {
+      return _compile((NumberLiteral)bl, expectedType);
+    } else if (bl instanceof Plus) {
+      return _compile((Plus)bl, expectedType);
+    } else if (bl instanceof PrimaryExpression) {
+      return _compile((PrimaryExpression)bl, expectedType);
+    } else if (bl instanceof StringLiteral) {
+      return _compile((StringLiteral)bl, expectedType);
+    } else if (bl instanceof VariableReference) {
+      return _compile((VariableReference)bl, expectedType);
+    } else {
+      throw new IllegalArgumentException("Unhandled parameter types: " +
+        Arrays.<Object>asList(bl, expectedType).toString());
+    }
+  }
+  
+  public CharSequence compileReference(final ScopedVariableReference rf, final Class<? extends Object> expectedType) {
+    if (rf instanceof AbsoluteCompartmentValueReference) {
+      return _compileReference((AbsoluteCompartmentValueReference)rf, expectedType);
+    } else if (rf instanceof RelativeCompartmentValueReference) {
+      return _compileReference((RelativeCompartmentValueReference)rf, expectedType);
+    } else if (rf instanceof GlobalVariableReference) {
+      return _compileReference((GlobalVariableReference)rf, expectedType);
+    } else if (rf instanceof LocalVariableReference) {
+      return _compileReference((LocalVariableReference)rf, expectedType);
+    } else if (rf instanceof ModelParamReference) {
+      return _compileReference((ModelParamReference)rf, expectedType);
+    } else {
+      throw new IllegalArgumentException("Unhandled parameter types: " +
+        Arrays.<Object>asList(rf, expectedType).toString());
+    }
+  }
+  
+  public CharSequence compileArgument(final JavaMethodArgument arg, final FunctionCall fc) {
+    if (arg instanceof FunctionArgumentReference) {
+      return _compileArgument((FunctionArgumentReference)arg, fc);
+    } else if (arg instanceof SystemArgumentReference) {
+      return _compileArgument((SystemArgumentReference)arg, fc);
+    } else {
+      throw new IllegalArgumentException("Unhandled parameter types: " +
+        Arrays.<Object>asList(arg, fc).toString());
+    }
+  }
+  
+  public CharSequence compileFunction(final FunctionReference fcr, final FunctionCall fc) {
+    if (fcr instanceof ExternalFunctionReference) {
+      return _compileFunction((ExternalFunctionReference)fcr, fc);
+    } else if (fcr != null) {
+      return _compileFunction(fcr, fc);
+    } else {
+      throw new IllegalArgumentException("Unhandled parameter types: " +
+        Arrays.<Object>asList(fcr, fc).toString());
+    }
+  }
+}