public static AssemblyIdentity GetAssemblyIdentity(EnvDTE.Project project, MetadataReaderHost host) {
      Contract.Requires(project != null);
      Contract.Requires(host != null);

      if (!ProjectIsAvailable(project))
        return null;

      VSServiceProvider.Current.Logger.WriteToLog("Getting the assembly identity for project: " + project.Name);

      string location_RootDir = null;
      string location_RelativeAssemblyDir = null;
      string location_FileName = null;
      string location = null;
      IName iName = null;
      string culture = "";//TODO: Find out where to get culture information.
      Version version = new Version();
      AssemblyIdentity result = null;
      try {
        var activePropCount = 
          project.ConfigurationManager != null && project.ConfigurationManager.ActiveConfiguration != null && project.ConfigurationManager.ActiveConfiguration.Properties != null ?
          project.ConfigurationManager.ActiveConfiguration.Properties.Count : 0;
        for (int i = activePropCount; 1 <= i; i--) {
          var prop = project.ConfigurationManager.ActiveConfiguration.Properties.Item(i);
          if (prop == null) continue;
          if (prop.Name == "OutputPath") {
            location_RelativeAssemblyDir = prop.Value as string;
            break;
          }
        }
        var propCount = project.Properties != null ? project.Properties.Count : 0;
        for (int i = propCount; 1 <= i; i--) {
          var prop = project.Properties.Item(i);
          if (prop == null) continue;
          switch (prop.Name) {
            case "AssemblyName":
              iName = host.NameTable.GetNameFor(prop.Value as string);
              break;
            case "AssemblyVersion":
              var stringVersion = prop.Value as string;
              if (!Version.TryParse(stringVersion, out version))
              {
                  version = new Version();
              }
              Contract.Assume(version != null);
              break;
            case "FullPath":
              location_RootDir = prop.Value as string;
              break;
            case "OutputFileName":
              location_FileName = prop.Value as string;
              break;
            default:
              break;
          }
        }
      } catch (COMException comEx) {
        VSServiceProvider.Current.Logger.WriteToLog("COM Exception while trying to access project's properties.");
        VSServiceProvider.Current.Logger.WriteToLog("Message: " + comEx.Message);
        if (comEx.Message.Contains(COMExceptionMessage_ProjectUnavailable)) {
          VSServiceProvider.Current.Logger.WriteToLog("Returning null.");
          return null;
        } else if (((uint)comEx.ErrorCode) == 0x80020009) {
          VSServiceProvider.Current.Logger.WriteToLog("Returning null.");
          return null;
        } else {
          throw comEx;
        }
      }

      //Check if we got enough information from VS to build the location
      if (location_FileName == null
        || location_RelativeAssemblyDir == null
        || location_RootDir == null) {
        VSServiceProvider.Current.Logger.WriteToLog("Couldn't find path to the project's output assembly.");
        return null;
      }

      //Set the location of the output assembly
      location = Path.Combine(location_RootDir, location_RelativeAssemblyDir, location_FileName);

      //Check that the output assembly exists
      if (!File.Exists(location)) {
        VSServiceProvider.Current.Logger.WriteToLog("Project output assembly could not be found at the location given by Visual Studio: " + location);
      }

      //Check our other information from VS
      if (iName == null
        || string.IsNullOrEmpty(location)) {
        VSServiceProvider.Current.Logger.WriteToLog("Couldn't gather sufficient information from the project to construct an assembly identity.");
        return null;
      }

      //Success
      Contract.Assert(version != null);
      Contract.Assert(culture != null);
      result = new AssemblyIdentity(iName, culture, version, Enumerable<byte>.Empty, location);
      host.AddLibPath(Path.Combine(location_RootDir, location_RelativeAssemblyDir, "CodeContracts"));
      host.AddLibPath(Path.Combine(location_RootDir, location_RelativeAssemblyDir, @"..\Debug\CodeContracts"));

      return result;
    }
    public static void AddProjectReferencesPathsIntoHost(References references, MetadataReaderHost host) {
      Contract.Requires(host != null);

      if (references == null) return;
      
      for (int i = 1; i <= references.Count; i++) {
        var tempRef = references.Item(i);
        if (tempRef == null) continue;

        var refPath = tempRef.Path;
        if (!String.IsNullOrEmpty(refPath)) {
          var refDir = Path.GetDirectoryName(refPath);
          if (refDir != null) {
            host.AddLibPath(refDir);
            var referenceAssemblyPath = Path.Combine(refDir, "CodeContracts");
            if (System.IO.Directory.Exists(referenceAssemblyPath))
              host.AddLibPath(referenceAssemblyPath);

          }
        }
      }
    }