public void ProcessRequest(HttpContext context)
        {
            byte[] requestData = new byte[(int)context.Request.InputStream.Length];
            context.Request.InputStream.ReadBlock(requestData, 0, (int)context.Request.InputStream.Length);

            // this is a mysterious token of unknown purpose. It seems to vary
            // with the type of request being done.
            // On GTS requests, it's 83 characters long and begins with NDS.
            // In Random Matchup, it looks more like a base64 string, is 88
            // chars long and encodes 64 bytes of random looking data.
            // It is null terminated (variable length), followed immediately
            // by the rest of the message.
            int tokenLength = Array.IndexOf<byte>(requestData, 0x00);
            String token = StringHelper.BytesToString(requestData, 0, tokenLength, Encoding.UTF8);
            int offset = tokenLength + 1;

            RequestType type = (RequestType)BitConverter.ToInt16(requestData, offset);
            offset += 2;

            PokemonValidationResult[] results;

            switch (type)
            {
                case RequestType.RandomMatchup:
                case RequestType.GTS:
                    {
                        int pkmCount = (requestData.Length - offset) / 220;
                        results = new PokemonValidationResult[pkmCount];

                        for (int x = 0; x < results.Length; x++)
                        {
                            byte[] data = new byte[220];
                            Array.Copy(requestData, offset + x, data, 0, 220);
                            Pokemon5 pkm = new Pokemon5(data);
                            // todo: actual validation goes here
                            results[x] = PokemonValidationResult.Valid;
                        }
                    } break;
                /*
                case RequestType.BattleSubway:
                    {
                        // todo: Need more info on this structure
                    } break;
                */
                // todo: there also appears to be a Battle Video request?
                default:
                    {
                        // Don't understand this request. Give it a response containing
                        // all 00s so stuff depending on it won't break.
                        // The game accepts a hash of all 00s and doesn't care what's contained
                        // in the response beyond its expected length so this will work.
                        // fixme: Once we start generating real signatures, they will prevent
                        // this from returning the necessary number of 00s in all cases.
                        results = new PokemonValidationResult[]{
                            PokemonValidationResult.Valid,
                            PokemonValidationResult.Valid,
                            PokemonValidationResult.Valid,
                            PokemonValidationResult.Valid,
                            PokemonValidationResult.Valid,
                            PokemonValidationResult.Valid};
                    } break;
            }

            PartyValidationResult result = PartyValidationResult.Valid;
            foreach (PokemonValidationResult pkr in results)
            {
                if (pkr != PokemonValidationResult.Valid) result = PartyValidationResult.Invalid;
            }

            context.Response.ContentType = "text/plain";
            context.Response.OutputStream.WriteByte((byte)result); // success
            foreach (PokemonValidationResult pkr in results)
            {
                context.Response.OutputStream.Write(BitConverter.GetBytes((int)pkr), 0, 4);
            }
            // placeholder for signature.
            // Should be 128 bytes of an unknown hashing/signing algorithm
            context.Response.OutputStream.Write(new byte[128], 0, 128);
        }
        public void ProcessRequest(HttpContext context)
        {
            byte[] requestData = new byte[(int)context.Request.InputStream.Length];
            context.Request.InputStream.ReadBlock(requestData, 0, (int)context.Request.InputStream.Length);

            // this is a mysterious token of unknown purpose. It seems to vary
            // with the type of request being done.
            // On GTS requests, it's 83 characters long and begins with NDS.
            // In Random Matchup, it looks more like a base64 string, is 88
            // chars long and encodes 64 bytes of random looking data.
            // It is null terminated (variable length), followed immediately
            // by the rest of the message.
            int    tokenLength = Array.IndexOf <byte>(requestData, 0x00);
            String token       = StringHelper.BytesToString(requestData, 0, tokenLength, Encoding.UTF8);
            int    offset      = tokenLength + 1;

            RequestType type = (RequestType)BitConverter.ToInt16(requestData, offset);

            offset += 2;

            PokemonValidationResult[] results;

            switch (type)
            {
            case RequestType.RandomMatchup:
            case RequestType.GTS:
            {
                int pkmCount = (requestData.Length - offset) / 220;
                results = new PokemonValidationResult[pkmCount];

                for (int x = 0; x < results.Length; x++)
                {
                    byte[] data = new byte[220];
                    Array.Copy(requestData, offset + x, data, 0, 220);
                    Pokemon5 pkm = new Pokemon5(data);
                    // todo: actual validation goes here
                    results[x] = PokemonValidationResult.Valid;
                }
            } break;

            /*
             * case RequestType.BattleSubway:
             *  {
             *      // todo: Need more info on this structure
             *  } break;
             */
            // todo: there also appears to be a Battle Video request?
            default:
            {
                // Don't understand this request. Give it a response containing
                // all 00s so stuff depending on it won't break.
                // The game accepts a hash of all 00s and doesn't care what's contained
                // in the response beyond its expected length so this will work.
                // fixme: Once we start generating real signatures, they will prevent
                // this from returning the necessary number of 00s in all cases.
                results = new PokemonValidationResult[] {
                    PokemonValidationResult.Valid,
                    PokemonValidationResult.Valid,
                    PokemonValidationResult.Valid,
                    PokemonValidationResult.Valid,
                    PokemonValidationResult.Valid,
                    PokemonValidationResult.Valid
                };
            } break;
            }

            PartyValidationResult result = PartyValidationResult.Valid;

            foreach (PokemonValidationResult pkr in results)
            {
                if (pkr != PokemonValidationResult.Valid)
                {
                    result = PartyValidationResult.Invalid;
                }
            }

            context.Response.ContentType = "text/plain";
            context.Response.OutputStream.WriteByte((byte)result); // success
            foreach (PokemonValidationResult pkr in results)
            {
                context.Response.OutputStream.Write(BitConverter.GetBytes((int)pkr), 0, 4);
            }
            // placeholder for signature.
            // Should be 128 bytes of an unknown hashing/signing algorithm
            context.Response.OutputStream.Write(new byte[128], 0, 128);
        }