dw_fluffos_v2/
dw_fluffos_v2/fluffos-2.9-ds2.05/
dw_fluffos_v2/fluffos-2.9-ds2.05/ChangeLog.old/
dw_fluffos_v2/fluffos-2.9-ds2.05/Win32/
dw_fluffos_v2/fluffos-2.9-ds2.05/compat/
dw_fluffos_v2/fluffos-2.9-ds2.05/compat/simuls/
dw_fluffos_v2/fluffos-2.9-ds2.05/include/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/clone/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/command/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/data/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/etc/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/include/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/inherit/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/inherit/master/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/log/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/single/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/single/tests/compiler/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/single/tests/efuns/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/single/tests/operators/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/u/
dw_fluffos_v2/fluffos-2.9-ds2.05/tmp/
dw_fluffos_v2/fluffos-2.9-ds2.05/windows/
dw_fluffos_v2/lib/
dw_fluffos_v2/lib/binaries/cmds/
dw_fluffos_v2/lib/binaries/cmds/creator/
dw_fluffos_v2/lib/binaries/cmds/living/
dw_fluffos_v2/lib/binaries/cmds/player/
dw_fluffos_v2/lib/binaries/d/admin/obj/
dw_fluffos_v2/lib/binaries/d/liaison/
dw_fluffos_v2/lib/binaries/global/virtual/
dw_fluffos_v2/lib/binaries/global/virtual/setup_compiler/
dw_fluffos_v2/lib/binaries/obj/handlers/autodoc/
dw_fluffos_v2/lib/binaries/obj/handlers/terrain_things/
dw_fluffos_v2/lib/binaries/obj/misc/
dw_fluffos_v2/lib/binaries/obj/misc/buckets/
dw_fluffos_v2/lib/binaries/obj/monster/
dw_fluffos_v2/lib/binaries/obj/reactions/
dw_fluffos_v2/lib/binaries/obj/reagents/
dw_fluffos_v2/lib/binaries/secure/cmds/creator/
dw_fluffos_v2/lib/binaries/secure/master/
dw_fluffos_v2/lib/binaries/std/
dw_fluffos_v2/lib/binaries/std/dom/
dw_fluffos_v2/lib/binaries/std/effects/object/
dw_fluffos_v2/lib/binaries/std/guilds/
dw_fluffos_v2/lib/binaries/std/languages/
dw_fluffos_v2/lib/binaries/std/races/
dw_fluffos_v2/lib/binaries/std/room/
dw_fluffos_v2/lib/binaries/std/room/basic/
dw_fluffos_v2/lib/binaries/std/shops/
dw_fluffos_v2/lib/binaries/std/shops/inherit/
dw_fluffos_v2/lib/binaries/www/
dw_fluffos_v2/lib/cmds/guild-race/
dw_fluffos_v2/lib/cmds/guild-race/crafts/
dw_fluffos_v2/lib/cmds/guild-race/other/
dw_fluffos_v2/lib/cmds/playtester/
dw_fluffos_v2/lib/cmds/playtester/senior/
dw_fluffos_v2/lib/d/admin/
dw_fluffos_v2/lib/d/admin/log/
dw_fluffos_v2/lib/d/admin/mapper/31-10-01/mapmaker/event/
dw_fluffos_v2/lib/d/admin/meetings/
dw_fluffos_v2/lib/d/admin/obj/
dw_fluffos_v2/lib/d/admin/room/we_care/
dw_fluffos_v2/lib/d/admin/save/
dw_fluffos_v2/lib/d/dist/
dw_fluffos_v2/lib/d/dist/mtf/
dw_fluffos_v2/lib/d/dist/pumpkin/
dw_fluffos_v2/lib/d/dist/pumpkin/chars/
dw_fluffos_v2/lib/d/dist/pumpkin/desert/
dw_fluffos_v2/lib/d/dist/pumpkin/gumboot/
dw_fluffos_v2/lib/d/dist/pumpkin/hospital/
dw_fluffos_v2/lib/d/dist/pumpkin/inherit/
dw_fluffos_v2/lib/d/dist/pumpkin/map/
dw_fluffos_v2/lib/d/dist/pumpkin/plain/
dw_fluffos_v2/lib/d/dist/pumpkin/pumpkin/
dw_fluffos_v2/lib/d/dist/pumpkin/save/
dw_fluffos_v2/lib/d/dist/pumpkin/squash/
dw_fluffos_v2/lib/d/dist/pumpkin/terrain/
dw_fluffos_v2/lib/d/dist/pumpkin/woods/
dw_fluffos_v2/lib/d/dist/start/
dw_fluffos_v2/lib/d/learning/TinyTown/buildings/
dw_fluffos_v2/lib/d/learning/TinyTown/map/
dw_fluffos_v2/lib/d/learning/TinyTown/roads/
dw_fluffos_v2/lib/d/learning/add_command/
dw_fluffos_v2/lib/d/learning/arms_and_weps/
dw_fluffos_v2/lib/d/learning/chars/
dw_fluffos_v2/lib/d/learning/cutnpaste/
dw_fluffos_v2/lib/d/learning/examples/npcs/
dw_fluffos_v2/lib/d/learning/examples/player_houses/npcs/
dw_fluffos_v2/lib/d/learning/examples/terrain_map/basic/
dw_fluffos_v2/lib/d/learning/functions/
dw_fluffos_v2/lib/d/learning/handlers/
dw_fluffos_v2/lib/d/learning/help_topics/npcs/
dw_fluffos_v2/lib/d/learning/help_topics/objects/
dw_fluffos_v2/lib/d/learning/help_topics/rcs_demo/
dw_fluffos_v2/lib/d/learning/help_topics/rooms/
dw_fluffos_v2/lib/d/learning/help_topics/rooms/crowd/
dw_fluffos_v2/lib/d/learning/help_topics/rooms/situations/
dw_fluffos_v2/lib/d/learning/items/
dw_fluffos_v2/lib/d/learning/save/
dw_fluffos_v2/lib/d/liaison/
dw_fluffos_v2/lib/d/liaison/NEWBIE/doc/
dw_fluffos_v2/lib/d/liaison/NEWBIE/save/oldlog/
dw_fluffos_v2/lib/db/
dw_fluffos_v2/lib/doc/
dw_fluffos_v2/lib/doc/creator/
dw_fluffos_v2/lib/doc/creator/autodoc/include/reaction/
dw_fluffos_v2/lib/doc/creator/autodoc/include/ritual_system/
dw_fluffos_v2/lib/doc/creator/autodoc/include/talker/
dw_fluffos_v2/lib/doc/creator/autodoc/include/terrain_map/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/baggage/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/clock/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/clothing/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/cont_save/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/corpse/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/money/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/monster/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/scabbard/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/service_provider/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/state_changer/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/wand/
dw_fluffos_v2/lib/doc/creator/autodoc/std/book_dir/
dw_fluffos_v2/lib/doc/creator/autodoc/std/key/
dw_fluffos_v2/lib/doc/creator/autodoc/std/learning/
dw_fluffos_v2/lib/doc/creator/autodoc/std/map/
dw_fluffos_v2/lib/doc/creator/autodoc/std/race/
dw_fluffos_v2/lib/doc/creator/autodoc/std/weapon_logic/
dw_fluffos_v2/lib/doc/creator/files/
dw_fluffos_v2/lib/doc/creator/policy/
dw_fluffos_v2/lib/doc/creator/room/
dw_fluffos_v2/lib/doc/effects/
dw_fluffos_v2/lib/doc/ideas/
dw_fluffos_v2/lib/doc/known_command/
dw_fluffos_v2/lib/doc/lpc/basic_manual/
dw_fluffos_v2/lib/doc/lpc/intermediate/
dw_fluffos_v2/lib/doc/new/add_command/
dw_fluffos_v2/lib/doc/new/handlers/
dw_fluffos_v2/lib/doc/new/living/
dw_fluffos_v2/lib/doc/new/living/race/
dw_fluffos_v2/lib/doc/new/living/spells/
dw_fluffos_v2/lib/doc/new/player/
dw_fluffos_v2/lib/doc/new/room/guild/
dw_fluffos_v2/lib/doc/new/room/outside/
dw_fluffos_v2/lib/doc/new/room/storeroom/
dw_fluffos_v2/lib/doc/object/
dw_fluffos_v2/lib/doc/playtesters/
dw_fluffos_v2/lib/doc/policy/
dw_fluffos_v2/lib/doc/weapons/
dw_fluffos_v2/lib/global/handlers/
dw_fluffos_v2/lib/global/virtual/setup_compiler/
dw_fluffos_v2/lib/include/
dw_fluffos_v2/lib/include/cmds/
dw_fluffos_v2/lib/include/effects/
dw_fluffos_v2/lib/include/npc/
dw_fluffos_v2/lib/include/shops/
dw_fluffos_v2/lib/net/daemon/chars/
dw_fluffos_v2/lib/net/inherit/
dw_fluffos_v2/lib/net/intermud3/
dw_fluffos_v2/lib/net/intermud3/services/
dw_fluffos_v2/lib/net/obj/
dw_fluffos_v2/lib/net/save/
dw_fluffos_v2/lib/net/smnmp/
dw_fluffos_v2/lib/net/snmp/
dw_fluffos_v2/lib/obj/amulets/
dw_fluffos_v2/lib/obj/b_day/
dw_fluffos_v2/lib/obj/examples/
dw_fluffos_v2/lib/obj/food/alcohol/
dw_fluffos_v2/lib/obj/food/chocolates/
dw_fluffos_v2/lib/obj/food/fruits/
dw_fluffos_v2/lib/obj/food/meat/
dw_fluffos_v2/lib/obj/food/nuts/
dw_fluffos_v2/lib/obj/food/seafood/
dw_fluffos_v2/lib/obj/food/vegetables/
dw_fluffos_v2/lib/obj/fungi/
dw_fluffos_v2/lib/obj/furnitures/artwork/
dw_fluffos_v2/lib/obj/furnitures/bathroom/
dw_fluffos_v2/lib/obj/furnitures/beds/
dw_fluffos_v2/lib/obj/furnitures/cabinets/
dw_fluffos_v2/lib/obj/furnitures/chairs/
dw_fluffos_v2/lib/obj/furnitures/chests/
dw_fluffos_v2/lib/obj/furnitures/clocks/
dw_fluffos_v2/lib/obj/furnitures/crockery/
dw_fluffos_v2/lib/obj/furnitures/cupboards/
dw_fluffos_v2/lib/obj/furnitures/cushions/
dw_fluffos_v2/lib/obj/furnitures/fake_plants/
dw_fluffos_v2/lib/obj/furnitures/lamps/
dw_fluffos_v2/lib/obj/furnitures/mirrors/
dw_fluffos_v2/lib/obj/furnitures/outdoor/
dw_fluffos_v2/lib/obj/furnitures/safes/
dw_fluffos_v2/lib/obj/furnitures/shelves/
dw_fluffos_v2/lib/obj/furnitures/sideboards/
dw_fluffos_v2/lib/obj/furnitures/sofas/
dw_fluffos_v2/lib/obj/furnitures/stoves/
dw_fluffos_v2/lib/obj/furnitures/tables/
dw_fluffos_v2/lib/obj/furnitures/wardrobes/
dw_fluffos_v2/lib/obj/handlers/
dw_fluffos_v2/lib/obj/handlers/autodoc/
dw_fluffos_v2/lib/obj/jewellery/anklets/
dw_fluffos_v2/lib/obj/jewellery/bracelets/
dw_fluffos_v2/lib/obj/jewellery/earrings/
dw_fluffos_v2/lib/obj/jewellery/misc/
dw_fluffos_v2/lib/obj/jewellery/necklaces/
dw_fluffos_v2/lib/obj/jewellery/rings/
dw_fluffos_v2/lib/obj/media/
dw_fluffos_v2/lib/obj/misc/buckets/
dw_fluffos_v2/lib/obj/misc/jars/
dw_fluffos_v2/lib/obj/misc/papers/
dw_fluffos_v2/lib/obj/misc/player_shop/
dw_fluffos_v2/lib/obj/misc/shops/
dw_fluffos_v2/lib/obj/misc/traps/
dw_fluffos_v2/lib/obj/monster/
dw_fluffos_v2/lib/obj/monster/godmother/
dw_fluffos_v2/lib/obj/monster/transport/
dw_fluffos_v2/lib/obj/plants/inherit/
dw_fluffos_v2/lib/obj/potions/
dw_fluffos_v2/lib/open/boards/
dw_fluffos_v2/lib/save/autodoc/
dw_fluffos_v2/lib/save/bank_accounts/
dw_fluffos_v2/lib/save/boards/frog/
dw_fluffos_v2/lib/save/books/bed_catalog/
dw_fluffos_v2/lib/save/creators/
dw_fluffos_v2/lib/save/mail/
dw_fluffos_v2/lib/save/mail/p/
dw_fluffos_v2/lib/save/soul/data/
dw_fluffos_v2/lib/save/tasks/
dw_fluffos_v2/lib/save/vaults/
dw_fluffos_v2/lib/secure/cmds/lord/
dw_fluffos_v2/lib/secure/config/
dw_fluffos_v2/lib/secure/items/
dw_fluffos_v2/lib/secure/player/
dw_fluffos_v2/lib/soul/
dw_fluffos_v2/lib/soul/i/
dw_fluffos_v2/lib/soul/j/
dw_fluffos_v2/lib/soul/k/
dw_fluffos_v2/lib/soul/o/
dw_fluffos_v2/lib/soul/q/
dw_fluffos_v2/lib/soul/to_approve/
dw_fluffos_v2/lib/soul/u/
dw_fluffos_v2/lib/soul/v/
dw_fluffos_v2/lib/soul/wish_list/
dw_fluffos_v2/lib/soul/y/
dw_fluffos_v2/lib/soul/z/
dw_fluffos_v2/lib/std/creator/
dw_fluffos_v2/lib/std/effects/
dw_fluffos_v2/lib/std/effects/attached/
dw_fluffos_v2/lib/std/effects/external/
dw_fluffos_v2/lib/std/effects/fighting/
dw_fluffos_v2/lib/std/effects/other/
dw_fluffos_v2/lib/std/environ/
dw_fluffos_v2/lib/std/guilds/
dw_fluffos_v2/lib/std/hospital/
dw_fluffos_v2/lib/std/house/
dw_fluffos_v2/lib/std/house/onebedhouse/
dw_fluffos_v2/lib/std/house/onebedhut/
dw_fluffos_v2/lib/std/house/tworoomflat/
dw_fluffos_v2/lib/std/languages/
dw_fluffos_v2/lib/std/liquids/
dw_fluffos_v2/lib/std/nationality/
dw_fluffos_v2/lib/std/nationality/accents/
dw_fluffos_v2/lib/std/nationality/accents/national/
dw_fluffos_v2/lib/std/nationality/accents/regional/
dw_fluffos_v2/lib/std/npc/goals/
dw_fluffos_v2/lib/std/npc/goals/basic/
dw_fluffos_v2/lib/std/npc/goals/misc/
dw_fluffos_v2/lib/std/npc/inherit/
dw_fluffos_v2/lib/std/npc/plans/
dw_fluffos_v2/lib/std/npc/plans/basic/
dw_fluffos_v2/lib/std/outsides/
dw_fluffos_v2/lib/std/races/shadows/
dw_fluffos_v2/lib/std/room/basic/topography/
dw_fluffos_v2/lib/std/room/controller/
dw_fluffos_v2/lib/std/room/controller/topography/
dw_fluffos_v2/lib/std/room/furniture/games/
dw_fluffos_v2/lib/std/room/furniture/inherit/
dw_fluffos_v2/lib/std/room/inherit/carriage/
dw_fluffos_v2/lib/std/room/inherit/topography/
dw_fluffos_v2/lib/std/room/punishments/
dw_fluffos_v2/lib/std/room/topography/area/
dw_fluffos_v2/lib/std/room/topography/iroom/
dw_fluffos_v2/lib/std/room/topography/milestone/
dw_fluffos_v2/lib/std/shadows/
dw_fluffos_v2/lib/std/shadows/attached/
dw_fluffos_v2/lib/std/shadows/curses/
dw_fluffos_v2/lib/std/shadows/disease/
dw_fluffos_v2/lib/std/shadows/fighting/
dw_fluffos_v2/lib/std/shadows/room/
dw_fluffos_v2/lib/std/shops/controllers/
dw_fluffos_v2/lib/std/shops/objs/
dw_fluffos_v2/lib/std/shops/player_shop/
dw_fluffos_v2/lib/std/shops/player_shop/office_code/
dw_fluffos_v2/lib/std/socket/
dw_fluffos_v2/lib/www/
dw_fluffos_v2/lib/www/external/autodoc/
dw_fluffos_v2/lib/www/external/java/telnet/Documentation/
dw_fluffos_v2/lib/www/external/java/telnet/Documentation/images/
dw_fluffos_v2/lib/www/external/java/telnet/examples/
dw_fluffos_v2/lib/www/external/java/telnet/tools/
dw_fluffos_v2/lib/www/pics/
dw_fluffos_v2/lib/www/secure/creator/
dw_fluffos_v2/lib/www/secure/editors/
dw_fluffos_v2/lib/www/secure/survey_results/
dw_fluffos_v2/win32/
/**
 * This is the handler for all things clubby, a club being a group of
 * players.  Each club must have a unique name.  It also handles elections
 * for various club positions.
 * @author Pinkfish
 * @started Sun Sep 27 03:35:42 EDT 1998
 */
