anchor.diff:            // TODO(paulberry)
             _unimplemented(expression, 'Missing type for named parameter');
           }
  -        _handleAssignment(parameterType, expression.expression);
  +        _handleAssignment(expression.expression, parameterType);
           suppliedNamedParameters.add(name);
         } else {
           if (calleeType.positionalParameters.length <= i) {
             // TODO(paulberry)
             _unimplemented(argumentList, 'Missing positional parameter at $i');
           }
  -        _handleAssignment(calleeType.positionalParameters[i++], expression);
  +        _handleAssignment(expression, calleeType.positionalParameters[i++]);
         }
       }
       // Any parameters not supplied must be optional.
  
positive.code:   DecoratedType visitIfStatement(IfStatement node) {
      // TODO(paulberry): should the use of a boolean in an if-statement be
      // treated like an implicit `assert(b != null)`?  Probably.
      _handleAssignment(_notNullType, node.condition);
      _inConditionalControlFlow = true;
      NullabilityNode trueGuard;
      NullabilityNode falseGuard;
  
negative.code:       // TODO(paulberry)
        _unimplemented(node, 'Variable declaration with no initializer');
      } else {
        _handleAssignment(initializer, destinationType);
      }
      return null;
    }
  
    /// Creates the necessary constraint(s) for an assignment from [source] to
    /// [destination].  [expressionChecks] tracks checks that might have to be
    /// done on the type of an expression.  [hard] indicates whether a hard edge
    /// should be created.
    void _checkAssignment(ExpressionChecks expressionChecks,
        {@required DecoratedType source,
        @required DecoratedType destination,
        @required bool hard}) {
      var edge = _graph.connect(source.node, destination.node, expressionChecks,
          guards: _guards, hard: hard);
      expressionChecks?.edges?.add(edge);
      // TODO(paulberry): generalize this.
      if ((_isSimple(source) || destination.type.isObject) &&
          _isSimple(destination)) {
        // Ok; nothing further to do.
      } else if (source.type is InterfaceType &&
          destination.type is InterfaceType &&
          source.type.element == destination.type.element) {
        assert(source.typeArguments.length == destination.typeArguments.length);
        for (int i = 0; i < source.typeArguments.length; i++) {
          _checkAssignment(expressionChecks,
              source: source.typeArguments[i],
              destination: destination.typeArguments[i],
              hard: false);
        }
      } else if (source.type is FunctionType &&
          destination.type is FunctionType) {
        _checkAssignment(expressionChecks,
            source: source.returnType,
            destination: destination.returnType,
            hard: hard);
        if (source.typeArguments.isNotEmpty ||
            destination.typeArguments.isNotEmpty) {
          throw UnimplementedError('TODO(paulberry)');
        }
        if (source.positionalParameters.isNotEmpty ||
            destination.positionalParameters.isNotEmpty) {
          throw UnimplementedError('TODO(paulberry)');
        }
        if (source.namedParameters.isNotEmpty ||
            destination.namedParameters.isNotEmpty) {
          throw UnimplementedError('TODO(paulberry)');
        }
      } else if (destination.type.isDynamic || source.type.isDynamic) {
        // ok; nothing further to do.
      } else {
        throw '$destination <= $source'; // TODO(paulberry)
      }
    }
  
  