anchor.diff:                      if not (isNull asm) then
                           yield asm |]
   
  -        let replacer = AssemblyReplacer (designTimeAssemblies, (lazy referencedAssemblies()), assemblyReplacementMap)
  -
  -        let convToTgt ty = replacer.ConvertDesignTimeTypeToTargetType ty
  +        //let replacer = AssemblyReplacer (designTimeAssemblies, referencedAssemblies, assemblyReplacementMap)
  +
  +        /// When translating quotations, Expr.Var's are translated to new variable respecting reference equality.
  +        let varTableFwd = Dictionary<Var, Var>()
  +        let varTableBwd = Dictionary<Var, Var>()
  +        let typeCacheFwd = Dictionary<Type, Type>()
  +        let typeCacheBwd = Dictionary<Type, Type>()
  +
  +        let fixName (fullName:string) =
  +          if fullName.StartsWith("FSI_") then
  +              // when F# Interactive is the host of the design time assembly,
  +              // all namespaces are prefixed with FSI_, in the runtime assembly
  +              // the name won't have that prefix
  +              fullName.Substring(fullName.IndexOf('.') + 1)
  +          else
  +              fullName
  +
  +        let tryGetTypeFromAssembly (originalAssemblyName:string) fullName (asm:Assembly) =
  +            // if the original assembly of the type being replaced is in `assemblyReplacementMap`,
  +            // then we only map it to assemblies with a name specified in `assemblyReplacementMap`
  +            let notRestrictedOrMatching =
  +                assemblyReplacementMap
  +                |> Seq.forall (fun (originalName:string, newName:string) ->
  +                    if originalAssemblyName.StartsWith originalName then asm.FullName.StartsWith(newName)
  +                    else true)
  +
  +            if not notRestrictedOrMatching then None
  +            elif asm.FullName.StartsWith "FSI-ASSEMBLY" then
  +                // when F# Interactive is the host of the design time assembly,
  +                // for each type in the runtime assembly there might be multiple
  +                // versions (FSI_0001.FullTypeName, FSI_0002.FullTypeName, etc).
  +                // Get the last one.
  +                asm.GetTypes()
  +                |> Seq.filter (fun t -> fixName t.FullName = fullName)
  +                |> Seq.sortBy (fun t -> t.FullName)
  +                |> Seq.toList
  +                |> function [] -> None | xs -> Some (Seq.last xs, false)
  +            else
  +                asm.GetType fullName |> function null -> None | x -> Some (x, true)
  +
  +
  +        let replaceTypeDefinition toTgt (t:Type) =
  +            let cache = (if toTgt then typeCacheFwd else typeCacheBwd)
  +            match cache.TryGetValue(t) with
  +            | true, newT -> newT
  +            | false, _ ->
  +                match t with 
  +                | :? ProvidedTypeDefinition as ptd -> 
  +                    ProvidedTypeDefinition(ptd.Name, ptd.BaseType |> Option.map convToTgt, 
  +                                           convToTgt,
  +                                           HideObjectMethods=ptd.HideObjectMethods, 
  +                                           NonNullable=nonNullable, 
  +                                           IsErased=isErased)
  +                | _ -> 
  +
  +                let asms = (if toTgt then referencedAssemblies.Force() else designTimeAssemblies.Force())
  +                let fullName = fixName t.FullName
  +
  +                match Array.choose (tryGetTypeFromAssembly t.Assembly.FullName fullName) asms |> Seq.distinct |> Seq.toArray with
  +                | r when r.Length > 0 ->
  +                     let (newT, canSave) = r.[0]
  +                     if canSave then cache.[t] <- newT
  +                     newT
  +                | _ ->
  +                    let msg =
  +                        if toTgt then sprintf "The type '%O' utilized by a type provider was not found in reference assembly set '%A'. You may be referencing a portable profile which contains fewer types than those needed by the type provider you are using." t (referencedAssemblies.Force())
  +                        elif designTimeAssemblies.Force().Length = 0 then
  +                            sprintf "A failure occured while determining compilation references"
  +                        else sprintf "The runtime-time type '%O' utilized by a type provider was not found in the compilation-time assembly set '%A'. You may be referencing a portable profile which contains fewer types than those needed by the type provider you are using. Please report this problem to the project site for the type provider." t (designTimeAssemblies.Force())
  +                    failwith msg
  +
  +
  +        let rec replaceType toTgt (t:Type) =
  +              if t :? ProvidedTypeDefinition then t
  +              // Don't try to translate F# abbreviations
  +              elif t :? ProvidedSymbolType && (t :?> ProvidedSymbolType).IsFSharpTypeAbbreviation then t
  +              // Types annotated with units-of-measure
  +              elif t :? ProvidedSymbolType && (t :?> ProvidedSymbolType).IsFSharpUnitAnnotated then
  +                  let genericType = t.GetGenericTypeDefinition()
  +                  let newT = replaceTypeDefinition toTgt genericType
  +                  let typeArguments = t.GetGenericArguments() |> Array.map (replaceType toTgt) |> Array.toList
  +                  ProvidedMeasureBuilder.Default.AnnotateType(newT, typeArguments)
  +              elif t.IsGenericType && not t.IsGenericTypeDefinition then
  +                  let genericType = t.GetGenericTypeDefinition()
  +                  let newT = replaceTypeDefinition toTgt genericType
  +                  let typeArguments = t.GetGenericArguments() |> Array.map (replaceType toTgt)
  +                  newT.MakeGenericType(typeArguments)
  +              elif t.IsGenericParameter then t
  +              elif t.IsArray || t.IsByRef || t.IsPointer then
  +                  let elemType = t.GetElementType()
  +                  let elemTypeT = replaceType toTgt elemType
  +                  if t.IsArray then
  +                      let rank = t.GetArrayRank()
  +                      if rank = 1 then elemTypeT.MakeArrayType() else elemTypeT.MakeArrayType(t.GetArrayRank())
  +                  elif t.IsByRef then elemTypeT.MakeByRefType()
  +                  else elemTypeT.MakePointerType()
  +
  +              else
  +                  replaceTypeDefinition toTgt t
  +
  +        let replaceProperty toTgt (p: PropertyInfo) =
  +            if p :? ProvidedProperty then p
  +            else
  +              let t = replaceType toTgt p.DeclaringType
  +              let bindingFlags = (if p.IsPublic then BindingFlags.Public else BindingFlags.NonPublic) ||| (if p.IsStatic then BindingFlags.Static else BindingFlags.Instance)
  +              let newP = t.GetProperty(p.Name, bindingFlags)
  +              if isNull newP then failwithf "Property '%O' of type '%O' not found. This property may be missing in the types available in the target assemblies." p t
  +              newP
  +
  +        let replaceField toTgt (f: FieldInfo) =
  +            if f :? ProvidedField then f
  +            else
  +              let t = replaceType toTgt f.DeclaringType
  +              let bindingFlags = (if f.IsPublic then BindingFlags.Public else BindingFlags.NonPublic) ||| (if f.IsStatic then BindingFlags.Static else BindingFlags.Instance)
  +              let newF = t.GetField(f.Name, bindingFlags)
  +              if isNull newF then failwithf "Field '%O' of type '%O' not found. This field may be missing in the types available in the target assemblies." f t
  +              newF
  +
  +        let replaceMethod toTgt (m: MethodInfo) =
  +            if m :? ProvidedMethod then m
  +            else
  +              let declTyT = replaceType toTgt m.DeclaringType
  +              let mT =
  +                  if m.IsGenericMethod then
  +                    let genericMethod = m.GetGenericMethodDefinition()
  +                    let parameterTypesT = genericMethod.GetParameters() |> Array.map (fun p -> replaceType toTgt p.ParameterType)
  +                    let genericMethodT = declTyT.GetMethod(genericMethod.Name,parameterTypesT)
  +                    if isNull genericMethodT then null else
  +                    let typeArgumentsT =  m.GetGenericArguments() |> Array.map (replaceType toTgt)
  +                    genericMethodT.MakeGenericMethod(typeArgumentsT)
  +                  else
  +                    let parameterTypesT = m.GetParameters() |> Array.map (fun p -> replaceType toTgt p.ParameterType)
  +                    declTyT.GetMethod(m.Name, parameterTypesT)
  +              match mT with
  +              | null -> failwithf "Method '%O' not found in type '%O'. This method may be missing in the types available in the target assemblies." m mT
  +              | _ -> mT
  +
  +        let replaceConstructor toTgt (cons: ConstructorInfo) =
  +            if cons :? ProvidedConstructor then cons
  +            else
  +                let declTyT = replaceType toTgt cons.DeclaringType
  +                let parameterTypesT = cons.GetParameters() |> Array.map (fun p -> replaceType toTgt p.ParameterType)
  +                let consT = declTyT.GetConstructor(parameterTypesT)
  +                match consT with
  +                | null -> failwithf "Constructor '%O' not found in type '%O'. This constructor may be missing in the types available in the target assemblies." cons declTyT
  +                | _ -> consT
  +
  +        let replaceVar toTgt (v: Var) =
  +         if toTgt then 
  +            match varTableFwd.TryGetValue v with
  +            | true, v -> v
  +            | false, _ ->
  +                // It's a variable local to the quotation
  +                let newVar = Var (v.Name, replaceType toTgt v.Type, v.IsMutable)
  +                // store it so we reuse it from now on
  +                varTableFwd.Add(v, newVar)
  +                varTableBwd.Add(newVar, v)
  +                newVar
  +         else
  +            match varTableBwd.TryGetValue v with
  +            | true, v -> v
  +            | false, _ ->
  +                let newVar = Var (v.Name, replaceType toTgt v.Type, v.IsMutable)
  +                // store the original var as we'll have to revert to it later
  +                varTableBwd.Add(v, newVar)
  +                varTableFwd.Add(newVar, v)
  +                newVar
  +
  +        let rec replaceExpr toTgt quotation =
  +
  +            match quotation with
  +            | Call (obj, m, args) ->
  +                let mR = replaceMethod toTgt m
  +                let argsR = List.map (replaceExpr toTgt) args
  +                match obj with
  +                | Some obj -> Expr.CallUnchecked (replaceExpr toTgt obj, mR, argsR)
  +                | None -> Expr.CallUnchecked (mR, argsR)
  +            | PropertyGet (obj, p, indexArgs) ->
  +                let pR = replaceProperty toTgt p
  +                let indexArgsR = List.map (replaceExpr toTgt) indexArgs
  +                match obj with
  +                | Some obj -> Expr.PropertyGetUnchecked (replaceExpr toTgt obj, pR, indexArgsR)
  +                | None -> Expr.PropertyGetUnchecked (pR, indexArgsR)
  +            | PropertySet (obj, p, indexArgs, value) ->
  +                let pR = replaceProperty toTgt p
  +                let indexArgsR = List.map (replaceExpr toTgt) indexArgs
  +                match obj with
  +                | Some obj -> Expr.PropertySetUnchecked (replaceExpr toTgt obj, pR, replaceExpr toTgt value, indexArgsR)
  +                | None -> Expr.PropertySetUnchecked (pR, replaceExpr toTgt value, indexArgsR)
  +            | NewObject (c, exprs) ->
  +                let exprsR = List.map (replaceExpr toTgt) exprs
  +                Expr.NewObjectUnchecked (replaceConstructor toTgt c, exprsR)
  +            | Coerce (expr, t) ->
  +                Expr.Coerce (replaceExpr toTgt expr, replaceType toTgt t)
  +            | NewArray (t, exprs) ->
  +                Expr.NewArrayUnchecked (replaceType toTgt t, List.map (replaceExpr toTgt) exprs)
  +            | NewTuple (exprs) ->
  +                Expr.NewTuple (List.map (replaceExpr toTgt) exprs)
  +            | Lambda (v,expr) ->
  +                Expr.Lambda (replaceVar toTgt v, replaceExpr toTgt expr)
  +            | TupleGet (expr, i) ->
  +                Expr.TupleGetUnchecked (replaceExpr toTgt expr, i)
  +            | NewDelegate (t, vars, expr) ->
  +                Expr.NewDelegateUnchecked (replaceType toTgt t, List.map (replaceVar toTgt) vars, replaceExpr toTgt expr)
  +            | FieldGet (obj, f) ->
  +                match obj with
  +                | Some obj -> Expr.FieldGetUnchecked (replaceExpr toTgt obj, replaceField toTgt f)
  +                | None -> Expr.FieldGetUnchecked (replaceField toTgt f)
  +            | FieldSet (obj, f, value) ->
  +                match obj with
  +                | Some obj -> Expr.FieldSetUnchecked (replaceExpr toTgt obj, replaceField toTgt f, replaceExpr toTgt value)
  +                | None -> Expr.FieldSetUnchecked (replaceField toTgt f, replaceExpr toTgt value)
  +            | Let (var, value, body) ->
  +                Expr.LetUnchecked(replaceVar toTgt var, replaceExpr toTgt value, replaceExpr toTgt body)
  +
  +            // Eliminate some F# constructs which do not cross-target well
  +            | Application(f,e) ->
  +                replaceExpr toTgt (Expr.CallUnchecked(f, f.Type.GetMethod "Invoke", [ e ]) )
  +            | NewUnionCase(ci, es) ->
  +                replaceExpr toTgt (Expr.CallUnchecked(Reflection.FSharpValue.PreComputeUnionConstructorInfo ci, es) )
  +            | NewRecord(ci, es) ->
  +                replaceExpr toTgt (Expr.NewObjectUnchecked(FSharpValue.PreComputeRecordConstructorInfo ci, es) )
  +            | UnionCaseTest(e,uc) ->
  +                let tagInfo = FSharpValue.PreComputeUnionTagMemberInfo uc.DeclaringType
  +                let tagExpr =
  +                    match tagInfo with
  +                    | :? PropertyInfo as tagProp -> Expr.PropertyGetUnchecked(e,tagProp)
  +                    | :? MethodInfo as tagMeth ->
  +                            if tagMeth.IsStatic then Expr.CallUnchecked(tagMeth, [e])
  +                            else Expr.CallUnchecked(e,tagMeth,[])
  +                    | _ -> failwith "unreachable: unexpected result from PreComputeUnionTagMemberInfo"
  +                let tagNumber = uc.Tag
  +                replaceExpr toTgt <@@ (%%(tagExpr): int) = tagNumber @@>
  +
  +            // Traverse remaining constructs
  +            | ShapeVarUnchecked v ->
  +                Expr.Var (replaceVar toTgt v)
  +            | ShapeLambdaUnchecked _ as d ->
  +                failwithf "It's not possible to use construct %O when cross targetting to a different FSharp.Core. Make sure you're not calling a function with signature A->(B->C) instead of A->B->C (using |> causes this)." d
  +            | ShapeCombinationUnchecked (o, exprs) ->
  +                RebuildShapeCombinationUnchecked (o, List.map (replaceExpr toTgt) exprs)
  +
  +        let convToTgt ty = ty |> replaceType true
   
           let ptb = ZProvidedTypeBuilder(convToTgt)
   
           let convCode (code: Expr list -> Expr) = 
  -            (fun args -> args |> List.map replacer.ConvertTargetExprToDesignTimeExpr |> code |> replacer.ConvertDesignTimeExprToTargetExpr)
  -
  -        member internal __.TryBindILAssemblyRef(aref: ILAssemblyRef): Choice<ContextAssembly, exn> = tryBindAssemblySimple(aref.Name)
  -
  -        member internal __.TryBindAssemblyName(aref: AssemblyName): Choice<ContextAssembly, exn> = tryBindAssemblySimple(aref.Name)
  -
  -        member __.ConvertDesignTimeTypeToTargetType ty = replacer.ConvertDesignTimeTypeToTargetType ty 
  -        member __.ConvertTargetTypeToDesignTimeType ty = replacer.ConvertTargetTypeToDesignTimeType ty 
  -
  -
  -        member __.ConvertDesignTimeExprToTargetExpr e = replacer.ConvertDesignTimeExprToTargetExpr e
  -
  -        member __.ConvertTargetExprToDesignTimeExpr e = replacer.ConvertTargetExprToDesignTimeExpr e
  +            (fun tgtArgs -> 
  +                let dtArgs = List.map (replaceExpr false) tgtArgs
  +                let dtCode = code dtArgs
  +                let tgtCode = replaceExpr true dtCode
  +                tgtCode)
  +
  +        /// Gets the equivalent target type
  +        member __.ConvertDesignTimeTypeToTargetType t = t |> replaceType true
  +
  +        /// Gets the equivalent target type
  +        member __.ConvertTargetTypeToDesignTimeType t = t |> replaceType false
  +
  +        /// Gets an equivalent expression with all the types replaced with runtime equivalents
  +        member __.ConvertDesignTimeExprToTargetExpr e = e |> replaceExpr true
  +
  +        /// Gets an equivalent expression with all the types replaced with designTime equivalents
  +        member __.ConvertTargetExprToDesignTimeExpr e = e |> replaceExpr false
  +
  +        member __.TryBindILAssemblyRef(aref: ILAssemblyRef): Choice<TargetAssembly, exn> = tryBindAssemblySimple(aref.Name)
  +
  +        member __.TryBindAssemblyName(aref: AssemblyName): Choice<TargetAssembly, exn> = tryBindAssemblySimple(aref.Name)
   
           member __.ILGlobals = ilGlobals.Value
   
  
positive.code:             File.Delete assemblyFileName
  //#endif
  
          new (context: ProvidedTypesContext) = 
              let assemblyFileName = Path.ChangeExtension(Path.GetTempFileName(), "dll")
              let simpleName = Path.GetFileNameWithoutExtension(assemblyFileName)
              ProvidedAssembly(AssemblyName(simpleName), assemblyFileName, context)
  
negative.code:         member __.AddDefinitionLocation(line,column,filePath) = customAttributesImpl.AddDefinitionLocation(line, column, filePath)
          override __.GetCustomAttributesData() = customAttributesImpl.GetCustomAttributesData()
  
          member __.SetDeclaringType x = declaringType <- x // check: not set twice
  
          member __.SetFieldAttributes attributes = fieldAttrs <- attributes
          // Implement overloads
  