/// <summary>
        /// Creates a new mutable from a live pip
        /// </summary>
        public static MutablePipState Create(Pip pip)
        {
            Contract.Requires(pip != null);
            Contract.Assert(PipState.Ignored == 0);

            MutablePipState mutable;

            switch (pip.PipType)
            {
            case PipType.Ipc:
                var pipAsIpc    = (IpcPip)pip;
                var serviceKind =
                    pipAsIpc.IsServiceFinalization ? ServicePipKind.ServiceFinalization :
                    pipAsIpc.ServicePipDependencies.Any() ? ServicePipKind.ServiceClient :
                    ServicePipKind.None;
                var serviceInfo = new ServiceInfo(serviceKind, pipAsIpc.ServicePipDependencies);
                mutable = new ProcessMutablePipState(pip.PipType, pip.SemiStableHash, default(PageableStoreId), serviceInfo, Process.Options.IsLight, default(RewritePolicy), AbsolutePath.Invalid, Process.MinPriority, pip.Provenance.ModuleId);
                break;

            case PipType.Process:
                var pipAsProcess = (Process)pip;
                mutable = new ProcessMutablePipState(
                    pip.PipType,
                    pip.SemiStableHash,
                    default(PageableStoreId),
                    pipAsProcess.ServiceInfo,
                    pipAsProcess.ProcessOptions,
                    pipAsProcess.RewritePolicy,
                    pipAsProcess.Executable.Path,
                    pipAsProcess.Priority,
                    pipAsProcess.Provenance.ModuleId,
                    pipAsProcess.PreserveOutputsTrustLevel);
                break;

            case PipType.CopyFile:
                var pipAsCopy = (CopyFile)pip;
                mutable = new CopyMutablePipState(pip.PipType, pip.SemiStableHash, default(PageableStoreId), pipAsCopy.OutputsMustRemainWritable);
                break;

            case PipType.SealDirectory:
                SealDirectoryKind sealDirectoryKind = default;
                bool scrub = false;
                var  seal  = (SealDirectory)pip;
                if (seal != null)
                {
                    sealDirectoryKind = seal.Kind;
                    scrub             = seal.Scrub;
                }

                mutable = new SealDirectoryMutablePipState(pip.PipType, pip.SemiStableHash, default(PageableStoreId), sealDirectoryKind, seal.Patterns, seal.IsComposite, scrub, seal.ContentFilter);
                break;

            default:
                mutable = new MutablePipState(pip.PipType, pip.SemiStableHash, default(PageableStoreId));
                break;
            }

            mutable.m_weakPip = new WeakReference <Pip>(pip);
            return(mutable);
        }
        /// <summary>
        /// Deserializes
        /// </summary>
        internal static MutablePipState Deserialize(BuildXLReader reader)
        {
            Contract.Requires(reader != null);

            var pipType        = (PipType)reader.ReadByte();
            var semiStableHash = reader.ReadInt64();
            var storeId        = PageableStoreId.Deserialize(reader);

            switch (pipType)
            {
            case PipType.Ipc:
            case PipType.Process:
                return(ProcessMutablePipState.Deserialize(reader, pipType, semiStableHash, storeId));

            case PipType.CopyFile:
                return(CopyMutablePipState.Deserialize(reader, pipType, semiStableHash, storeId));

            case PipType.SealDirectory:
                return(SealDirectoryMutablePipState.Deserialize(reader, pipType, semiStableHash, storeId));

            default:
                return(new MutablePipState(pipType, semiStableHash, storeId));
            }
        }