inherit "/obj/handlers/inherit/club_elected";

#define __CLUBS_H_NO_CLASSES

#include <clubs.h>
#include <broadcaster.h>
#include <player_handler.h>
#include <player_handler.h>

// Special variables to control the club inner workings.
private nosave mapping _discussion_items;

#define CLUB_DISCUSS_FUNCTION_OBJECT     0
#define CLUB_DISCUSS_FUNCTION_FUNCTION   1

#define CLUB_DISCUSS_QUORUM_COMMITTEE   75
#define CLUB_DISCUSS_QUORUM_OPEN        25

private void add_club_discussion(int type,
                                 function func);
protected int remove_discussion_item(string club_name,
                                     class discussion_idea item);
private mixed club_discuss_new_position(int message,
                                        string club_name,
                                        class discussion_idea frog);
private mixed club_discuss_position_name(int message,
                                         string club_name,
                                         class discussion_idea frog,
                                         string arg1, 
                                         string arg2);
private mixed club_discuss_position_remove(int message,
                                           string club_name,
                                           class discussion_idea frog,
                                           string arg1, 
                                           string arg2);
private mixed club_discuss_description(int message,
                                       string club_name,
                                       class discussion_idea frog);
private mixed club_discuss_memo(int message,
                                string club_name,
                                class discussion_idea frog);
private mixed club_discuss_secret(int message,
                                  string club_name,
                                  class discussion_idea frog);
private mixed club_discuss_remove_member(int message,
                                         string club_name,
                                         class discussion_idea frog,
                                         string member);
private mixed club_discuss_no_confidence(int message,
                                         string club_name,
                                         class discussion_idea frog,
                                         string arg1, 
                                         string arg2);
private mixed club_discuss_election(int message,
                                    string club_name,
                                    class discussion_idea frog,
                                    string arg1, 
                                    string arg2);
private mixed club_discuss_nomination(int message,
                                      string club_name,
                                      class discussion_idea frog,
                                      string arg1,
                                      string arg2);
private mixed club_discuss_function(int message,
                                    string club_name,
                                    class discussion_idea frog,
                                    string arg1,
                                    string arg2);
private mixed club_discuss_create_account(int message,
                                    string club_name,
                                    class discussion_idea frog,
                                    string arg1,
                                    string arg2);
class discussion_idea query_discussion_item_by_type(string club_name,
                                                    int type,
                                                    class discussion_idea idea);
protected mixed send_discuss_message(string club_name,
                                    int message,
                                    class discussion_idea item,
                                    string arg1,
                                    string arg2);
protected void broadcast_discuss_message(string club_name,
                                         int message,
                                         string arg1,
                                         string arg2);
int add_discussion_item(string club,
                        int type,
                        string added_by,
                        string name,
                        string info,
                        string *choices,
                        int time_to_finish,
                        mixed extra_data);
int setup_by_election(string club,
                      string position,
                      string info);
int is_discuss_nominateable(string club_name,
                            int id);

void create() {
   _discussion_items = ([ ]);
   ::create();

   add_club_discussion(CLUB_DISCUSS_NEW_POSITION,
                       (: club_discuss_new_position :));
   add_club_discussion(CLUB_DISCUSS_POSITION_NAME,
                       (: club_discuss_position_name :));
   add_club_discussion(CLUB_DISCUSS_POSITION_REMOVE,
                       (: club_discuss_position_remove :));
   add_club_discussion(CLUB_DISCUSS_DESCRIPTION,
                       (: club_discuss_description :));
   add_club_discussion(CLUB_DISCUSS_MEMO,
                       (: club_discuss_memo :));
   add_club_discussion(CLUB_DISCUSS_MEMBER_REMOVE,
                       (: club_discuss_remove_member :));
   add_club_discussion(CLUB_DISCUSS_SECRET_TYPE,
                       (: club_discuss_secret :));
   add_club_discussion(CLUB_DISCUSS_NO_CONFIDENCE,
                       (: club_discuss_no_confidence :));
   add_club_discussion(CLUB_DISCUSS_ELECTION,
                       (: club_discuss_election :));
   add_club_discussion(CLUB_DISCUSS_NOMINATION,
                       (: club_discuss_nomination :));
   add_club_discussion(CLUB_DISCUSS_FUNCTION,
                       (: club_discuss_function :));
   add_club_discussion(CLUB_DISCUSS_CREATE_ACCOUNT,
                       (: club_discuss_create_account :));
} /* create() */

private void add_club_discussion(int type,
                                 function func) {
   _discussion_items[type] = func;
} /* add_club_discussion() */

/**
 * This method is called when a discussion item is finished.  It then
 * archives it or whatever else it wishes to do with the item
 * @param club_name the name of the club
 * @param item the text string of the finished item
 */
protected int archive_discussion_item(string club_name,
                                      string subject,
                                      string item) {
   if (is_elected_club(club_name)) {
      // Do some useful archiving.
      add_archive(club_name,
                  subject,
                  item);
   }
} /* archive_discussion_item() */

/**
 * This is a special function to be used with the discuss items to
 * make sure that there is not another discussion item checking the
 * same name.
 * @param club_name the name of the club to check
 * @param position the position to check for
 * @return 1 if the position is being discussed as an item
 */
