public Boolean LoadState(IMesDocumentManager shell, IMesDocumentManagerView shellView, String fileName)
        {
            Dictionary <String, IMesLayoutItem> layoutItems = new Dictionary <String, IMesLayoutItem>();

            if (!File.Exists(fileName))
            {
                return(false);
            }

            try
            {
                using (BinaryReader reader = new BinaryReader(new FileStream(fileName, FileMode.Open, FileAccess.Read)))
                {
                    Int32 count = reader.ReadInt32();

                    for (Int32 i = 0; i < count; i++)
                    {
                        String typeName         = reader.ReadString();
                        String contentId        = reader.ReadString();
                        Int64  stateEndPosition = reader.ReadInt64();
                        stateEndPosition += reader.BaseStream.Position;

                        Type    contentType   = Type.GetType(typeName);
                        Boolean skipStateData = true;

#warning LoadState
#if false
                        if (contentType != null)
                        {
                            var contentInstance = IoC.GetInstance(contentType, null) as ILayoutItem;

                            if (contentInstance != null)
                            {
                                layoutItems.Add(contentId, contentInstance);

                                try
                                {
                                    contentInstance.LoadState(reader);
                                    skipStateData = false;
                                }
                                catch
                                {
                                    skipStateData = true;
                                }
                            }
                        }
#endif

                        // Skip state data block if we couldn't read it.
                        if (skipStateData)
                        {
                            reader.BaseStream.Seek(stateEndPosition, SeekOrigin.Begin);
                        }
                    }

                    shellView.LoadLayout(reader.BaseStream, shell.ShowTool, shell.OpenDocument, layoutItems);
                }
            }
            catch
            {
                return(false);
            }

            return(true);
        }
        public Boolean SaveState(IMesDocumentManager shell, IMesDocumentManagerView shellView, String fileName)
        {
            try
            {
                using (BinaryWriter writer = new BinaryWriter(new FileStream(fileName, FileMode.Create, FileAccess.Write)))
                {
                    IEnumerable <IMesLayoutItem> itemStates = shell.Documents.Concat(shell.Tools.Cast <IMesLayoutItem>());

                    Int32 itemCount = 0;
                    // reserve some space for items count, it'll be updated later
                    writer.Write(itemCount);

                    foreach (IMesLayoutItem item in itemStates)
                    {
                        if (!item.ShouldReopenOnStart)
                        {
                            continue;
                        }

                        Type itemType = item.GetType();
                        List <ExportAttribute> exportAttributes = itemType
                                                                  .GetCustomAttributes(typeof(ExportAttribute), false)
                                                                  .Cast <ExportAttribute>().ToList();

                        // get exports with explicit types or names that inherit from ILayoutItem
                        List <Type> exportTypes         = new List <Type>();
                        Boolean     foundExportContract = false;
                        foreach (ExportAttribute att in exportAttributes)
                        {
                            // select the contract type if it is of type ILayoutitem.
                            Type type = att.ContractType;
                            if (LayoutBaseType.IsAssignableFrom(type))
                            {
                                exportTypes.Add(type);
                                foundExportContract = true;
                                continue;
                            }

                            // select the contract name if it is of type ILayoutItem.
                            type = GetTypeFromContractNameAsILayoutItem(att);
                            if (LayoutBaseType.IsAssignableFrom(type))
                            {
                                exportTypes.Add(type);
                                foundExportContract = true;
                            }
                        }
                        // select the viewmodel type if it is of type ILayoutItem.
                        if (!foundExportContract && LayoutBaseType.IsAssignableFrom(itemType))
                        {
                            exportTypes.Add(itemType);
                        }

                        // throw exceptions here, instead of failing silently. These are design time errors.
                        Type firstExport = exportTypes.FirstOrDefault();
                        if (firstExport == null)
                        {
                            throw new InvalidOperationException(String.Format(
                                                                    "A ViewModel that participates in LayoutItem.ShouldReopenOnStart must be decorated with an ExportAttribute who's ContractType that inherits from ILayoutItem, infringing type is {0}.", itemType));
                        }

                        if (exportTypes.Count > 1)
                        {
                            throw new InvalidOperationException(String.Format(
                                                                    "A ViewModel that participates in LayoutItem.ShouldReopenOnStart can't be decorated with more than one ExportAttribute which inherits from ILayoutItem. infringing type is {0}.", itemType));
                        }

                        String selectedTypeName = firstExport.AssemblyQualifiedName;

                        if (String.IsNullOrEmpty(selectedTypeName))
                        {
                            throw new InvalidOperationException(String.Format(
                                                                    "Could not retrieve the assembly qualified type name for {0}, most likely because the type is generic.", firstExport));
                        }
                        // TODO: it is possible to save generic types. It requires that every generic parameter is saved, along with its position in the generic tree... A lot of work.

                        writer.Write(selectedTypeName);
                        writer.Write(item.ContentId);

                        // Here's the tricky part. Because some items might fail to save their state, or they might be removed (a plug-in assembly deleted and etc.)
                        // we need to save the item's state size to be able to skip the data during deserialization.
                        // Save current stream position. We'll need it later.
                        Int64 stateSizePosition = writer.BaseStream.Position;

                        // Reserve some space for item state size
                        writer.Write(0L);

                        Int64 stateSize;

                        try
                        {
                            Int64 stateStartPosition = writer.BaseStream.Position;
                            item.SaveState(writer);
                            stateSize = writer.BaseStream.Position - stateStartPosition;
                        }
                        catch
                        {
                            stateSize = 0;
                        }

                        // Go back to the position before item's state and write the actual value.
                        writer.BaseStream.Seek(stateSizePosition, SeekOrigin.Begin);
                        writer.Write(stateSize);

                        if (stateSize > 0)
                        {
                            // Got to the end of the stream
                            writer.BaseStream.Seek(0, SeekOrigin.End);
                        }

                        itemCount++;
                    }

                    writer.BaseStream.Seek(0, SeekOrigin.Begin);
                    writer.Write(itemCount);
                    writer.BaseStream.Seek(0, SeekOrigin.End);

                    shellView.SaveLayout(writer.BaseStream);
                }
            }
            catch
            {
                return(false);
            }

            return(true);
        }