public static InferredExpr <Field, Method> GetInferredExpr <Local, Parameter, Method, Field, Property, Event, Type, Attribute, Assembly>(
            this Microsoft.Research.CodeAnalysis.Caching.Models.Method @this,
            Method currentMethod,
            IDecodeMetaData <Local, Parameter, Method, Field, Property, Event, Type, Attribute, Assembly> mdDecoder,
            IDecodeContracts <Local, Parameter, Method, Field, Type> contractDecoder,
            bool trace
            )
        {
            if (@this.InferredExpr == null)
            {
                return(default(InferredExpr <Field, Method>));
            }
            if (@this.InferredExprHash == null)
            {
                throw new SerializationException("Cannot check deserialization, hash null");
            }

            var state             = StreamingContextStates.File | StreamingContextStates.Persistence;
            var streamingContext  = new StreamingContext(state);
            var surrogateSelector = Serializers.SurrogateSelectorFor(streamingContext, currentMethod, mdDecoder, contractDecoder, trace);
            var formatter         = new BinaryFormatter(surrogateSelector, streamingContext);
            var stream            = new System.IO.MemoryStream(@this.InferredExpr);

            try
            {
                // Fix for SerializationException below. Somehow deserialization does not find certain assemblies, so we help out
                // the resolver to find currently loaded assemblies.
                AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(DeserializeAssemblyResolve);
                var result  = (InferredExpr <Field, Method>)formatter.Deserialize(stream);
                var newHash = DummyExpressionHasher.Hash(result, trace);
                if (@this.InferredExprHash.ContentEquals(newHash))
                {
                    return(result);
                }
                throw new SerializationException(String.Format("Deserialization failed: hash differs. Expected '{0}', got '{1}'.", @this.InferredExprString, result.ToString()));
            }
            catch (SerializationException)
            {
                // "Unable to find assembly 'ClousotMain, Version=1.1.1.1, Culture=neutral, PublicKeyToken=188286aac86319f9'." just means the Clousot has been recompiled (its version number should have changed)
                // must not happen, please, please, please! ('cause the method hasn't changed)

                // this happens because there are some types in ClousotMain that get serialized. But when we build an installer, these types are actually in cccheck.exe
                // so a cache populated using Clousot does not interact well with a cache used with cccheck.
                throw;
            }
            catch (NotImplementedException e)
            {
                throw new SerializationException("Some deserialization implementation is missing, see inner exception", e);
            }
            catch (Exception e)
            {
                // ArgumentException "Object of type '<type>' cannot be converted to type '<type>'." just means the type has changed
                throw new SerializationException("Random exception while deserializing, see inner exception", e);
            }
            finally
            {
                AppDomain.CurrentDomain.AssemblyResolve -= new ResolveEventHandler(DeserializeAssemblyResolve);
            }
        }
        public static void SetInferredExpr <Local, Parameter, Method, Field, Property, Event, Type, Attribute, Assembly>(
            this Microsoft.Research.CodeAnalysis.Caching.Models.Method @this,
            InferredExpr <Field, Method> value,
            Method currentMethod,
            IDecodeMetaData <Local, Parameter, Method, Field, Property, Event, Type, Attribute, Assembly> mdDecoder,
            IDecodeContracts <Local, Parameter, Method, Field, Type> contractDecoder,
            bool trace,
            bool traceHashing)
        {
            // To make the serialization happy
            var state            = StreamingContextStates.File | StreamingContextStates.Persistence;
            var streamingContext = new StreamingContext(state);

            // We do not want to serialize CCI types directly. We want the Serialization to call us and ask if we have a better way of serializing
            var surrogateSelector = Serializers.SurrogateSelectorFor(streamingContext, currentMethod, mdDecoder, contractDecoder, trace);

            // Create the serializer
            var formatter = new BinaryFormatter(surrogateSelector, streamingContext);
            var stream    = new System.IO.MemoryStream();

            try
            {
                // Now do the work!
                formatter.Serialize(stream, value);
            }
            catch (SerializationException)
            {
                throw;
            }
            catch (NotImplementedException e)
            {
                throw new SerializationException("Some serialization implementation is missing, see inner exception", e);
            }
            catch (Exception e)
            {
                throw new SerializationException("Random exception while serializing, see inner exception", e);
            }
            @this.InferredExpr     = stream.ToArray();
            @this.InferredExprHash = DummyExpressionHasher.Hash(value, traceHashing);
            if (trace)
            {
                @this.InferredExprString = value.ToString();
            }
        }