int is_discussion_position_valid(string club_name,
                                 string position) {
   class discussion_idea bing;

   position = lower_case(position);
   // Not already a position name.
   if (is_valid_position(club_name, position)) {
      return 0;
   }

   // Discussing it as a possible alternative name.
   do {
      bing = query_discussion_item_by_type(club_name,
                                           CLUB_DISCUSS_POSITION_NAME,
                                           bing);
      if (bing) {
         if (!undefinedp(bing->choices[position])) {
            return 0;
         }
      }
   } while (bing);

   // Discussing it as a new position type.
   do {
      bing = query_discussion_item_by_type(club_name,
                                           CLUB_DISCUSS_NEW_POSITION,
                                           bing);
      if (bing) {
         if (bing->information == position) {
            return 0;
         }
      }
   } while (bing);

   return 1;
} /* is_discussion_position_valid() */

private mixed club_discuss_position_name(int message,
                                         string club_name,
                                         class discussion_idea frog,
                                         string arg1,
                                         string arg2) {
   string body;
   string position;
   int num;
   string old_pos;

   switch (message) {
      case CLUB_DISCUSS_MESSAGE_VERIFY :
         /*
          * The current position must be in the list of choices.  Add
          * it if it is not..  Also make sure that none of the other
          * names are already positions in the club.
          */
         if (!is_discussion_position_valid(club_name, frog->optional_data)) {
            return 0;
         }

         frog->choices = ([ CLUB_DISCUSS_YES_CHOICE : 0,
                            CLUB_DISCUSS_NO_CHOICE : 0,
                            CLUB_DISCUSS_ABSTAIN_CHOICE : 0 ]);

         if (!is_valid_position(club_name, frog->name)) {
            return 0;
         }

         return 1;

      case CLUB_DISCUSS_MESSAGE_COMPLETE :
         /*
          * Ok!  Now we complete the position and tally up to find
          * which position is the best.
          */
         body = "Hello!\n\nThe discussion item " 
                "added at " + ctime(frog->time_added) + ", finished at " +
                ctime(time()) + " and added by " + frog->added_by +
                " has finished.";
         body += "  The final votes for the discussion item to change the " 
                "position " +frog->name + " to " + frog->optional_data +
                " is:\n";
         foreach (position, num in frog->choices) {
            body += position + ":   " + num + "\n";
         }
         body += "\n";
         if (frog->information) {
            body += frog->information + "\n";
         }

         // Need to keep track of the old name since the change postion
         // call will modify the name in the structure.
         old_pos = frog->name;

         if (frog->choices[CLUB_DISCUSS_YES_CHOICE] > 
             frog->choices[CLUB_DISCUSS_NO_CHOICE]) {
            change_position_name_in_club(club_name,
                                        frog->name,
                                        frog->optional_data);
            body += "Which means the position " + old_pos +
                     " has been changed to " + frog->optional_data + ".\n";
         } else {
            body += "Which means the position " + old_pos +
                    " has not been changed to " + frog->optional_data + ".\n";
         }
         do_mail_committee(club_name,
                           "Results of changing the position " + 
                              frog->name,
                           body);
         archive_discussion_item(club_name,
                                 send_discuss_message(club_name,
                                                 CLUB_DISCUSS_MESSAGE_SHORT_DESCRIPTION,
                                                 frog,
                                                 0,
                                                 0),
                                 body);
         return 1;

      case CLUB_DISCUSS_MESSAGE_LONG_DESCRIPTION :
         body = "Voting on changing the position '" + frog->name +
                "' to '" + frog->optional_data + "'.\n";
         if (frog->information) {
            body += frog->information;
         }
         return body;

      case CLUB_DISCUSS_MESSAGE_SHORT_DESCRIPTION :
         return "Changing the position '" + frog->name + "'";

      case CLUB_DISCUSS_MESSAGE_CHANGE_POSITION :
         if (frog->name == arg1) {
            frog->name = arg2;
            return 1;
         }
         return 0;

      case CLUB_DISCUSS_MESSAGE_REMOVE_POSITION :
         if (frog->name == arg1) {
            remove_discussion_item(club_name, frog);
            return 1;
         }
         return 0;
   }
   return 0;
} /* club_discuss_position_name() */

private mixed club_discuss_position_remove(int message,
                                           string club_name,
                                           class discussion_idea frog,
                                           string arg1,
                                           string arg2) {
   string body;
   string position;
   int num;

   switch (message) {
      case CLUB_DISCUSS_MESSAGE_VERIFY :
         /*
          * The current position must be in the list of choices.  Add
          * it if it is not..  Also make sure that none of the other
          * names are already positions in the club.
          */
         if (!is_valid_position(club_name, frog->name)) {
            return 0;
         }

         if (is_basic_position(club_name, frog->name)) {
            return 0;
         }

         frog->choices = ([ CLUB_DISCUSS_YES_CHOICE : 0,
                            CLUB_DISCUSS_NO_CHOICE : 0,
                            CLUB_DISCUSS_ABSTAIN_CHOICE : 0 ]);

         return 1;

      case CLUB_DISCUSS_MESSAGE_COMPLETE :
         /*
          * Ok!  Now we complete the position and tally up to find
          * which position is the best.
          */
         body = "Hello!\n\nThe discussion item " 
                "added at " + ctime(frog->time_added) + ", finished at " +
                ctime(time()) + " and added by " + frog->added_by +
                " has finished.";
         body += "  The final votes for the discussion item " 
                "to remove the position " + frog->name + " are:\n";
         foreach (position, num in frog->choices) {
            body += position + ":   " + num + "\n";
         }
         body += "\n";
         if (frog->information) {
            body += frog->information + "\n";
         }

         if (frog->choices[CLUB_DISCUSS_YES_CHOICE] > 
             frog->choices[CLUB_DISCUSS_NO_CHOICE]) {
            if (is_basic_position(club_name, frog->name)) {
               body += "Unable to remove the basic position " + frog->name +
                        ".\n";
            } else if (remove_position_in_club(club_name, frog->name)) {
               body += "Which means the position " + frog->name +
                        " has been removed.\n";
            } else {
               body += "Unable to remove the position " + frog->name +
                        " for some reason, basic position or something?\n";
            }
         } else {
            body += "Which means the position " + frog->name +
                    " has not been removed.\n";
         }
         do_mail_committee(club_name,
                           "Results of removing the position " + 
                              frog->name,
                           body);
         archive_discussion_item(club_name,
                                 send_discuss_message(club_name,
                                                 CLUB_DISCUSS_MESSAGE_SHORT_DESCRIPTION,
                                                 frog,
                                                 0,
                                                 0),
                                 body);
         return 1;

      case CLUB_DISCUSS_MESSAGE_LONG_DESCRIPTION :
         body = "Voting on removing the position '" + frog->name +
                "'.\n";
         if (frog->information) {
            body += frog->information;
         }
         return body;

      case CLUB_DISCUSS_MESSAGE_SHORT_DESCRIPTION :
         return "Removing the position '" + frog->name + "'";

      case CLUB_DISCUSS_MESSAGE_CHANGE_POSITION :
         if (frog->name == arg1) {
            frog->name = arg2;
            return 1;
         }
         return 0;

      case CLUB_DISCUSS_MESSAGE_REMOVE_POSITION :
         if (frog->name == arg1) {
            remove_discussion_item(club_name, frog);
            return 1;
         }
         return 0;
   }
   return 0;
} /* club_discuss_position_remove() */

private mixed club_discuss_new_position(int message,
                                        string club_name,
                                        class discussion_idea frog) {
   string body;

   switch (message) {
      case CLUB_DISCUSS_MESSAGE_VERIFY :
         /* Make sure they only have a yes and no choice. */
         frog->choices = ([ CLUB_DISCUSS_YES_CHOICE : 0,
                            CLUB_DISCUSS_NO_CHOICE : 0,
                            CLUB_DISCUSS_ABSTAIN_CHOICE : 0 ]);
         if (!is_discussion_position_valid(club_name, frog->name)) {
            return 0;
         }
         return 1;

      case CLUB_DISCUSS_MESSAGE_COMPLETE :
         body = "Hello!\n\nThe discussion item " 
                "added at " + ctime(frog->time_added) + ", finished at " +
                ctime(time()) + " and added by " + frog->added_by +
                " has finished.";
         body += "  The vote for adding the position " +
            frog->name + " to the club " + query_club_name(club_name) +
            " has been completed and the results are " +
            frog->choices[CLUB_DISCUSS_YES_CHOICE] + " in favour, " +
            frog->choices[CLUB_DISCUSS_NO_CHOICE] + " against and " +
            frog->choices[CLUB_DISCUSS_ABSTAIN_CHOICE] + " abstaining.\n";
         if (frog->information) {
            body += frog->information;
         }
         if (is_valid_position(club_name, frog->name)) {
            body += "\nUnfortunately " + frog->name +
               " is not a valid position.  Vote forfited.\n";
            do_mail_committee(club_name,
                              "Results of adding " + frog->name,
                              body);
            return 0;
         }
         if (frog->choices[CLUB_DISCUSS_YES_CHOICE] >
             frog->choices[CLUB_DISCUSS_NO_CHOICE]) {
            if (create_position_in_club(club_name, frog->name)) {
               body += "\nWhich means that the position " + frog->name +
                  " has been created.\n";
               setup_by_election(club_name,
                                 frog->name,
                                 frog->information);
            } else if (is_voting_in_progress(club_name)) {
               body += "\nWhich means we attempted to create the position " +
                  frog->name + " but were prevented because "
                  "voting is in progress?\n";
            } else {
               body += "\nWhich means we attempted to create the position " +
                  frog->name + " but were prevented for some reason.\n";
            }
         } else {
            body += "\nWhich means that the position " + frog->name +
               " was not created.\n";
         }
         do_mail_committee(club_name,
                           "Results of adding " + frog->name,
                           body);
         archive_discussion_item(club_name,
                                 send_discuss_message(club_name,
                                                 CLUB_DISCUSS_MESSAGE_SHORT_DESCRIPTION,
                                                 frog,
                                                 0,
                                                 0),
                                 body);
         return 1;

      case CLUB_DISCUSS_MESSAGE_LONG_DESCRIPTION :
         body = "Voting on adding the position '" + frog->name +
            "' to the club.\n";
         if (frog->information) {
            body += frog->information;
         }
         return body;

      case CLUB_DISCUSS_MESSAGE_SHORT_DESCRIPTION :
         return "Adding the position '" + frog->name + "'";
   }
   return 0;
} /* club_discuss_position_name() */

