public ISlicerResult DoWork(Func <SliceDefinition, ISliceWorkResult> workOnSlice)
        {
            var result = new SlicesResult <Method>();

            var directory = DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss");

            directory += " ";
            if (this.environment.AssembliesToAnalyze.Count <= 2)
            {
                directory += String.Join(" ", this.environment.AssembliesToAnalyze.Select(this.mdDecoder.Name));
            }
            else
            {
                directory += this.mdDecoder.Name(this.environment.AssembliesToAnalyze.First()) + " and others";
            }

            var baseDirectory = this.options.cacheDirectory ?? "";

            directory = Path.Combine(baseDirectory, directory);

            if (!Directory.Exists(directory))
            {
                Directory.CreateDirectory(directory);
            }

            foreach (var assembly in this.environment.AssembliesToAnalyze)
            {
                foreach (var method in this.Methods(assembly))
                {
                    var methods = new List <Method> {
                        method
                    };
                    var declaringType = this.mdDecoder.DeclaringType(method);
                    var sliceName     = String.Format("{0}.{1}.{2}.{3}", this.mdDecoder.Namespace(declaringType), this.mdDecoder.Name(declaringType), this.mdDecoder.Name(method), this.randGenerator.Next(0x10000).ToString("X4"));
                    sliceName = SanitizeName(sliceName);

                    output.WriteLine("Building slice {0} ...", sliceName);

#if TRACE_PERFORMANCE
                    var startTime = DateTime.Now;
#endif
                    var slice = this.BuildSlice(sliceName, assembly, methods, options.InferObjectInvariantsOnlyForReadonlyFields);

                    string           dll                    = null;
                    ISliceWorkResult sliceResult            = null;
                    bool             writeSliceToFileResult = false;

                    try
                    {
                        // This is Mike
                        writeSliceToFileResult = this.environment.CodeWriter.WriteSliceToFile(slice, directory, out dll);
                    }
                    catch (Exception e)
                    {
                        sliceResult = new WriteSliceToFileException(e);
                    }

                    if (sliceResult != null)
                    {
                    }
                    else if (!writeSliceToFileResult)
                    {
                        //throw new NotImplementedException();
                        output.WriteLine("Failed to write slice {0}", sliceName);

                        sliceResult = new WriteSliceToFileError(sliceName, directory);
                    }
                    else
                    {
                        if (workOnSlice != null)
                        {
#if DEBUG
                            Func <Method, MethodId> createMethodId = (Method m) => new MethodId(this.GetMethodHash(m), this.mdDecoder.FullName(m));
#else
                            Func <Method, MethodId> createMethodId = m => this.GetMethodHash(m).AsMethodId();
#endif

                            var hashedMethods              = methods.Select(createMethodId).ToArray(); // ToArray to force computation
                            var hashedDependencies         = slice.Dependencies.Select(createMethodId).ToArray();
                            var hashedMethodsInTheSameType = slice.OtherMethodsInTheSameType.Select(createMethodId).ToArray();

                            dll = Path.GetFullPath(dll);

                            var sliceDef = new SliceDefinition(hashedMethods, hashedDependencies, hashedMethodsInTheSameType, dll);

                            try
                            {
                                sliceResult = workOnSlice(sliceDef);
                            }
                            catch (Exception e)
                            {
                                sliceResult = new WorkOnSliceException(e);
                            }
                        }
                        else
                        {
                            sliceResult = null; // todo?
                        }
                    }

#if TRACE_PERFORMANCE
                    output.WriteLine("Time to build the slice: {0}, memory: {1}Mb", DateTime.Now - startTime, System.GC.GetTotalMemory(true) / (1024 * 1024));
#endif
                    result.AddSliceResult(methods, sliceResult);
                    this.methodDriverCache.Clear();
                }

                //this.methodDriverCache.Clear();
                this.methodHashCache.Clear();
            }

            return(result);
        }
 public void AddSliceResult(List <Method> methods, ISliceWorkResult sliceResult)
 {
     this.slicesResults.Add(new KeyValuePair <List <Method>, ISliceWorkResult>(methods, sliceResult));
 }