internal static unsafe ChaosTargetFilter FromNative(IntPtr pointer)
        {
            if (pointer == IntPtr.Zero)
            {
                return(null);
            }

            NativeTypes.FABRIC_CHAOS_CLUSTER_ENTITY_FILTER nativeEntityFilter = *(NativeTypes.FABRIC_CHAOS_CLUSTER_ENTITY_FILTER *)pointer;

            IList <string> nodetypeInclusionList = null;

            if (nativeEntityFilter.NodeTypeInclusionList != IntPtr.Zero)
            {
                nodetypeInclusionList =
                    NativeTypes.FromNativeStringList(
                        *(NativeTypes.FABRIC_STRING_LIST *)nativeEntityFilter.NodeTypeInclusionList);
            }

            IList <string> applicationInclusionList = null;

            if (nativeEntityFilter.ApplicationInclusionList != IntPtr.Zero)
            {
                applicationInclusionList =
                    NativeTypes.FromNativeStringList(
                        *(NativeTypes.FABRIC_STRING_LIST *)nativeEntityFilter.ApplicationInclusionList);
            }

            var clusterEntityChaosFilter = new ChaosTargetFilter
            {
                NodeTypeInclusionList =
                    nodetypeInclusionList,
                ApplicationInclusionList =
                    applicationInclusionList
            };

            return(clusterEntityChaosFilter);
        }
        /// <summary>
        /// Reads the state of this object from byte array.
        /// </summary>
        /// <param name="br">A BinaryReader object</param>
        /// <exception cref="EndOfStreamException">The end of the stream is reached. </exception>
        /// <exception cref="IOException">An I/O error occurs. </exception>
        public override void Read(BinaryReader br)
        {
            long timetoRunInTicks = br.ReadInt64();

            this.TimeToRun = new TimeSpan(timetoRunInTicks);

            long waitTimeBetweenIterationsInTicks = br.ReadInt64();

            this.WaitTimeBetweenIterations = new TimeSpan(waitTimeBetweenIterationsInTicks);

            long waitTimeBetweenFaultsInTicks = br.ReadInt64();

            this.WaitTimeBetweenFaults = new TimeSpan(waitTimeBetweenFaultsInTicks);

            long maxClusterStabilizationTimeoutInTicks = br.ReadInt64();

            this.MaxClusterStabilizationTimeout = new TimeSpan(maxClusterStabilizationTimeoutInTicks);

            bool enableReplicaMoveFaults = br.ReadBoolean();

            this.EnableMoveReplicaFaults = enableReplicaMoveFaults;

            long maxConcurrentFaults = br.ReadInt64();

            this.MaxConcurrentFaults = maxConcurrentFaults;

            // Context
            int kvpCount = br.ReadInt32();

            if (kvpCount > 0)
            {
                this.Context = new Dictionary <string, string>();
                for (int i = 0; i < kvpCount; ++i)
                {
                    string key = br.ReadString();
                    string val = br.ReadString();
                    if (!this.Context.ContainsKey(key))
                    {
                        this.Context.Add(key, val);
                    }
                }
            }

            // Extensions, not available in all versions, thus optional
            if (br.BaseStream.Position != br.BaseStream.Length)
            {
                this.ReadClusterHealthPolicy(br, this.ClusterHealthPolicy);
            }
            else
            {
                TestabilityTrace.TraceSource.WriteInfo(TraceType, "ChaosParameters.Read could not find ClusterHealthPolicy; probably because, it was trying to deserialize an older version of ChaosParameters.");
            }

            if (br.BaseStream.Position != br.BaseStream.Length)
            {
                bool hasChaosTargetFilter = br.ReadBoolean();

                if (hasChaosTargetFilter)
                {
                    this.ChaosTargetFilter = new ChaosTargetFilter();
                    this.ChaosTargetFilter.Read(br);
                }
            }
        }