private mixed club_discuss_description(int message,
                                       string club_name,
                                       class discussion_idea frog) {
   string body;

   switch (message) {
      case CLUB_DISCUSS_MESSAGE_VERIFY :
         /* See if there is already one of these going... */
         if (query_discussion_item_by_type(club_name,
                                           CLUB_DISCUSS_DESCRIPTION,
                                           0)) {
            return 0;
         }

         /* Make sure they only have a yes and no choice. */
         frog->choices = ([ CLUB_DISCUSS_YES_CHOICE : 0,
                            CLUB_DISCUSS_NO_CHOICE : 0,
                            CLUB_DISCUSS_ABSTAIN_CHOICE : 0 ]);
         return 1;

      case CLUB_DISCUSS_MESSAGE_COMPLETE :
         body = "Hello!\n\nThe discussion item " 
                "added at " + ctime(frog->time_added) + ", finished at " +
                ctime(time()) + " and added by " + frog->added_by +
                " has finished.";
         body += "  The vote for changing the description of the " +
            "club " + query_club_name(club_name) +
            " to:\n" + frog->information + "\nThe vote has been completed "
            "and the results are " +
            frog->choices[CLUB_DISCUSS_YES_CHOICE] + " in favour, " +
            frog->choices[CLUB_DISCUSS_NO_CHOICE] + " against and " +
            frog->choices[CLUB_DISCUSS_ABSTAIN_CHOICE] + " abstaining.\n";

         if (frog->choices[CLUB_DISCUSS_YES_CHOICE] >
             frog->choices[CLUB_DISCUSS_NO_CHOICE]) {
            set_club_description(club_name, frog->information);
            body += "Which means the description has been changed.\n";
         } else {
            body += "Which means the description has not been changed.\n";
         }
         do_mail_committee(club_name,
                           "Results of changing the description",
                           body);
         archive_discussion_item(club_name,
                                 send_discuss_message(club_name,
                                                 CLUB_DISCUSS_MESSAGE_SHORT_DESCRIPTION,
                                                 frog,
                                                 0,
                                                 0),
                                 body);
         return 1;

      case CLUB_DISCUSS_MESSAGE_LONG_DESCRIPTION :
         body = "Voting on changing the description of the club to:\n" + 
                frog->information + "\n";
         return body;

      case CLUB_DISCUSS_MESSAGE_SHORT_DESCRIPTION :
         return "Changing the description";
   }
   return 0;
} /* club_discuss_description() */

private mixed club_discuss_secret(int message,
                                  string club_name,
                                  class discussion_idea frog) {
   string body;

   switch (message) {
      case CLUB_DISCUSS_MESSAGE_VERIFY :
         /* See if there is already one of these going... */
         if (query_discussion_item_by_type(club_name,
                                           CLUB_DISCUSS_SECRET_TYPE,
                                           0)) {
            return 0;
         }

         /* Make sure they only have a yes and no choice. */
         frog->choices = ([ CLUB_DISCUSS_YES_CHOICE : 0,
                            CLUB_DISCUSS_NO_CHOICE : 0,
                            CLUB_DISCUSS_ABSTAIN_CHOICE : 0 ]);
         return 1;

      case CLUB_DISCUSS_MESSAGE_COMPLETE :
         body = "Hello!\n\nThe discussion item " 
                "added at " + ctime(frog->time_added) + ", finished at " +
                ctime(time()) + " and added by " + frog->added_by +
                " has finished.";
         body += "  The vote for changing the club " +
                query_club_name(club_name) + " to ";
         if (query_club_secret(club_name)) {
            body += "an open club";
         } else {
            body += "a secret club";
         }
         body += " has been completed and the "
            "results are " +
            frog->choices[CLUB_DISCUSS_YES_CHOICE] + " in favour and " +
            frog->choices[CLUB_DISCUSS_NO_CHOICE] + " against with " +
            frog->choices[CLUB_DISCUSS_ABSTAIN_CHOICE] + " abstaining.\n\n";
         if (frog->choices[CLUB_DISCUSS_YES_CHOICE] >
             frog->choices[CLUB_DISCUSS_NO_CHOICE]) {
            if (query_club_secret(club_name)) {
               reset_club_secret(club_name);
               body += "Which means the club is now open.\n";
            } else {
               set_club_secret(club_name);
               body += "Which means the club is now secret.\n";
            }
         } else {
            body += "Which means the club's secret flag has not been "
                    "changed.\n";
         }
         if (frog->information) {
            body += "\n" + frog->information;
         }
         do_mail_committee(club_name,
                           "Results of changing the secret flag",
                           body);
         archive_discussion_item(club_name,
                                 send_discuss_message(club_name,
                                                 CLUB_DISCUSS_MESSAGE_SHORT_DESCRIPTION,
                                                 frog,
                                                 0,
                                                 0),
                                 body);
         return 1;

      case CLUB_DISCUSS_MESSAGE_LONG_DESCRIPTION :
         if (query_club_secret(club_name)) {
            body = "Voting on changing the club to be open.\n";
         } else {
            body = "Voting on changing the club to be secret.\n";
         }
         if (frog->information) {
            body += frog->information;
         }
         return body;

      case CLUB_DISCUSS_MESSAGE_SHORT_DESCRIPTION :
         if (query_club_secret(club_name)) {
            return "Changing the club to be open";
         } else {
            return "Changing the club to be secret";
         }
   }
   return 0;
} /* club_discuss_secret() */

private mixed club_discuss_memo(int message,
                                string club_name,
                                class discussion_idea frog) {
   string body;
   string choice;
   int num;

   switch (message) {
      case CLUB_DISCUSS_MESSAGE_VERIFY :
         /*
          * A memo can have any fields.  The verification is always
          * correct.
          */
         return 1;

      case CLUB_DISCUSS_MESSAGE_COMPLETE :
         /*
          * Ok!  Now we complete the position and tally up to find
          * which position is the best.
          */
         body = "Hello!\n\nThe discussion item " 
                "added at " + ctime(frog->time_added) + ", finished at " +
                ctime(time()) + " and added by " + frog->added_by +
                " has finished.";
         body += "   The final votes for discussion memo '" +
                frog->name + "' were:\n";
         foreach (choice, num in frog->choices) {
            body += choice + ":   " + num + "\n";
         }
         body += "\n" + frog->information;

         do_mail_committee(club_name,
                           "Results of memo '" +
                           frog->name + "'\n",
                           body);
         archive_discussion_item(club_name,
                                 send_discuss_message(club_name,
                                                 CLUB_DISCUSS_MESSAGE_SHORT_DESCRIPTION,
                                                 frog,
                                                 0,
                                                 0),
                                 body);
         return 1;

      case CLUB_DISCUSS_MESSAGE_LONG_DESCRIPTION :
         body = "Voting on the memo '" + frog->name +
                "'.\n";
         if (stringp(frog->information)) {
            body += "\n" + frog->information;
         }
         return body;

      case CLUB_DISCUSS_MESSAGE_SHORT_DESCRIPTION :
         return "Memo: " + frog->name;
   }
   return 0;
} /* club_discuss_memo() */

private mixed club_discuss_remove_member(int message,
                                         string club_name,
                                         class discussion_idea frog,
                                         string member) {
   string body;
   class discussion_idea womble;

   switch (message) {
      case CLUB_DISCUSS_MESSAGE_VERIFY :
         /* See if there is already one of these going... */
         frog->name = lower_case(frog->name);
         do {
            womble = query_discussion_item_by_type(club_name,
                                                   CLUB_DISCUSS_MEMBER_REMOVE,
                                                   womble);
            // Check to see if they are already being removed.
            if (womble &&
                womble->name == frog->name) {
               return 0;
            }
         } while (womble);

         if (!is_member_of(club_name, frog->name)) {
            return 0;
         }

         /* Make sure they only have a yes and no choice. */
         frog->choices = ([ CLUB_DISCUSS_YES_CHOICE : 0,
                            CLUB_DISCUSS_NO_CHOICE : 0,
                            CLUB_DISCUSS_ABSTAIN_CHOICE : 0 ]);
         return 1;

      case CLUB_DISCUSS_MESSAGE_COMPLETE :
         body = "Hello!\n\nThe discussion item " 
                "added at " + ctime(frog->time_added) + ", finished at " +
                ctime(time()) + " and added by " + frog->added_by +
                " has finished.";
         body += "  The vote for changing removing the member " +
                frog->name + " from the club " +
                query_club_name(club_name) + 
                " has been completed and the "
            "results are " +
            frog->choices[CLUB_DISCUSS_YES_CHOICE] + " in favour and " +
            frog->choices[CLUB_DISCUSS_NO_CHOICE] + " against with " +
            frog->choices[CLUB_DISCUSS_ABSTAIN_CHOICE] + " abstaining.\n\n";
         if (frog->information) {
            body += frog->information;
         }
         if (frog->choices[CLUB_DISCUSS_YES_CHOICE] >
             frog->choices[CLUB_DISCUSS_NO_CHOICE]) {
            if (!is_member_of(club_name, frog->name)) {
               body += "Looks like someone beat us to removing them.\n";
            } else {
               body += "Which means they have now been removed.\n";
               remove_member(club_name, frog->name);
            }
         } else {
            body += "Which means no one has been removed.\n";
         }
         do_mail_committee(club_name,
                           "Results of removing the member",
                           body);
         archive_discussion_item(club_name,
                                 send_discuss_message(club_name,
                                                 CLUB_DISCUSS_MESSAGE_SHORT_DESCRIPTION,
                                                 frog,
                                                 0,
                                                 0),
                                 body);
         return 1;

      case CLUB_DISCUSS_MESSAGE_LONG_DESCRIPTION :
         body = "Voting on removing the member " + frog->name + ".\n";
         if (frog->information) {
            body += frog->information;
         }
         return body;

      case CLUB_DISCUSS_MESSAGE_SHORT_DESCRIPTION :
         return "Removing the member " + frog->name;

      case CLUB_DISCUSS_MESSAGE_REMOVE_MEMBER :
         if (frog->name == member) {
            // Remove this discussion item!
            return remove_discussion_item(club_name, frog);
         }
         return 0;
   }
   return 0;
} /* club_discuss_remove_member() */

