/// <summary>
            /// Gets the total weight between two given states in the component.
            /// </summary>
            /// <param name="srcStateIndexInComponent">The index of the source state in the component.</param>
            /// <param name="destStateIndexInComponent">The index of the destination state in the component.</param>
            /// <returns>The total weight between the given states in the component.</returns>
            public Weight GetWeight(int srcStateIndexInComponent, int destStateIndexInComponent)
            {
                Argument.CheckIfInRange(
                    srcStateIndexInComponent >= 0 && srcStateIndexInComponent < this.Size,
                    "srcStateIndexInComponent",
                    "The given index is out of range.");
                Argument.CheckIfInRange(
                    destStateIndexInComponent >= 0 && destStateIndexInComponent < this.Size,
                    "destStateIndexInComponent",
                    "The given index is out of range.");

                if (this.Size == 1)
                {
                    if (!this.singleStatePairwiseWeight.HasValue)
                    {
                        // Optimize for a common case
                        State state = this.statesInComponent[0];
                        this.singleStatePairwiseWeight = Weight.Zero;
                        for (int i = 0; i < state.TransitionCount; ++i)
                        {
                            Transition transition = state.GetTransition(i);
                            if (this.transitionFilter(transition) && transition.DestinationStateIndex == state.Index)
                            {
                                this.singleStatePairwiseWeight = Weight.Sum(
                                    this.singleStatePairwiseWeight.Value, transition.Weight);
                            }
                        }

                        this.singleStatePairwiseWeight =
                            this.useApproximateClosure
                                ? Weight.ApproximateClosure(this.singleStatePairwiseWeight.Value)
                                : Weight.Closure(this.singleStatePairwiseWeight.Value);
                    }

                    return(this.singleStatePairwiseWeight.Value);
                }

                if (this.pairwiseWeights == null)
                {
                    this.ComputePairwiseWeightsMatrix();
                }

                return(this.pairwiseWeights[srcStateIndexInComponent, destStateIndexInComponent]);
            }
            /// <summary>
            /// Computes the total weights between each pair of states in the component
            /// using the <a href="http://www.cs.nyu.edu/~mohri/pub/hwa.pdf">generalized Floyd's algorithm</a>.
            /// </summary>
            private void ComputePairwiseWeightsMatrix()
            {
                this.pairwiseWeights = Util.ArrayInit(this.Size, this.Size, (i, j) => Weight.Zero);
                for (int srcStateIndexInComponent = 0; srcStateIndexInComponent < this.Size; ++srcStateIndexInComponent)
                {
                    State state = this.statesInComponent[srcStateIndexInComponent];
                    foreach (var transition in state.Transitions)
                    {
                        State destState = state.Owner.States[transition.DestinationStateIndex];
                        int   destStateIndexInComponent;
                        if (this.transitionFilter(transition) && (destStateIndexInComponent = this.GetIndexByState(destState)) != -1)
                        {
                            this.pairwiseWeights[srcStateIndexInComponent, destStateIndexInComponent] = Weight.Sum(
                                this.pairwiseWeights[srcStateIndexInComponent, destStateIndexInComponent], transition.Weight);
                        }
                    }
                }

                for (int k = 0; k < this.Size; ++k)
                {
                    Weight loopWeight =
                        this.useApproximateClosure ? Weight.ApproximateClosure(this.pairwiseWeights[k, k]) : Weight.Closure(this.pairwiseWeights[k, k]);

                    for (int i = 0; i < this.Size; ++i)
                    {
                        if (i == k || this.pairwiseWeights[i, k].IsZero)
                        {
                            continue;
                        }

                        for (int j = 0; j < this.Size; ++j)
                        {
                            if (j == k || this.pairwiseWeights[k, j].IsZero)
                            {
                                continue;
                            }

                            Weight additionalWeight = Weight.Product(
                                this.pairwiseWeights[i, k], loopWeight, this.pairwiseWeights[k, j]);
                            this.pairwiseWeights[i, j] = Weight.Sum(this.pairwiseWeights[i, j], additionalWeight);
                        }
                    }

                    for (int i = 0; i < this.Size; ++i)
                    {
                        this.pairwiseWeights[i, k] = Weight.Product(this.pairwiseWeights[i, k], loopWeight);
                        this.pairwiseWeights[k, i] = Weight.Product(this.pairwiseWeights[k, i], loopWeight);
                    }

                    this.pairwiseWeights[k, k] = loopWeight;
                }
            }