+#define SILVERLIGHT_KEY "7cec85d7bea7798e"
+#define WINFX_KEY "31bf3856ad364e35"
+#define ECMA_KEY "b77a5c561934e089"
+#define MSFINAL_KEY "b03f5f7f11d50a3a"
+
+typedef struct {
+ const char *name;
+ const char *from;
+ const char *to;
+} KeyRemapEntry;
+
+static KeyRemapEntry key_remap_table[] = {
+ { "Microsoft.CSharp", WINFX_KEY, MSFINAL_KEY },
+ { "System", SILVERLIGHT_KEY, ECMA_KEY },
+ { "System.ComponentModel.Composition", WINFX_KEY, ECMA_KEY },
+ { "System.ComponentModel.DataAnnotations", "ddd0da4d3e678217", WINFX_KEY },
+ { "System.Core", SILVERLIGHT_KEY, ECMA_KEY },
+ { "System.Numerics", WINFX_KEY, ECMA_KEY },
+ { "System.Runtime.Serialization", SILVERLIGHT_KEY, ECMA_KEY },
+ { "System.ServiceModel", WINFX_KEY, ECMA_KEY },
+ { "System.ServiceModel.Web", SILVERLIGHT_KEY, WINFX_KEY },
+ { "System.Windows", SILVERLIGHT_KEY, MSFINAL_KEY },
+ { "System.Xml", SILVERLIGHT_KEY, ECMA_KEY },
+ { "System.Xml.Linq", WINFX_KEY, ECMA_KEY },
+ { "System.Xml.Serialization", WINFX_KEY, MSFINAL_KEY }
+};
+
+static void
+remap_keys (MonoAssemblyName *aname)
+{
+ int i;
+ for (i = 0; i < G_N_ELEMENTS (key_remap_table); i++) {
+ const KeyRemapEntry *entry = &key_remap_table [i];
+
+ if (strcmp (aname->name, entry->name) ||
+ !mono_public_tokens_are_equal (aname->public_key_token, (const unsigned char*) entry->from))
+ continue;
+
+ memcpy (aname->public_key_token, entry->to, MONO_PUBLIC_KEY_TOKEN_LENGTH);
+
+ mono_trace (G_LOG_LEVEL_WARNING, MONO_TRACE_ASSEMBLY,
+ "Remapped public key token of retargetable assembly %s from %s to %s",
+ aname->name, entry->from, entry->to);
+ return;
+ }
+}
+