private mixed club_discuss_no_confidence(int message,
                                         string club_name,
                                         class discussion_idea frog,
                                         string arg1,
                                         string arg2) {
   string body;
   class discussion_idea womble;
   string real;
   string pos;

   if (!frog->name) {
      real = "all postions";
   } else {
      real = frog->name;
   }

   switch (message) {
      case CLUB_DISCUSS_MESSAGE_VERIFY :
         /* See if there is already one of these going... */
         frog->name = lower_case(frog->name);
         do {
            womble = query_discussion_item_by_type(club_name,
                                                   CLUB_DISCUSS_NO_CONFIDENCE,
                                                   womble);
            // Check to see if they are already being removed.
            if (womble &&
                womble->name == frog->name) {
               return 0;
            }
         } while (womble);

         if (!is_valid_position(club_name, frog->name) &&
             frog->name) {
            return 0;
         }

         /* Make sure they only have a yes and no choice. */
         frog->choices = ([ CLUB_DISCUSS_YES_CHOICE : 0,
                            CLUB_DISCUSS_NO_CHOICE : 0,
                            CLUB_DISCUSS_ABSTAIN_CHOICE : 0 ]);
         return 1;

      case CLUB_DISCUSS_MESSAGE_COMPLETE :
         body = "Hello!\n\nThe discussion item " 
                "added at " + ctime(frog->time_added) + ", finished at " +
                ctime(time()) + " and added by " + frog->added_by +
                " has finished.";
         body += "   The vote for no confidence in " +
                real + " in the club " +
                query_club_name(club_name) + 
                " has been completed and the "
            "results are " +
            frog->choices[CLUB_DISCUSS_YES_CHOICE] + " in favour and " +
            frog->choices[CLUB_DISCUSS_NO_CHOICE] + " against with " +
            frog->choices[CLUB_DISCUSS_ABSTAIN_CHOICE] + " abstaining.\n\n";
         if (frog->choices[CLUB_DISCUSS_YES_CHOICE] >
             frog->choices[CLUB_DISCUSS_NO_CHOICE]) {
            if (!frog->name) {
               body += "Therefor we have removed everyone from the committee "
                  "and started a new election.\n";
               foreach (pos in query_valid_positions(club_name)) {
                  catch(set_position_holder(club_name, pos, CLUB_UNKNOWN_MEMBER));
               }
               start_election(club_name);
            } else if (is_valid_position(club_name,
                                  frog->name)) {
               set_position_holder(club_name, frog->name, CLUB_UNKNOWN_MEMBER);
               body += "Therefor we had set the position as vacant.\n";
            } else {
               body += "The position in the club appears to have vanished!\n";
            }
         } else {
            body += "Which means nothing has happened.\n";
         }

         if (frog->information) {
            body += frog->information;
         }

         do_mail_committee(club_name,
                           "Results of no confidence vote",
                           body);
         archive_discussion_item(club_name,
                                 send_discuss_message(club_name,
                                                 CLUB_DISCUSS_MESSAGE_SHORT_DESCRIPTION,
                                                 frog,
                                                 0,
                                                 0),
                                 body);
         return 1;

      case CLUB_DISCUSS_MESSAGE_LONG_DESCRIPTION :
         body = "Voting on confidence in the position " +
                real + ", a yes vote indicates that you are in favour of the "
                "no confidence vote.\n";
         if (frog->information) {
            body += frog->information;
         }
         return body;

      case CLUB_DISCUSS_MESSAGE_SHORT_DESCRIPTION :
         return "No confidence in " + real;

      case CLUB_DISCUSS_MESSAGE_REMOVE_MEMBER :
         if (holds_position_of(club_name,
                               frog->name,
                               arg1) ||
             holds_position_of(club_name,
                               frog->name,
                               CLUB_UNKNOWN_MEMBER)) {
            return remove_discussion_item(club_name, frog);
         }
         return 0;

      case CLUB_DISCUSS_MESSAGE_CHANGE_POSITION :
         if (frog->name == arg1) {
            frog->name = arg2;
            return 1;
         }
         return 0;

      case CLUB_DISCUSS_MESSAGE_REMOVE_POSITION :
         if (frog->name == arg1) {
            remove_discussion_item(club_name, frog);
            return 1;
         }
         return 0;
   }
   return 0;
} /* club_discuss_no_confidence() */

private int is_nomination_or_election_being_discussed(
   string club_name,
   string pos_name
   )
{
   class discussion_idea womble;

   womble = 0;
   do {
      womble = query_discussion_item_by_type(club_name,
                                             CLUB_DISCUSS_ELECTION,
                                             womble);
      // Check to see if they are already being elected.
      if (womble &&
          lower_case(womble->name) == lower_case(pos_name)) {
         return 1;
      }
   } while (womble);

   womble = 0;
   do {
      womble = query_discussion_item_by_type(club_name,
                                             CLUB_DISCUSS_NOMINATION,
                                             womble);
      // Check to see if they are already being nominated.
      if (womble &&
          lower_case(womble->name) == lower_case(pos_name)) {
         return 1;
      }
   } while (womble);

   return 0;
} /* is_nomination_or_election_discussed() */

private mixed club_discuss_nomination(int message,
                                      string club_name,
                                      class discussion_idea frog,
                                      string arg1,
                                      string arg2) {
   string body;
   string name;
   string *nom;
   string *nominated;
   int ret;

   switch (message) {
      case CLUB_DISCUSS_MESSAGE_VERIFY :
         //
         // Make the name correct.
         //
         frog->name = query_position_name(club_name, frog->name);

         /* See if there is already one of these going... */
         if (is_nomination_or_election_being_discussed(club_name, frog->name)) {
            return 0;
         }

         if (!is_valid_position(club_name, frog->name)) {
            return 0;
         }

         if (is_election_in_progress(club_name) ||
             is_nomination_in_progress(club_name)) {
            return 0;
         }

         /* Setup the nomination mapping. */
         frog->choices = ([ ]);
         return 1;

      case CLUB_DISCUSS_MESSAGE_COMPLETE :
         body = "Hello!\n\nThe discussion item " 
                "added at " + ctime(frog->time_added) + ", finished at " +
                ctime(time()) + " and added by " + frog->added_by +
                " has finished.";
         body += "  The vote for nominations for the position of " +
                frog->name + " in the club " +
                query_club_name(club_name) + 
                " has been completed and the "
            "results are:\n";
         nominated = ({ });
         foreach (name, nom in frog->choices) {
            body += name + ": " + query_multiple_short(nom);
            if (member_array(name, nom) != -1 &&
                sizeof(nom) >= 2) {
               body += " (accepted)\n";
               nominated += ({ name });
            } else {
               body += "\n";
            }
         }
         if (frog->information) {
            body += frog->information;
         }
         if (sizeof(nominated)) {
            if (is_valid_position(club_name,
                                  frog->name)) {
               if (sizeof(nominated) != 1) {
                  body += "Therefor we had added an election for " + 
                     query_multiple_short(nominated) +
                     " .\n";
                  //
                  // Do the addition in a call out, so we are removed first.
                  //
                  call_out((: add_discussion_item :), 0,
                                      club_name,
                                      CLUB_DISCUSS_ELECTION |
                                         CLUB_DISCUSS_OPEN |
                                         CLUB_DISCUSS_NO_QUORUM,
                                      CLUB_CONTROLLER_MEMBER,
                                      frog->name,
                                      frog->information,
                                      nominated,
                                      7 * (24 * 60 * 60),
                                      0);
               } else {
                  body += "Only " + nominated[0] +
                     " was nominated, so they are elected immediately.\n";
                  set_position_holder(club_name, frog->name, nominated[0]);
               }
            } else {
               body += "The position in the club appears to have vanished!\n";
            }
         } else {
            if (is_valid_position(club_name, frog->name)) {
               body += "No one accepted their nomination, so nothing "
                       "happened.\n";
               //
               // Do the addition in a call out, so we are removed first.
               //
               call_out((: add_discussion_item :), 0,
                                   club_name,
                                   CLUB_DISCUSS_NOMINATION |
                                      CLUB_DISCUSS_OPEN |
                                      CLUB_DISCUSS_NO_QUORUM,
                                   frog->added_by,
                                   frog->name,
                                   frog->information,
                                   ({ }),
                                   7 * (24 * 60 * 60),
                                   frog->optional_data);
            } else {
               body += "The position in the club appears to have vanished!\n";
            }
         }
         do_mail_committee(club_name,
                           "Results of nomination",
                           body);
         archive_discussion_item(club_name,
                                 send_discuss_message(club_name,
                                                 CLUB_DISCUSS_MESSAGE_SHORT_DESCRIPTION,
                                                 frog,
                                                 0,
                                                 0),
                                 body);
         return 1;

      case CLUB_DISCUSS_MESSAGE_LONG_DESCRIPTION :
         body = "Nominations for the position " + frog->name + ":\n";
         foreach (name, nom in frog->choices) {
            body += name + ": " + query_multiple_short(nom);
            if (member_array(name, nom) != -1 &&
                sizeof(nom) >= 2) {
               body += " (accepted)\n";
            } else {
               body += "\n";
            }
         }
         if (frog->information) {
            body += frog->information;
         }
         return body;

      case CLUB_DISCUSS_MESSAGE_SHORT_DESCRIPTION :
         return "Nominations for " + frog->name;

      case CLUB_DISCUSS_MESSAGE_NOMINATION :
         if (is_member_of(club_name, arg1) &&
             is_member_of(club_name, arg2)) {
            // Pass in the person nominated in the optional data.
            if (!frog->choices[arg2]) {
               frog->choices[arg2] = ({ arg1 });
               return 1;
            } else if (member_array(arg1, 
                                    frog->choices[arg2]) == -1) {
               frog->choices[arg2] += ({ arg1 });
               return 1;
            }
         }
         return 0;

      case CLUB_DISCUSS_MESSAGE_WITHDRAW :
         if (frog->choices[arg1]) {
            map_delete(frog->choices, arg1);
            return 1;
         }
         return 0;

      case CLUB_DISCUSS_MESSAGE_REMOVE_MEMBER :
         // Check out to see if they have been nominated or nominated someone.
         if (frog->choices[arg1]) {
            map_delete(frog->choices, arg1);
            ret = 1;
         }
         foreach (name, nom in frog->choices) {
            if (member_array(arg1, nom) != -1) {
               frog->choices[name] = nom - ({ arg1 });
               if (!sizeof(frog->choices[name])) {
                  map_delete(frog->choices, name);
               }
               ret = 1;
            }
         }
         return ret;

      case CLUB_DISCUSS_MESSAGE_CHANGE_POSITION :
         if (frog->name == arg1) {
            frog->name = arg2;
            return 1;
         }
         return 0;

      case CLUB_DISCUSS_MESSAGE_TYPE :
         return CLUB_DISCUSS_MESSAGE_TYPE_NOMINATE;

      case CLUB_DISCUSS_MESSAGE_NOMINATION_QUERY :
         return frog->choices;

      case CLUB_DISCUSS_MESSAGE_REMOVE_POSITION :
         if (frog->name == arg1) {
            remove_discussion_item(club_name, frog);
            return 1;
         }
         return 0;
   }
   return 0;
} /* club_discuss_nomination() */

private mixed club_discuss_election(int message,
                                    string club_name,
                                    class discussion_idea frog,
                                    string arg1,
                                    string arg2) {
   string body;
   string name;
   int num;
   int highest;
   string *voted;

   switch (message) {
      case CLUB_DISCUSS_MESSAGE_VERIFY :
         //
         // Make the name correct.
         //
         frog->name = query_position_name(club_name, frog->name);

         /* See if there is already one of these going... */
         if (is_nomination_or_election_being_discussed(club_name, frog->name)) {
            return 0;
         }

         if (!is_valid_position(club_name, frog->name)) {
            return 0;
         }

         if (is_election_in_progress(club_name) ||
             is_nomination_in_progress(club_name)) {
            return 0;
         }

         /* Make sure they only voting for people in the club. */
         foreach (name, num in frog->choices) {
            frog->choices[name] = 0;
            if (!is_member_of(club_name, name)) {
               map_delete(frog->choices, name);
            }
         }

         if (!sizeof(frog->choices)) {
            return 0;
         }
         return 1;

      case CLUB_DISCUSS_MESSAGE_COMPLETE :
         body = "Hello!\n\nThe discussion item " 
                "added at " + ctime(frog->time_added) + ", finished at " +
                ctime(time()) + " and added by " + frog->added_by +
                " has finished.";
         body += "  The vote the position of " +
                frog->name + " in the club " +
                query_club_name(club_name) + 
                " has been completed and the "
            "results are:\n";
         highest = 0;
         voted = ({ });
         foreach (name, num in frog->choices) {
            body += name + ": " + num + "\n";
            if (num > highest) {
               highest = num;
               voted = ({ name });
            } else if (highest == num) {
               voted += ({ name });
            }
         }
         if (frog->information) {
            body += frog->information;
         }
         if (sizeof(voted)) {
            if (is_valid_position(club_name,
                                  frog->name)) {
               if (sizeof(voted) == 1) {
                  body += "Therefor " + voted[0] + 
                     " was elected to the position of " + frog->name +
                     ".\n";
                  set_position_holder(club_name, frog->name, voted[0]);
               } else {
                  body += "More than one person tied for the position, so "
                     "the election has been added again.\n";
               }
            } else {
               body += "The position in the club appears to have vanished!\n";
            }
         } else {
            body += "No one voted for anyone, so nothing happened.\n";
         }
         do_mail_committee(club_name,
                           "Results of election",
                           body);
         archive_discussion_item(club_name,
                                 send_discuss_message(club_name,
                                                 CLUB_DISCUSS_MESSAGE_SHORT_DESCRIPTION,
                                                 frog,
                                                 0,
                                                 0),
                                 body);
         return 1;

      case CLUB_DISCUSS_MESSAGE_LONG_DESCRIPTION :
         body = "Election for the position of " + frog->name + ".\n";
         if (frog->information) {
            body += frog->information;
         }
         return body;

      case CLUB_DISCUSS_MESSAGE_SHORT_DESCRIPTION :
         return "Election for " + frog->name;

      case CLUB_DISCUSS_MESSAGE_REMOVE_MEMBER :
         if (!undefinedp(frog->choices[arg1])) {
            map_delete(frog->choices, arg1);
            return 1;
         }
         return 0;

      case CLUB_DISCUSS_MESSAGE_CHANGE_POSITION :
         if (frog->name == arg1) {
            frog->name = arg2;
            return 1;
         }
         return 0;

      case CLUB_DISCUSS_MESSAGE_REMOVE_POSITION :
         if (frog->name == arg1) {
            remove_discussion_item(club_name, frog);
            return 1;
         }
         return 0;
   }
   return 0;
} /* club_discuss_election() */

