	desc = new WeakReference (m);
				return m;
			}
		}

		internal void ResetCachedData ()
		{
			// The domain may have changed (?!)

			// This check has been commented out because GetFolderDomain will fail if sourceFile changed
			// or if there is no folder info for the add-in (it may happen when using pre-generated add-in
			// scan data files).
			// A domain change at run-time is an unlikely scenario and not properly supported anyway in
			// other parts of the code. In general, changes in an already loaded add-in are not supported.

//			if (sourceFile != null)
//				domain = database.GetFolderDomain (null, Path.GetDirectoryName (sourceFile));

			desc = null;
			addin = null;
		}
			
		/// <summary>
		/// Compares two add-in versions
		/// </summary>
		/// <returns>
		/// -1 if v1 is greater than v2, 0 if v1 == v2, 1 if v1 less than v2
		/// </returns>
		/// <param name='v1'>
		/// A version
		/// </param>
		/// <param name='v2'>
		/// A version
		/// </param>
		public static int CompareVersions (string v1, string v2)
		{
			string[] a1 = v1.Split ('.');
			string[] a2 = v2.Split ('.');
			
			for (int n=0; n<a1.Length; n++) {
				if (n >= a2.Length)
					return -1;
				if (a1[n].Length == 0) {
					if (a2[n].Length != 0)
						return 1;
					continue;
				}
				try {
					int n1 = int.Parse (a1[n]);
					int n2 = int.Parse (a2[n]);
					if (n1 < n2)
						return 1;
					else if (n1 > n2)
						return -1;
				} catch {
					return 1;
				}
			}
			if (a2.Length > a1.Length)
				return 1;
			return 0;
		}

		/// <summary>
		/// Returns the identifier of an add-in
		/// </summary>
		/// <returns>
		/// The full identifier.
		/// </returns>
		/// <param name='ns'>
		/// Namespace of the add-in
		/// </param>
		/// <param name='id'>
		/// Name of the add-in
		/// </param>
		/// <param name='version'>
		/// Version of the add-in
		/// </param>
		public static string GetFullId (string ns, string id, string version)
		{
			string res;
			if (id.StartsWith ("::", StringComparison.Ordinal))
				res = id.Substring 