anchor.diff:    TypeVariable();
     
     String toString() => types.toString();
  -}
  -
  -class TypeMap {
  -  Map<Expression, TypeVariable> _typeMap = <Expression, TypeVariable>{};
  -  Map<Identifier, TypeVariable> _getters = <Identifier, TypeVariable>{};
  -  Map<Identifier, TypeVariable> _setters = <Identifier, TypeVariable>{};
  -  
  -  TypeVariable operator [](Expression e) => (containsKey(e) ? _typeMap[e] : addEmpty(e));
  -  
  -  bool containsKey(Expression e) => _typeMap.containsKey(e);
  -  TypeVariable addEmpty(Expression e) => _typeMap[e] = new TypeVariable();
  -  TypeVariable add(Expression e, TypeVariable type) => _typeMap[e] = type;
  -  
  -  void operator []=(Expression e, AbstractType t) {
  -    if (!_typeMap.containsKey(e))
  -      _typeMap[e] = new TypeVariable();
  -    _typeMap[e].add(t);
  -  }
  -  
  -  TypeVariable setter(Identifier i) {
  -    if (!_setters.containsKey(i))
  -      _setters[i] = new TypeVariable();
  -    return _setters[i];
  -  }
  -  
  -  TypeVariable getter(Identifier i) {
  -    if (!_getters.containsKey(i))
  -      _getters[i] = new TypeVariable();
  -    return _getters[i];
  -  }
  -  
  -  String toString() {
  -    StringBuffer sb = new StringBuffer();
  -    
  -    for(Expression exp in _typeMap.keys){
  -      sb.writeln("${exp}: ${_typeMap[exp]}");
  -    }
  -    
  -    return sb.toString();
  -  }
   }
   
   
  
positive.code:     }
  
      return res + "${returnType})";
    }
    
    bool operator ==(Object other) => 
  
negative.code:   bool operator ==(Object other) => other is VoidType;
  }
  
  class ConstraintAnalysis {
    Map<Source, TypeMap> typeMap = <Source, TypeMap>{};
    
  
    LibraryElement get dartCore => elementAnalysis.dartCore;
    Engine engine;
    ElementAnalysis elementAnalysis;
    ElementTyper elementTyper;
    
    ConstraintAnalysis(Engine this.engine, ElementAnalysis this.elementAnalysis) {
      elementTyper = new ElementTyper(this); 
    }
  }
  
  /************ TypeIdentifiers *********************/
  abstract class TypeIdentifier {}
  
  
  class ExpressionTypeIdentifier extends TypeIdentifier {
    Expression exp;
    
    ExpressionTypeIdentifier(Expression this.exp);
    
    int get hashCode => exp.hashCode; 
  }
  
  
  class AbstractTypeIdentifier extends TypeIdentifier {
    AbstractType type;
    Name name;
    
    AbstractTypeIdentifier(AbstractType this.type, Name this.name);
    
    int get hashCode => type.hashCode + 31 * name.hashCode;
  }
  
  
  /************* Type maps ********************/
  class TypeMap {
    Map<TypeIdentifier, TypeVariable> _typeMap = <TypeIdentifier, TypeVariable>{};
    
    TypeVariable operator [](TypeIdentifier ident) => (containsKey(ident) ? _typeMap[ident] : addEmpty(ident));
    
    bool containsKey(TypeIdentifier ident) => _typeMap.containsKey(ident);
    TypeVariable addEmpty(TypeIdentifier ident) => _typeMap[ident] = new TypeVariable();
    
    void operator []=(TypeIdentifier ident, AbstractType t) {
      if (!_typeMap.containsKey(ident))
        _typeMap[ident] = new TypeVariable();
      _typeMap[ident].add(t);
    }
    
    String toString() {
      StringBuffer sb = new StringBuffer();
      
      for(Expression exp in _typeMap.keys){
        sb.writeln("${exp}: ${_typeMap[exp]}");
      }
      
      return sb.toString();
    }
  }
  
  
  class TypeVariable {
    List<AbstractType> types = <AbstractType>[];
    
    List<Function> event_listeners = <Function>[];
    bool _changed = false;
    
    void add(AbstractType t) {
      //TODO (jln) If the type added is a free-type check if there already exists a free type and merge them. 
      if (!types.contains(t)) {
        _changed = true;
        types.add(t);
        trigger(t);
        _changed = false;
      }
    }
    
    Function notify(void f(TypeVariable, AbstractType)) {
      event_listeners.add(f);
      
      bool reset;
      do {
        reset = false;
        for(var i= 0; i < types.length; i++){
            if (_changed) {
              reset = true;
              break;
            } else 
              f(this, types[i]);
        }
      } while(reset);
      return (() => event_listeners.remove(f));
    }
    
  