private mixed club_discuss_function(int message,
                                    string club_name,
                                    class discussion_idea frog,
                                    string arg1,
                                    string arg2) {
   mixed ret;

   ret = call_other(frog->name[CLUB_DISCUSS_FUNCTION_OBJECT],
                    frog->name[CLUB_DISCUSS_FUNCTION_FUNCTION],
                    message,
                    club_name,
                    frog,
                    arg1,
                    arg2);
   if (message == CLUB_DISCUSS_MESSAGE_COMPLETE &&
       stringp(ret)) {
      do_mail_committee(club_name,
                      send_discuss_message(club_name,
                                           CLUB_DISCUSS_MESSAGE_SHORT_DESCRIPTION,
                                           frog,
                                           arg1,
                                           arg2),
                      ret);
      archive_discussion_item(club_name,
                              send_discuss_message(club_name,
                                                 CLUB_DISCUSS_MESSAGE_SHORT_DESCRIPTION,
                                                 frog,
                                                 0,
                                                 0),
                              ret);
      return 1;
   }

   return ret;
} /* club_discuss_function() */

private mixed club_discuss_create_account(int message,
                                    string club_name,
                                    class discussion_idea frog,
                                    string arg1,
                                    string arg2) {
   string body;
   class discussion_idea womble;

   switch (message) {
      case CLUB_DISCUSS_MESSAGE_VERIFY :
         /* See if there is already one of these going... */
         do {
            womble = query_discussion_item_by_type(club_name,
                                                   CLUB_DISCUSS_CREATE_ACCOUNT,
                                                   womble);
            // Check to see if the account is already being added.
            if (womble &&
                womble->name == frog->name) {
               return 0;
            }
         } while (womble);

         frog->choices = ([ CLUB_DISCUSS_YES_CHOICE : 0,
                            CLUB_DISCUSS_NO_CHOICE : 0,
                            CLUB_DISCUSS_ABSTAIN_CHOICE : 0 ]);

         if (is_account_of(club_name, frog->name)) {
            return 0;
         }

         return 1;

      case CLUB_DISCUSS_MESSAGE_COMPLETE :
         body = "Hello!\n\nThe discussion item " 
                "added at " + ctime(frog->time_added) + ", finished at " +
                ctime(time()) + " and added by " + frog->added_by +
                " has finished.";
         body += "  The vote for adding the special account " +
                frog->name + " in the club " +
                query_club_name(club_name) + 
                " has been completed and the "
                "results are " +
                frog->choices[CLUB_DISCUSS_YES_CHOICE] + " in favour, " +
                frog->choices[CLUB_DISCUSS_NO_CHOICE] + " against and " +
                frog->choices[CLUB_DISCUSS_ABSTAIN_CHOICE] + " abstaining.\n";

         if (frog->choices[CLUB_DISCUSS_YES_CHOICE] >
             frog->choices[CLUB_DISCUSS_NO_CHOICE]) {
            if (create_account(club_name, frog->name)) {
                body += "Which means the special account " + frog->name +
                     " has been created.\n";
            } else {
                body += "Which means the special account " + frog->name +
                     " was attempted to be created but had some problems.\n";
            }
         } else {
            body += "Which means the special account " + frog->name +
                  " has not been created.\n";
         }

         if (frog->information) {
            body += frog->information;
         }
         do_mail_committee(club_name,
                           "Results of creating account",
                           body);
         archive_discussion_item(club_name,
                                 send_discuss_message(club_name,
                                                 CLUB_DISCUSS_MESSAGE_SHORT_DESCRIPTION,
                                                 frog,
                                                 0,
                                                 0),
                                 body);
         return 1;

      case CLUB_DISCUSS_MESSAGE_LONG_DESCRIPTION :
         body = "Creating the special account " + frog->name + ".\n";
         if (frog->information) {
            body += frog->information;
         }
         return body;

      case CLUB_DISCUSS_MESSAGE_SHORT_DESCRIPTION :
         return "Create special account " + frog->name;
   }
   return 0;
} /* club_discuss_election() */

/**
 * This method figures out the discussion item for the club with the
 * given id.
 * @param club_name the name of the club
 * @param id the id of the discussion item
 * @return the found discussion item
 * @see add_discussion_item()
 */
class discussion_idea query_discussion_item(string club_name,
                                            int id) {
   class election_info frog;
   class discussion_idea bing;

   frog = (class election_info)query_elected_info(club_name);
   if (frog) {
      foreach (bing in frog->discussion) {
         if (bing->id == id) {
            return bing;
         }
      }
   }
   return 0;
} /* query_discussion_item() */

/**
 * This method returns all the current discussion items for this
 * club.
 * @param club_name the name of the club to query the discussion items for
 * @return the list of current discussion items
 */
class discussion_idea* query_all_discussion_items(string club_name) {
   class election_info frog;

   frog = (class election_info)query_elected_info(club_name);
   if (frog) {
      return copy(frog->discussion);
   }
   return 0;
} /* query_all_discussion_items() */

/**
 * This method returns a nice little description of the discussion item.
 * This is a very short description usable in lists and stuff.
 * @param club_name the name of the club
 * @param id the id of the discussion item
 * @return a short description of the item
 */
string query_discussion_item_short_description(string club_name,
                                               int id) {
   class discussion_idea bing;

   bing = query_discussion_item(club_name, id);
   if (bing) {
      if (_discussion_items[bing->discuss_type & CLUB_DISCUSS_TYPE_MASK]) {
         return send_discuss_message(club_name,
                                     CLUB_DISCUSS_MESSAGE_SHORT_DESCRIPTION,
                                     bing,
                                     0,
                                     0);
      }
   }
   return 0;
} /* query_discuss_item_short_description() */

/**
 * This method returns a nice little description of the discussion item.
 * This is a longer description, useful in more places.
 * @param club_name the name of the club
 * @param id the id of the discussion item
 * @return a long description of the item
 */
string query_discussion_item_long_description(string club_name,
                                            int id) {
   class discussion_idea bing;

   bing = query_discussion_item(club_name, id);
   if (bing) {
      if (_discussion_items[bing->discuss_type & CLUB_DISCUSS_TYPE_MASK]) {
         return send_discuss_message(club_name,
                                     CLUB_DISCUSS_MESSAGE_LONG_DESCRIPTION,
                                     bing,
                                     0,
                                     0);
      }
   }
   return 0;
} /* query_discuss_item_long_description() */

/**
 * This method checks to make sure the type of the discussion item
 * is valid.
 * @param type the type of the discussion item
 * @return 1 if it is valid, 0 if not
 */
int is_valid_discussion_item_type(int type) {
   if (_discussion_items[type & CLUB_DISCUSS_TYPE_MASK]) {
      return 1;
   }
   return 0;
} /* is_valid_duscussion_item_type() */

/**
 * This method will add a discussion item to the table to be voted on.
 * @param club the club the item is being added to
 * @param type the type of the discussion item to be added
 * @param added_by who added the discussion item
 * @param name the name of the discussion item
 * @param choices the choices for the discussion item
 * @param time_to_finish the amount of time the election has to run
 * @param extra_data any optional data associated with the discussion idea
 * @return 1 if successfully added, 0 if not
 */
int add_discussion_item(string club,
                        int type,
                        string added_by,
                        string name,
                        string info,
                        string *choices,
                        int time_to_finish,
                        mixed extra_data) {
   class discussion_idea bing;
   class election_info frog;
   int max_id;
   string choice;
   int i;

   // Allow the item to be added by the club contoller or the club itself.
   if (is_elected_club(club) &&
       is_valid_discussion_item_type(type) &&
       time_to_finish > 0 &&
       (is_member_of(club, lower_case(added_by)) ||
        added_by == CLUB_CONTROLLER_MEMBER ||
        normalise_name(added_by) == normalise_name(club))) {
      /* Cool, then we can add this item. */
      frog = (class election_info)query_elected_info(club);
      if (!pointerp(frog->discussion)) {
         frog->discussion = ({ });
      }
      bing = new(class discussion_idea);
      max_id = 0;
      for (i = 0; i < sizeof(frog->discussion); i++) {
         if (frog->discussion[i]->id > max_id) {
            max_id = frog->discussion[i]->id;
         }
      }
      bing->id = max_id + 1;
      bing->time_added = time();
      bing->time_finish = time() + time_to_finish;
      bing->discuss_type = type;
      bing->added_by = added_by;
      bing->name = name;
      bing->information = info;
      bing->choices = ([ ]);
      foreach (choice in choices) {
         bing->choices[lower_case(choice)] = 0;
      }
      bing->voted = ({ });
      bing->optional_data = extra_data;
      /* Verify the data... */
      if (send_discuss_message(club,
                               CLUB_DISCUSS_MESSAGE_VERIFY,
                               bing,
                               0,
                               0)) {
         frog->discussion += ({ bing });
         set_club_changed(club);
         return 1;
      }
      return 0;
   }
   return 0;
} /* add_discussion_item() */

/**
 * This method figures out the discussion item for the club with the
 * given type.  It will also continue on a search from a last found item.
 * @param club_name the name of the club
 * @param type the type of the discussion item to find
 * @return the found discussion item
 * @see add_discussion_item()
 */
class discussion_idea query_discussion_item_by_type(string club_name,
                                                    int type,
                                                    class discussion_idea idea) {
   class election_info frog;
   class discussion_idea bing;
   int found;

   frog = (class election_info)query_elected_info(club_name);
   if (frog) {
      if (!idea) {
         found = 1;
      }
      foreach (bing in frog->discussion) {
         if (found) {
            if ((bing->discuss_type & CLUB_DISCUSS_TYPE_MASK) == type) {
               return bing;
            }
         } else if (bing == idea) {
            found = 1;
         }
      }
   }
   return 0;
} /* query_discussion_item_by_type() */

/**
 * This method returns all the choices for this discussion item.
 * @param club_name the name of the club
 * @param id the id of the discussion item
 * @return an array of the valid set of choices, empty array on failure
 */
