public override TableFactorTest.PartiallyObservedConstructorData Generate(SourceOfRandomness sourceOfRandomness, IGenerationStatus generationStatus)
            {
                int len = sourceOfRandomness.NextInt(1, 4);
                ICollection <int> taken = new HashSet <int>();

                int[] neighborIndices = new int[len];
                int[] dimensions      = new int[len];
                int[] observations    = new int[len];
                int   numObserved     = 0;

                for (int i = 0; i < len; i++)
                {
                    int j = sourceOfRandomness.NextInt(8);
                    while (taken.Contains(j))
                    {
                        j = sourceOfRandomness.NextInt(8);
                    }
                    taken.Add(j);
                    neighborIndices[i] = j;
                    dimensions[i]      = sourceOfRandomness.NextInt(1, 3);
                    if (sourceOfRandomness.NextBoolean() && numObserved + 1 < dimensions.Length)
                    {
                        observations[i] = sourceOfRandomness.NextInt(dimensions[i]);
                        numObserved++;
                    }
                    else
                    {
                        observations[i] = -1;
                    }
                }
                ConcatVectorTable t = new ConcatVectorTable(dimensions);

                TableFactorTest.ConcatVectorGenerator gen = new TableFactorTest.ConcatVectorGenerator(typeof(ConcatVector));
                foreach (int[] assn in t)
                {
                    ConcatVector vec = gen.Generate(sourceOfRandomness, generationStatus);
                    t.SetAssignmentValue(assn, null);
                }
                TableFactorTest.PartiallyObservedConstructorData data = new TableFactorTest.PartiallyObservedConstructorData();
                data.factor       = new GraphicalModel.Factor(t, neighborIndices);
                data.observations = observations;
                return(data);
            }
            private void GenerateCliques(int[] variableSizes, IList <int> startSet, ICollection <int> alreadyRepresented, GraphicalModel model, SourceOfRandomness randomness)
            {
                if (alreadyRepresented.Count == variableSizes.Length)
                {
                    return;
                }
                // Generate the clique variable set
                IList <int> cliqueContents = new List <int>();

                Sharpen.Collections.AddAll(cliqueContents, startSet);
                Sharpen.Collections.AddAll(alreadyRepresented, startSet);
                while (true)
                {
                    if (alreadyRepresented.Count == variableSizes.Length)
                    {
                        break;
                    }
                    if (cliqueContents.Count == 0 || randomness.NextDouble(0, 1) < 0.7)
                    {
                        int gen;
                        do
                        {
                            gen = randomness.NextInt(variableSizes.Length);
                        }while (alreadyRepresented.Contains(gen));
                        alreadyRepresented.Add(gen);
                        cliqueContents.Add(gen);
                    }
                    else
                    {
                        break;
                    }
                }
                // Create the actual table
                int[] neighbors     = new int[cliqueContents.Count];
                int[] neighborSizes = new int[neighbors.Length];
                for (int j = 0; j < neighbors.Length; j++)
                {
                    neighbors[j]     = cliqueContents[j];
                    neighborSizes[j] = variableSizes[neighbors[j]];
                }
                ConcatVectorTable table = new ConcatVectorTable(neighborSizes);

                foreach (int[] assignment in table)
                {
                    // Generate a vector
                    ConcatVector v = new ConcatVector(ConcatVecComponents);
                    for (int x = 0; x < ConcatVecComponents; x++)
                    {
                        if (randomness.NextBoolean())
                        {
                            v.SetSparseComponent(x, randomness.NextInt(32), randomness.NextDouble());
                        }
                        else
                        {
                            double[] val = new double[randomness.NextInt(12)];
                            for (int y = 0; y < val.Length; y++)
                            {
                                val[y] = randomness.NextDouble();
                            }
                            v.SetDenseComponent(x, val);
                        }
                    }
                    // set vec in table
                    table.SetAssignmentValue(assignment, null);
                }
                model.AddFactor(table, neighbors);
                // Pick the number of children
                IList <int> availableVariables = new List <int>();

                Sharpen.Collections.AddAll(availableVariables, cliqueContents);
                availableVariables.RemoveAll(startSet);
                int numChildren = randomness.NextInt(0, availableVariables.Count);

                if (numChildren == 0)
                {
                    return;
                }
                IList <IList <int> > children = new List <IList <int> >();

                for (int i = 0; i < numChildren; i++)
                {
                    children.Add(new List <int>());
                }
                // divide up the shared variables across the children
                int cursor = 0;

                while (true)
                {
                    if (availableVariables.Count == 0)
                    {
                        break;
                    }
                    if (children[cursor].Count == 0 || randomness.NextBoolean())
                    {
                        int gen = randomness.NextInt(availableVariables.Count);
                        children[cursor].Add(availableVariables[gen]);
                        availableVariables.Remove(availableVariables[gen]);
                    }
                    else
                    {
                        break;
                    }
                    cursor = (cursor + 1) % numChildren;
                }
                foreach (IList <int> shared1 in children)
                {
                    foreach (int i_1 in shared1)
                    {
                        foreach (IList <int> shared2 in children)
                        {
                            System.Diagnostics.Debug.Assert((shared1 == shared2 || !shared2.Contains(i_1)));
                        }
                    }
                }
                foreach (IList <int> shared in children)
                {
                    if (shared.Count > 0)
                    {
                        GenerateCliques(variableSizes, shared, alreadyRepresented, model, randomness);
                    }
                }
            }