public int[] GetSeeds(int shelves, int slot1, int slot2, int slot3, int[] priorSeeds)
        {
            LastSeedsFound = -1;
            long start = Environment.TickCount;

            progressAmt = 0;
            progressMax = 1;

            IntArray result;

            // useful pre-computes
            int twoShelves     = shelves * 2;
            int halfShelves    = shelves / 2 + 1;
            int shelvesPlusOne = shelves + 1;

            // pre-computes for tests
            int  slot1low     = slot1 * 3 - halfShelves;
            int  slot1high    = slot1 * 3 + 2 - halfShelves;
            int  threeSubHalf = 3 - halfShelves;
            int  secondSubOne = slot2 - 1;
            bool early3       = (slot3 == twoShelves) && ((shelves + 7 + halfShelves) <= twoShelves);

            // temp values
            int ench1, ench2, ench3;

            long seed;

            if (priorSeeds == null)
            {
                // reasonable guess (based on 15:7/17/30 being ~80M)
                result = new IntArray(100000000);

                progressAmt = int.MinValue;
                progressMax = -1; // progress has explicit check for this
                if (shelvesPlusOne == 16)
                {
                    do
                    {
                        seed = JavaRandom.GetSeed(progressAmt);

                        ench1 = seed.NextTwoInt16();
                        if (ench1 < slot1low || ench1 > slot1high)
                        {
                            progressAmt++; continue;
                        }

                        ench2 = (seed.NextTwoInt16() + halfShelves) * 2 / 3;
                        if (ench2 != secondSubOne)
                        {
                            progressAmt++; continue;
                        }

                        result.AddValue(progressAmt++);
                    }while (progressAmt != int.MinValue);
                    progressAmt = int.MaxValue;
                }
                else if ((shelvesPlusOne & -shelvesPlusOne) == shelvesPlusOne)
                {
                    do
                    {
                        seed = JavaRandom.GetSeed(progressAmt);

                        ench1 = seed.NextTwoIntP2(shelvesPlusOne);
                        if (ench1 < threeSubHalf)
                        {
                            if (slot1 != 1)
                            {
                                progressAmt++; continue;
                            }
                        }
                        if (ench1 < slot1low || ench1 > slot1high)
                        {
                            progressAmt++; continue;
                        }

                        ench2 = (seed.NextTwoIntP2(shelvesPlusOne) + halfShelves) * 2 / 3;
                        if (ench2 != secondSubOne)
                        {
                            progressAmt++; continue;
                        }

                        if (!early3)
                        {
                            ench3 = (seed.NextTwoIntP2(shelvesPlusOne) + halfShelves);
                            if (Math.Max(ench3, twoShelves) != slot3)
                            {
                                progressAmt++; continue;
                            }
                        }

                        result.AddValue(progressAmt++);
                    }while (progressAmt != int.MinValue);
                    progressAmt = int.MaxValue;
                }
                else
                {
                    do
                    {
                        seed = JavaRandom.GetSeed(progressAmt);

                        ench1 = seed.NextTwoIntNotP2(shelvesPlusOne);
                        if (ench1 < threeSubHalf)
                        {
                            if (slot1 != 1)
                            {
                                progressAmt++; continue;
                            }
                        }
                        if (ench1 < slot1low || ench1 > slot1high)
                        {
                            progressAmt++; continue;
                        }

                        ench2 = (seed.NextTwoIntNotP2(shelvesPlusOne) + halfShelves) * 2 / 3;
                        if (ench2 != secondSubOne)
                        {
                            progressAmt++; continue;
                        }

                        if (!early3)
                        {
                            ench3 = (seed.NextTwoIntNotP2(shelvesPlusOne) + halfShelves);
                            if (Math.Max(ench3, twoShelves) != slot3)
                            {
                                progressAmt++; continue;
                            }
                        }

                        result.AddValue(progressAmt++);
                    }while (progressAmt != int.MinValue);
                    progressAmt = int.MaxValue;
                }
            }
            else
            {
                // reasonable guess (+5 is for small quantities)
                result = new IntArray(priorSeeds.Length / 20 + 5);

                float total = (float)priorSeeds.Length;
                progressMax = priorSeeds.Length;
                foreach (int s in priorSeeds)
                {
                    // less efficient, but runs on far fewer seeds
                    seed = JavaRandom.GetSeed(s);

                    ench1 = seed.NextTwoInt(shelvesPlusOne);
                    if (ench1 < threeSubHalf)
                    {
                        if (slot1 != 1)
                        {
                            progressAmt++; continue;
                        }
                    }
                    if (ench1 < slot1low || ench1 > slot1high)
                    {
                        progressAmt++; continue;
                    }

                    ench2 = (seed.NextTwoInt(shelvesPlusOne) + halfShelves) * 2 / 3;
                    if (ench2 != secondSubOne)
                    {
                        progressAmt++; continue;
                    }

                    if (!early3)
                    {
                        ench3 = (seed.NextTwoInt(shelvesPlusOne) + halfShelves);
                        if (Math.Max(ench3, twoShelves) != slot3)
                        {
                            progressAmt++; continue;
                        }
                    }

                    progressAmt++;
                    result.AddValue(s);
                }
            }

            int[] values = result.GetValues();
            LastSeedsFound = values.Length;
            if (values.Length == 1)
            {
                TheSeed = values[0];
            }
            LastSearchTime = Environment.TickCount - start;
            return(values);
        }