string *query_discussion_choices(string club_name,
                             int id) {
   class discussion_idea frog;

   frog = query_discussion_item(club_name, id);
   if (frog) {
      return keys(frog->choices);
   }
   return ({ });
} /* is_valid_discussion_choice() */

/**
 * This method returns the person who added the discussion item.
 * @param club_name the name of the club
 * @param id the id of the discussion item
 * @return the name of the person who added the discussion item
 */
string query_discussion_added_by(string club_name,
                                 int id) {
   class discussion_idea frog;

   frog = query_discussion_item(club_name, id);
   if (frog &&
       frog->added_by) {
      return frog->added_by;
   }
   return CLUB_UNKNOWN_MEMBER;
} /* query_discussion_added_by() */

/**
 * This method returns the timeout time of the current discussion item.
 * @param club_name the name of the club
 * @param id the id of the discussion item
 * @return the time at which the dicussion item will finish
 */
int query_discussion_time_finish(string club_name,
                                 int id) {
   class discussion_idea frog;

   frog = query_discussion_item(club_name, id);
   if (frog) {
      return frog->time_finish;
   }
   return 0;
} /* query_discussion_time_finish() */

/**
 * This method returns the timeout time of the current discussion item.
 * @param club_name the name of the club
 * @param id the id of the discussion item
 * @return the time at which the dicussion item will finish
 */
int query_discussion_time_added(string club_name,
                                 int id) {
   class discussion_idea frog;

   frog = query_discussion_item(club_name, id);
   if (frog) {
      return frog->time_finish;
   }
   return 0;
} /* query_discussion_time_added() */

/**
 * This method returns the optional data of the discussion item.
 * @param club_name the name of the club
 * @param id the id of the discussion item
 * @return the optional data in the club
 */
mixed query_discussion_optional_data(string club_name,
                                     int id) {
   class discussion_idea frog;

   frog = query_discussion_item(club_name, id);
   if (frog) {
      return frog->optional_data;
   }
   return 0;
} /* query_discussion_optional_data() */

/**
 * This method returns the nomination mapping for the discussion item
 * if it exists.  The nomination mapping is of the format:<br>
 * <pre>
 * ([
 *    name : ({ nomated_by, nominated_by, ... })
 *    ..
 *  ])
 * </pre>
 * @param club_name the name of the club
 * @param id the id of the discussion item
 * @return the mapping as described above
 */
mapping query_discussion_nomination(string club_name,
                                    int id) {
   class discussion_idea frog;
   mapping stuff;

   frog = query_discussion_item(club_name, id);
   if (frog) {
      stuff = send_discuss_message(club_name,
                                   CLUB_DISCUSS_MESSAGE_NOMINATION_QUERY,
                                   frog,
                                   0,
                                   0);
      if (stuff) {
         return stuff;
      }
      return ([ ]);
   }
   return ([ ]);
} /* query_discussion_nomination() */

/**
 * This method checks to see if the given nomination has already been 
 * done.
 * @param club_name the name of the club
 * @param id the id of the discussion ite,
 * @param nominator the person doing the nomination
 * @param nominated the person being nominated
 * @return 1 if they are already nominated, 0 if not
 */
int is_discuss_person_nominated(string club_name,
                               int id,
                               string nominator,
                               string nominated) {
   mapping bing;

   bing = query_discussion_nomination(club_name, id);
   if (bing[nominated]) {
      if (member_array(nominator, bing[nominated]) != -1) {
         return 1;
      }
   }
   return 0;
} /* is_discuss_person_nominated() */

/**
 * This method checks to see if the discussion item is a committee only
 * item.
 * @param club_name the name of the club
 * @param id the id of the discussion item
 * @return 1 if it is a committee only item, 0 if it is open
 */
int is_committee_discussion_item(string club_name,
                                 int id) {
   class discussion_idea frog;

   frog = query_discussion_item(club_name, id);
   if (frog) {
       if (frog->discuss_type & CLUB_DISCUSS_OPEN) {
          return 0;
       }
       return 1;
   }
   return 0;
} /* is_committee_discussion_item() */

/**
 * This method checks to see if the discussion item has no quorum
 * associated with it.
 * @param club_name the name of the club
 * @param id the id of the discussion item
 * @return 1 if it has no quorum, 0 if it is does
 */
int is_no_quorum_discussion_item(string club_name,
                                 int id) {
   class discussion_idea frog;

   frog = query_discussion_item(club_name, id);
   if (frog) {
       if (frog->discuss_type & CLUB_DISCUSS_NO_QUORUM) {
          return 1;
       }
       return 0;
   }
   return 0;
} /* is_no_quorum_discussion_item() */

/**
 * This method checks to see if the discussion item is completed yet.
 * @param club_name the name of the club
 * @param id the id of the discussion item
 * @return 1 if the discussion item is finished
 * @see vote_for_discussion_item()
 */
int is_discussion_item_finished(string club_name,
                                int id) {
   class discussion_idea frog;
   string *committee;

   frog = query_discussion_item(club_name, id);
   if (frog) {
      /*
       * If this is a committee only item, then if all the committee have
       * voted it is finished.
       */
      if (is_committee_discussion_item(club_name, id)) {
         // Check to see if everyone has voted.
         committee = query_committee(club_name);
         if (committee &&
             !sizeof(committee - frog->voted)) {
            return 1;
         }
      }

      // See if it has run to its completion time.
      if (frog->time_finish < time()) {
         return 1;
      }
   }
   return 0;
} /* is_discussion_item_finished() */

/**
 * This method returns the number of people needed for quorum
 * in this discussion item.
 * @param club_name the name of the club to check for quorum
 * @param id the discussion item id
 * @return the number of people needed for quorum
 */
int query_discussion_item_quorum_number(string club_name,
                                        int id) {
   class discussion_idea bing;
   int num;

   bing = query_discussion_item(club_name, id);
   // No need for a quorum on this item.
   if (is_no_quorum_discussion_item(club_name, id)) {
      return 0;
   } else if (is_committee_discussion_item(club_name, id)) {
      /* Quorum is 75% of the (active) committee... */
      num = sizeof(filter(query_committee(club_name),
                          (: $1 != CLUB_UNKNOWN_MEMBER &&
                             PLAYER_HANDLER->test_active($1) :)));
      return (num * CLUB_DISCUSS_QUORUM_COMMITTEE / 100);
   } else {
      /* Only require 50% of the (active) general assembly to vote. */
      num = sizeof(filter(query_members(club_name),
                          (: $1 != CLUB_UNKNOWN_MEMBER &&
                             PLAYER_HANDLER->test_active($1, 1) :)));
      return (num * CLUB_DISCUSS_QUORUM_OPEN / 100);
   }
   return 0;
} /* query_discussion_item_quorum_number() */

/**
 * This method returns the number of people who have voted for the
 * discussion item.
 * @param club_name the name of the club to check for quorum
 * @param id the discussion item id
 * @return the number of people who have voted
 */
int query_discussion_item_number_voted(string club_name,
                                       int id) {
   class discussion_idea bing;

   bing = query_discussion_item(club_name, id);
   if (bing) {
      return sizeof(bing->voted);
   }
   return 0;
} /* query_discussion_item_quorum_number() */

/**
 * This method checks to see if quorum has been reached or not
 * for the club.
 * @param club_name the name of the club to check for quorum
 * @param id the discussion item id
 * @return 1 if quorum is reached, 0 if not
 */
int is_discussion_item_quorum(string club_name,
                              int id) {
   class discussion_idea bing;
   int num;

   bing = query_discussion_item(club_name, id);
   if (bing) {
      num = query_discussion_item_quorum_number(club_name, id);
      if (sizeof(bing->voted) >= num) {
         return 1;
      }
   }
   return 0;
} /* is_discussion_item_quorum() */

/**
 * This checks to see if the specified choice is a real discussion item
 * choice.
 * @param club_name the name of the club
 * @param id the id of the discussion item
 * @param choice the choice to check
 */
int is_valid_discussion_choice(string club_name,
                               int id,
                               string choice) {
   class discussion_idea frog;

   frog = query_discussion_item(club_name, id);
   choice = lower_case(choice);
   if (frog &&
       !undefinedp(frog->choices[choice])) {
      return 1;
   }
   return 0;
} /* is_valid_discussion_choice() */

/**
 * This method checks to see if the discussion item is a votable
 * item or not.
 * @param club_name the name of the club
 * @param id the id of the discussion item
 * @return 1 if it is votable, 0 if not
 */
int is_discuss_votable(string club_name,
                       int id) {
   class discussion_idea frog;

   frog = query_discussion_item(club_name, id);
   if (frog) {
      if (send_discuss_message(club_name,
                               CLUB_DISCUSS_MESSAGE_TYPE,
                               frog,
                               0,
                               0) == CLUB_DISCUSS_MESSAGE_TYPE_VOTE) {
         return 1;
      }
   }
   return 0;
} /* is_discuss_votable() */

/**
 * This method checks to see if the discussion item is a votable
 * item or not.
 * @param club_name the name of the club
 * @param id the id of the discussion item
 * @return 1 if it is votable, 0 if not
 */
int is_discuss_nominateable(string club_name,
                            int id) {
   class discussion_idea frog;

   frog = query_discussion_item(club_name, id);
   if (frog) {
      if (send_discuss_message(club_name,
                               CLUB_DISCUSS_MESSAGE_TYPE,
                               frog,
                               0,
                               0) == CLUB_DISCUSS_MESSAGE_TYPE_NOMINATE) {
         return 1;
      }
   }
   return 0;
} /* is_discuss_nominateable() */

/**
 * This method checks to see if the specified person can see the
 * discussion idea. 
 * @param club_name the name of the club
 * @param id the id of the discussion idea
 * @param person the name of the person
 * @see vote_for_discussion_item()
 */
int can_reference_discussion_item(string club_name,
                                  int id,
                                  string person) {
   class discussion_idea frog;

   frog = query_discussion_item(club_name, id);
   if (frog && 
       (!is_committee_discussion_item(club_name, id) ||
        holds_any_position_of(club_name, person))) {
      return 1;
   }
   return 0;
} /* can_reference_discussion_item() */

/**
 * This method checks to see if the specified person has already voted for
 * this discussion item.
 * @param club_name the name of the club
 * @param id the id of the discussion item
 * @param person the name of the person to check
 */
int has_voted_for_discussion_item(string club_name,
                                  int id,
                                  string person) {
   class discussion_idea frog;

   frog = query_discussion_item(club_name, id);
   if (frog &&
       member_array(person, frog->voted) != -1) {
      return 1;
   }
   return 0;
} /* has_voted_for_discussion_item() */

/**
 * This method sets up the discussion item as being voted by the
 * person specified.
 * @param club_name the name of the club
 * @param id the id of the discussion item
 * @param person the person doing the voting
 * @param choice the choices there are to vote on
 * @see add_discussion_item()
 */
int vote_for_discussion_item(string club_name,
                             int id,
                             string person,
                             string choice) {
   class discussion_idea frog;

   frog = query_discussion_item(club_name, id);
   choice = lower_case(choice);
   if (frog &&
       can_reference_discussion_item(club_name, id, person) &&
       !has_voted_for_discussion_item(club_name, id, person) &&
       is_valid_discussion_choice(club_name, id, choice) &&
       is_discuss_votable(club_name, id)) {
      frog->choices[choice]++;
      frog->voted += ({ person });
      set_club_changed(club_name);
      return 1;
   }
   return 0;
} /* vote_for_discussion_item() */

/**
 * This message does the nomination thing for those discussion items
 * which accept nominations.
 * @param club_name the name of the club
 * @param id the id of the discussion item
 * @param nominator the person doing the nomination
 * @param nominated the person nominated
 */
int nominate_discussion_item(string club_name,
                             int id,
                             string nominator,
                             string nominated) {
   class discussion_idea frog;

   frog = query_discussion_item(club_name, id);
   if (frog &&
       is_member_of(club_name, nominator) &&
       is_member_of(club_name, nominated) &&
       is_discuss_nominateable(club_name, id)) {
      if (!is_creator_club(club_name) &&
          PLAYER_HANDLER->test_creator(nominated)) {
         return 0;
      }
      if (send_discuss_message(club_name,
                               CLUB_DISCUSS_MESSAGE_NOMINATION,
                               frog,
                               nominator,
                               nominated)) {
         set_club_changed(club_name);
         return 1;
      }
   }
   return 0;
} /* nominate_discussion_item() */

/**
 * This message does the withdraw thing for those discussion items
 * which accept nominations.
 * @param club_name the name of the club
 * @param id the id of the discussion item
 * @param withdraw the person being withdrawn
 */
int withdraw_discussion_item(string club_name,
                             int id,
                             string withdraw) {
   class discussion_idea frog;

   frog = query_discussion_item(club_name, id);
   if (frog &&
       is_member_of(club_name, withdraw) &&
       is_discuss_nominateable(club_name, id)) {
      if (send_discuss_message(club_name,
                               CLUB_DISCUSS_MESSAGE_WITHDRAW,
                               frog,
                               withdraw,
                               withdraw)) {
         set_club_changed(club_name);
         return 1;
      }
   }
   return 0;
} /* withdraw_discussion_item() */

/**
 * This method removes a discussion item from the club.
 * @param club_name the name of the club to remove the discussion item
 * @param item the discusion item to remove
 * @return 1 on success, 0 on failure
 */
protected int remove_discussion_item(string club_name,
                                     class discussion_idea item) {
   class election_info bing;
   int i;

   bing = (class election_info)query_elected_info(club_name);
   if (bing) {
      for (i = 0; i < sizeof(bing->discussion); i++) {
         if (bing->discussion[i] == item) {            
            bing->discussion = bing->discussion[0..i - 1] + 
               bing->discussion[i + 1..];
            set_club_changed(club_name);
            return 1;
         }
      }
   }
   return 0;
} /* remove_discussion_item() */

/**
 * This method completes the discussion item.
 * @param club_name the name of the club
 * @param id the id of the discussion item
 * @return 1 if successful, 0 if not
 * @see add_discussion_item()
 */
int complete_discussion_item(string club_name,
                             int id) {
   class discussion_idea frog;
   class election_info bing;
   int ret;

   frog = query_discussion_item(club_name, id);
   bing = (class election_info)query_elected_info(club_name);
   if (frog &&
       is_discussion_item_finished(club_name, id)) {
      if (is_discussion_item_quorum(club_name, id)) {
         if (_discussion_items[frog->discuss_type & CLUB_DISCUSS_TYPE_MASK]) {
            send_broadcast_message(club_name,
                                   "Finished discussion item: " +
                                   send_discuss_message(club_name,
                                                        CLUB_DISCUSS_MESSAGE_SHORT_DESCRIPTION,
                                                        frog,
                                                        0,
                                                        0) +
                                   " see archives for results.");
            send_discuss_message(club_name,
                                 CLUB_DISCUSS_MESSAGE_COMPLETE,
                                 frog,
                                 0,
                                 0);
         } else {
            ret = -1;
            do_mail_committee(club_name,
                              "Completed vote",
                              "The completed vote on:\n" +
                              "Discussion type " +
                               (frog->discuss_type & CLUB_DISCUSS_TYPE_MASK) +
                              " failed due to major internal messes.\n");
         }
      } else {
         if (_discussion_items[frog->discuss_type & CLUB_DISCUSS_TYPE_MASK]) {
            do_mail_committee(club_name,
                              "Completed vote",
                              "The completed vote on:\n" +
                              query_discussion_item_long_description(club_name,
                                                                     id) +
                              "\n\nDid not have quorum, only " +
                              sizeof(frog->voted) + " people voted.\n");
         } else {
            do_mail_committee(club_name,
                              "Completed vote",
                              "The completed vote on:\n" +
                              "Discussion type " + (frog->discuss_type & CLUB_DISCUSS_TYPE_MASK) +
                              " failed due to major internal messes.\n");
         }
         ret = -1;
      }
      remove_discussion_item(club_name, frog);
      //bing->discussion -= ({ frog });
      //set_club_changed(club_name);
   }
   return ret;
} /* complete_discussion_item() */

/**
 * This method sends a message to all the discussion items in the club
 * and then marks the club as changed if any of them return a non-zero
 * value.  This is used for events like a member being removed of a
 * position being changed in name.
 * @param club_name the name of the club
 * @param message the message number
 * @param arg1 the first arguement
 * @param arg2 the second arguement
 */
protected mixed send_discuss_message(string club_name,
                                     int message,
                                     class discussion_idea item,
                                     string arg1,
                                     string arg2) {
   return evaluate(_discussion_items[item->discuss_type &
                                           CLUB_DISCUSS_TYPE_MASK],
                   message,
                   club_name,
                   item,
                   arg1,
                   arg2);
} /* send_discuss_message() */

/**
 * This method sends a message to all the discussion items in the club
 * and then marks the club as changed if any of them return a non-zero
 * value.  This is used for events like a member being removed of a
 * position being changed in name.
 * @param club_name the name of the club
 * @param message the message number
 * @param arg1 the first arguement
 * @param arg2 the second arguement
 */
protected void broadcast_discuss_message(string club_name,
                                         int message,
                                         string arg1,
                                         string arg2) {
   class discussion_idea frog;
   class election_info bing;

   bing = (class election_info)query_elected_info(club_name);
   foreach (frog in bing->discussion) {
      if (send_discuss_message(club_name,
                               message,
                               frog,
                               arg1,
                               arg2)) {
         set_club_changed(club_name);
      }
   }
} /* broadcast_discuss_message() */

/*
 * -----   Methods for checking changes to the club and reporting them to 
 * -----   the discusion items
 */

/**
 * Catch the remove member calls and inform the system about them.
 * @ignore yes
 */
int remove_member(string name,
                  string member) {
   if (::remove_member(name, member)) {
      if (is_elected_club(name)) {
         broadcast_discuss_message(name,
                                   CLUB_DISCUSS_MESSAGE_REMOVE_MEMBER,
                                   member,
                                   0);
      }
      return 1;
   }
   return 0;
} /* remove_member() */

/**
 * Catch the position change call and inform the system about it.
 * @ignore yes
 */
int change_position_name_in_club(string name,
                                 string position,
                                 string new_position) {
   if (::change_position_name_in_club(name, position, new_position)) {
      if (is_elected_club(name)) {
         broadcast_discuss_message(name,
                                   CLUB_DISCUSS_MESSAGE_CHANGE_POSITION,
                                   position,
                                   new_position);
      }
      return 1;
   }
   return 0;
} /* change_position_name_in_club() */

/**
 * Catch the position removal things...
 * @ignore yes
 */
int remove_position_in_club(string name,
                            string position) {
   if (::remove_position_in_club(name, position)) {
      if (is_elected_club(name)) {
         broadcast_discuss_message(name,
                                   CLUB_DISCUSS_MESSAGE_REMOVE_POSITION,
                                   position,
                                   0);
      }
      return 1;
   }
   return 0;
} /* remove_position_in_club() */

/**
 * Catch the position holder message and turn it into a nomination.
 * @ignore yes
 */
int set_position_holder(string club_name,
                                  string position,
                                  string person) {
   if (::set_position_holder(club_name, position, person)) {
      if (person == CLUB_UNKNOWN_MEMBER) {
         add_discussion_item(club_name,
                             CLUB_DISCUSS_NOMINATION |
                                CLUB_DISCUSS_NO_QUORUM |
                                CLUB_DISCUSS_OPEN,
                             CLUB_CONTROLLER_MEMBER,
                             position,
                             "Position became vacant.\n",
                             ({ }),
                             7 * (24 * 60 * 60),
                             0);
      }
      return 1;
   }
   return 0;
} /* set_position_holder() */

/**
 * Catch the start election thing and zap all currently running
 * by-elections.
 * @ignore yes
 */
int start_election(string name) {
   class discussion_idea womble;
   class election_info data;
   int type;

   if (::start_election(name)) {
      data = (class election_info)query_elected_info(name);
      foreach (womble in data->discussion) {
         type = womble->discuss_type & CLUB_DISCUSS_TYPE_MASK;
         if (type == CLUB_DISCUSS_NOMINATION ||
             type == CLUB_DISCUSS_ELECTION) {
            remove_discussion_item(name, womble);
            set_club_changed(name);
         }
      }
      return 1;
   }
   return 0;
} /* start_election() */

/** @ignore yes */
protected void check_elected_information(string name,
                                        string member,
                                        int startup) {
   class election_info data;
   class discussion_idea frog;
   string pos;

   ::check_elected_information(name, member, startup);

   data = (class election_info)query_elected_info(name);
   if (data) {
      foreach (frog in data->discussion) {
         if (is_discussion_item_finished(name, frog->id)) {
            complete_discussion_item(name, frog->id);
            set_club_changed(name);
         } else if (frog->discuss_type == CLUB_DISCUSS_NOMINATION ||
                    frog->discuss_type == CLUB_DISCUSS_ELECTION) {
           if (!is_election_in_progress(name) &&
               !is_nomination_in_progress(name)) {
               frog->discuss_type |= CLUB_DISCUSS_OPEN |
                                     CLUB_DISCUSS_NO_QUORUM;
               set_club_changed(name);
            } else {
               remove_discussion_item(name, frog);
            }
         }
      }

      //
      // Check each position to see if we should start a by election
      // for it.
      //
      foreach (pos, member in data->positions) {
         if (member == CLUB_UNKNOWN_MEMBER &&
             !is_election_in_progress(name) &&
             !is_nomination_in_progress(name) &&
             !is_nomination_or_election_being_discussed(name, pos)) {
/*
tell_creator("pinkfish", "Setting up by election for position " + pos +
             " in club " + name + ": " + member + "\n");
 */
            setup_by_election(name,
                              pos, 
                              "Automatic after the position is declared "
                              "vacant.\n");
            set_club_changed(name);
         }
      }
   }
} /* check_elected_information() */

/**
 * This method setups up a by-election for the specified position in the
 * club.
 * @param club the club to make a byelection in
 * @param position the position the byelection is for
 * @param info the information about the vote
 * @return 1 on success, 0 on failure
 */
int setup_by_election(string club,
                      string position,
                      string info) {
   // Check to make sure that we are not in the election or nomination
   // Phase right now.  If we are too close to this phase we should
   // wait for the election to happen.
   return add_discussion_item(club,
                              CLUB_DISCUSS_NOMINATION |
                                 CLUB_DISCUSS_OPEN |
                                 CLUB_DISCUSS_NO_QUORUM,
                              CLUB_CONTROLLER_MEMBER,
                              position,
                              info,
                              ({ }),
                              7 * 24 * 60 * 60,
                              0);
} /* setup_by_election() */