/*****************************************************************************/
/* File name: Registry.java                                                  */
/* Purpose: to register RPC programs                                         */
/*                                                                           */
/* Last modified: 17.06.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*                                                                           */
/* This program is distributed in the hope that it will be useful, but       */
/* WITHOUT ANY WARRANTY; without even the implied warranty of                */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General */
/* Public License for more details.                                          */
/*                                                                           */
/* This software is distributed under the terms                              */
/* of the GNU General Public License as published                            */
/* by the Free Software Foundation; either version 2, or (at your option)    */
/* any later version.                                                        */
/* See file COPYING for your rights (GNU GPL)                                */
/*****************************************************************************/


package pm;


import java.util.*;


public
class

Registry
{

  private final static String RCSID = "$Header: /d/NFS/pm/RCS/Registry.java,v 1.8 1999/06/17 22:04:00 vklimov Exp $";


  protected ProgramHashtable programHashtable = null;
  protected int nMappings = 0;


  public

  Registry()
/*****************************************************************************/
/* Function name: Registry                                                   */
/* File name: Registry.java                                                  */
/* Purpose: constructor for the Registry class                               */
/* Parameters:                                                               */
/* Returns:                                                                  */
/* Last modified: 04.06.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
                                                       /* Registry */
/*---------------------------------------------------------------------------*/

      programHashtable = new ProgramHashtable();

    }
/*end of Registry*/


  public
  synchronized
  boolean

  put( Mapping mapping )
/*****************************************************************************/
/* Function name: put                                                        */
/* File name: Registry.java                                                  */
/* Purpose: to register a mapping                                            */
/* Parameters: mapping                                                       */
/* Returns: true - if registered OK, false - otherwise                       */
/* Last modified: 05.06.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      boolean containsThisMapping;
      Long programNumberKey;
      Long versionNumberKey;
      Long protocolNumberKey;
      VersionHashtable versionHashtable = null;
      ProtocolHashtable protocolHashtable = null;
                                                               /* put */
/*---------------------------------------------------------------------------*/

      programNumberKey = new
        Long( mapping.programNumber );
      versionNumberKey = new
        Long( mapping.versionNumber );
      protocolNumberKey = new
        Long( mapping.protocolNumber );

      versionHashtable = (VersionHashtable)
        programHashtable.get( (Object) programNumberKey );

      if (versionHashtable == null)                    /* have to create   */
        {                                              /* versionHashtable */
                                                  /* and ProtocolHashtable */

          protocolHashtable = new
            ProtocolHashtable();
          versionHashtable = new
            VersionHashtable();
          protocolHashtable.put(
            (Object) protocolNumberKey,
            (Object) mapping            );
          versionHashtable.put(
            (Object) versionNumberKey,
            (Object) protocolHashtable  );
          programHashtable.put(
            (Object) programNumberKey,
            (Object) versionHashtable  );
        }
      else /* OK got versionHashtable */
        {

          protocolHashtable = (ProtocolHashtable)
            versionHashtable.get(  (Object) versionNumberKey );

          if (protocolHashtable == null)
            {

              protocolHashtable = new
                ProtocolHashtable();
              protocolHashtable.put(
                (Object) protocolNumberKey,
                (Object) mapping            );
              versionHashtable.put(
                (Object) versionNumberKey,
                (Object) protocolHashtable  );
            }
          else /* OK got protocolHashtable */
            {

              containsThisMapping =
                protocolHashtable.
                  containsKey(
                    (Object) protocolNumberKey );

              if (containsThisMapping)                 /* have already ! */
                {
                  return false;                              /* return ! */
                }
              else /* OK, may put this mapping */
                {
                  protocolHashtable.put(
                    (Object) protocolNumberKey,
                    (Object) mapping            );
                }
            /*end of if on containsThisMapping*/
            }
        /*end of if on protocolHashtable*/
        }
    /*end of if on versionHashtable*/

      nMappings++;
      return true;

    }
/*end of put*/


  public
  synchronized
  boolean

  remove( Mapping mapping )
/*****************************************************************************/
/* Function name: remove                                                     */
/* File name: Registry.java                                                  */
/* Purpose: to unregister a mapping, protocol and port are ignored,          */
/*          i.e. all mappings with the program number and version number     */
/*          are removed - that means that the whole corresponding            */
/*          protocolHashtable object is removed                              */
/* Parameters: mapping                                                       */
/* Returns: true - if unregistered OK, false - otherwise                     */
/* Last modified: 05.06.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      boolean containsThisMapping;
      Long programNumberKey;
      Long versionNumberKey;
      VersionHashtable versionHashtable = null;
      ProtocolHashtable protocolHashtable = null;
      int nRemoved;
      int i;
                                                               /* remove */
/*---------------------------------------------------------------------------*/

      programNumberKey = new
        Long( mapping.programNumber );
      versionNumberKey = new
        Long( mapping.versionNumber );

      versionHashtable = (VersionHashtable)
        programHashtable.get( (Object) programNumberKey );

      if (versionHashtable == null)
        {
        }
      else /* OK got versionHashtable */
        {
          protocolHashtable = (ProtocolHashtable)
            versionHashtable.remove( (Object) versionNumberKey );

          if (protocolHashtable == null)
            {
            }
          else /* OK removed */
            {
               nRemoved = protocolHashtable.size();
               for (i=0;i<nRemoved;i++)
                 nMappings--;
             /*end of for-loop*/

               return true;                              /* return ! */
            }
        /*end of if on protocolHashtable*/
        }
    /*end of if on versionHashtable*/

      return false;

    }
/*end of remove*/


  public
  int

  size()
/*****************************************************************************/
/* Function name: size                                                       */
/* File name: Registry.java                                                  */
/* Purpose: to return number of mappings in this registry                    */
/* Parameters:                                                               */
/* Returns: size                                                             */
/* Last modified: 05.06.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
                                                               /* size */
/*---------------------------------------------------------------------------*/

      return nMappings;

    }
/*end of size*/


  public
  synchronized
  long

  getPort( Mapping mapping )
/*****************************************************************************/
/* Function name: getPort                                                    */
/* File name: Registry.java                                                  */
/* Purpose: to get port number corresponding a mapping                       */
/* Parameters: mapping                                                       */
/* Returns: the port number, if the mapping is not found returns 0           */
/* Last modified: 05.06.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      Mapping thisMapping;
      Long programNumberKey;
      Long versionNumberKey;
      Long protocolNumberKey;
      VersionHashtable versionHashtable = null;
      ProtocolHashtable protocolHashtable = null;
                                                               /* getPort */
/*---------------------------------------------------------------------------*/


      programNumberKey = new
        Long( mapping.programNumber );
      versionNumberKey = new
        Long( mapping.versionNumber );
      protocolNumberKey = new
        Long( mapping.protocolNumber );

      versionHashtable = (VersionHashtable)
        programHashtable.get( (Object) programNumberKey );

      if (versionHashtable == null)
        {
        }
      else /* OK got versionHashtable */
        {
          protocolHashtable = (ProtocolHashtable)
            versionHashtable.get( (Object) versionNumberKey );

          if (protocolHashtable == null)
            {
            }
          else /* OK got protocolHashtable */
            {
              thisMapping = (Mapping)
                protocolHashtable.
                  get( (Object) protocolNumberKey );

              if (thisMapping != null)
                {
                  return thisMapping.portNumber;         /* return ! */
                }
              else /* OK, may get this mapping */
                {
                }
            /*end of if on containsThisMapping*/
            }
        /*end of if on protocolHashtable*/
        }
    /*end of if on versionHashtable*/

      return pm.Constants.PORT_NOT_FOUND_NUMBER;

    }
/*end of getPort*/


  public
  synchronized
  Enumeration

  mappings()
/*****************************************************************************/
/* Function name: mappings                                                   */
/* File name: Registry.java                                                  */
/* Purpose: to enumeration of all mappings in this registry object           */
/* Parameters:                                                               */
/* Returns: the enumeration of mappings                                      */
/* Last modified: 06.06.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
                                                           /* mappings */
/*---------------------------------------------------------------------------*/

       return new RegistryEnumerator( this );

    }
/*end of mappings*/


  public
  static
  void

  main(String argv[])
/*****************************************************************************/
/* Function name: main                                                       */
/* File name: Registry.java                                                  */
/* Purpose: to test the Registry class                                       */
/* Parameters: agrument strings array                                        */
/* Returns:                                                                  */
/* Last modified: 06.06.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      int mainI;
      Registry registry;
      Mapping mapping;
      boolean result;
      Enumeration mappings;
                                                           /* main */
/*---------------------------------------------------------------------------*/

      registry = new Registry();

      mapping = new Mapping( 1, 1, 1, 1 );
      result =
        registry.put( mapping );
      if (!result)
        System.out.println( "put rejected for mapping " +
                            mapping.toString() );

      mapping = new Mapping( 1, 2, 1, 1 );
      result =
        registry.put( mapping );
      if (!result)
        System.out.println( "put rejected for mapping " +
                            mapping.toString() );

      mapping = new Mapping( 1, 3, 1, 1 );
      result =
        registry.put( mapping );
      if (!result)
        System.out.println( "put rejected for mapping " +
                            mapping.toString() );

      mapping = new Mapping( 1, 4, 1, 1 );
      result =
        registry.put( mapping );
      if (!result)
        System.out.println( "put rejected for mapping " +
                            mapping.toString() );

      mapping = new Mapping( 1, 5, 1, 1 );
      result =
        registry.put( mapping );
      if (!result)
        System.out.println( "put rejected for mapping " +
                            mapping.toString() );

      mapping = new Mapping( 1, 1, 2, 1 );
      result =
        registry.put( mapping );
      if (!result)
        System.out.println( "put rejected for mapping " +
                            mapping.toString() );

      mapping = new Mapping( 1, 1, 3, 1 );
      result =
        registry.put( mapping );
      if (!result)
        System.out.println( "put rejected for mapping " +
                            mapping.toString() );

      mapping = new Mapping( 1, 1, 4, 1 );
      result =
        registry.put( mapping );
      if (!result)
        System.out.println( "put rejected for mapping " +
                            mapping.toString() );

      mapping = new Mapping( 1, 1, 5, 1 );
      result =
        registry.put( mapping );
      if (!result)
        System.out.println( "put rejected for mapping " +
                            mapping.toString() );

      mapping = new Mapping( 1, 2, 2, 1 );
      result =
        registry.put( mapping );
      if (!result)
        System.out.println( "put rejected for mapping " +
                            mapping.toString() );

      mapping = new Mapping( 1, 2, 3, 1 );
      result =
        registry.put( mapping );
      if (!result)
        System.out.println( "put rejected for mapping " +
                            mapping.toString() );

      mapping = new Mapping( 1, 2, 4, 1 );
      result =
        registry.put( mapping );
      if (!result)
        System.out.println( "put rejected for mapping " +
                            mapping.toString() );

      mapping = new Mapping( 1, 2, 5, 1 );
      result =
        registry.put( mapping );
      if (!result)
        System.out.println( "put rejected for mapping " +
                            mapping.toString() );

      mapping = new Mapping( 1, 3, 2, 2 );
      result =
        registry.put( mapping );
      if (!result)
        System.out.println( "put rejected for mapping " +
                            mapping.toString() );

      mapping = new Mapping( 1, 3, 3, 2 );
      result =
        registry.put( mapping );
      if (!result)
        System.out.println( "put rejected for mapping " +
                            mapping.toString() );

      mapping = new Mapping( 2, 3, 1, 1 );
      result =
        registry.put( mapping );
      if (!result)
        System.out.println( "put rejected for mapping " +
                            mapping.toString() );

      mapping = new Mapping( 3, 3, 3, 3 );
      result =
        registry.put( mapping );
      if (!result)
        System.out.println( "put rejected for mapping " +
                            mapping.toString() );

      mapping = new Mapping( 3, 4, 3, 3 );
      result =
        registry.put( mapping );
      if (!result)
        System.out.println( "put rejected for mapping " +
                            mapping.toString() );

      mapping = new Mapping( 5, 5, 5, 5 );
      result =
        registry.put( mapping );
      if (!result)
        System.out.println( "put rejected for mapping " +
                               mapping.toString() );

      System.out.println( "\n\nso far registered " +
                          registry.size() + " mappings" );

      mappings =
        registry.mappings();

      for (mainI=0;mappings.hasMoreElements(); mainI++)
        {
          try
            {
              System.out.println( "mainI=" + mainI +
                                  " mapping=" +
                                  mappings.nextElement() );
            }
          catch( NoSuchElementException e )
            {
              System.out.println( "\n\nno more mappings" );
              break;                                          /* break ! */
            }
        /*end of try-catch*/
        }
    /*end of for-loop*/

    }
/*end of main*/


} /* end of Registry class */


final
class

RegistryEnumerator implements Enumeration
{

  private Registry registry;
  private int count;

  private Vector programNumberKeysVector = null;
  private Vector versionNumberKeysVector = null;
  private Vector protocolNumberKeysVector = null;

  private Long currentProgramNumberKey = null;
  private Long currentVersionNumberKey = null;
  private Long currentProtocolNumberKey = null;
  private VersionHashtable versionHashtable = null;
  private ProtocolHashtable protocolHashtable = null;


  public

  RegistryEnumerator( Registry registry )
/*****************************************************************************/
/* Function name: RegistryEnumerator                                         */
/* File name: Registry.java                                                  */
/* Purpose: constructor for the RegistryEnumerator class                     */
/* Parameters: registry                                                      */
/* Returns:                                                                  */
/* Last modified: 05.06.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
                                                   /* RegistryEnumerator */
/*---------------------------------------------------------------------------*/

      this.registry = registry;
      count = 0;

    }
/*end of RegistryEnumerator*/


  public
  synchronized
  void

  nullAllInstanceVariables()
/*****************************************************************************/
/* Function name: nullAllInstanceVariables                                   */
/* File name: Registry.java                                                  */
/* Purpose: to assign null to all instance variables                         */
/*          of this RegistryEnumeration object                               */
/* Parameters:                                                               */
/* Returns:                                                                  */
/* Last modified: 06.06.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
                                              /* nullAllInstanceVariables */
/*---------------------------------------------------------------------------*/

      programNumberKeysVector = null;
      versionNumberKeysVector = null;
      protocolNumberKeysVector = null;

      currentProgramNumberKey = null;
      currentVersionNumberKey = null;
      currentProtocolNumberKey = null;
      versionHashtable = null;
      protocolHashtable = null;

    }
/*end of nullAllInstanceVariables */


  public
  boolean

  hasMoreElements()
/*****************************************************************************/
/* Function name: hasMoreElements                                            */
/* File name: Registry.java                                                  */
/* Purpose: to check whether there are more mappings to serve up             */
/* Parameters:                                                               */
/* Returns: true - if there are more mappings to serve up, false - otherwise */
/* Last modified: 05.06.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
                                                       /* hasMoreElements */
/*---------------------------------------------------------------------------*/

      if (count < registry.nMappings)
        return true;
      else
        return false;
    /*end of if*/

    }
/*end of hasMoreElements*/


  private
  synchronized
  void

  createAndFillProgramNumberKeysVector()
/*****************************************************************************/
/* Function name: createAndFillProgramNumberKeysVector                       */
/* File name: Registry.java                                                  */
/* Purpose: to create a Vector containing all programNumber keys             */
/* Parameters:                                                               */
/* Returns:                                                                  */
/* Last modified: 06.06.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      int i;
      Enumeration programNumberKeysEnumeration;
      Long programNumberKey;

                               /* createAndFillProgramNumberKeysVector */
/*---------------------------------------------------------------------------*/

      programNumberKeysVector = new Vector();

      programNumberKeysEnumeration =
        registry.programHashtable.keys();

      i = 0;
      while( programNumberKeysEnumeration.hasMoreElements() )
        {
          try
            {
              programNumberKey = (Long)
                 programNumberKeysEnumeration.nextElement() ;

              programNumberKeysVector.addElement(
                (Object) programNumberKey );
            }
          catch( NoSuchElementException e )
            {
              break;                                             /* break ! */
            }
        /*end of try-catch*/
          i++;
        }
    /*end of while-loop on programNumberKeysEnumeration*/

      currentProgramNumberKey = (Long)
        programNumberKeysVector.firstElement();

    }
/*end of createAndFillProgramNumberKeysVector*/


  private
  synchronized
  void

  createAndFillVersionNumberKeysVector()
/*****************************************************************************/
/* Function name: createAndFillVersionNumberKeysVector                       */
/* File name: Registry.java                                                  */
/* Purpose: to create a Vector containing all versionNumber keys             */
/* Parameters:                                                               */
/* Returns:                                                                  */
/* Last modified: 07.06.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      int i;
      Enumeration versionNumberKeysEnumeration;
      Long versionNumberKey;

                               /* createAndFillVersionNumberKeysVector() */
/*---------------------------------------------------------------------------*/

      versionNumberKeysVector = new Vector();

      versionNumberKeysEnumeration =
        versionHashtable.keys();

      i = 0;
      while( versionNumberKeysEnumeration.hasMoreElements() )
        {
          try
            {
              versionNumberKey = (Long)
                 versionNumberKeysEnumeration.nextElement() ;

              versionNumberKeysVector.addElement(
                (Object) versionNumberKey );
            }
          catch( NoSuchElementException e )
            {
              break;                                             /* break ! */
            }
        /*end of try-catch*/
          i++;
        }
    /*end of while-loop on versionNumberKeysEnumeration*/

      currentVersionNumberKey = (Long)
        versionNumberKeysVector.firstElement();

    }
/*end of createAndFillVersionNumberKeysVector()*/


  private
  synchronized
  void

  createAndFillProtocolNumberKeysVector()
/*****************************************************************************/
/* Function name: createAndFillProtocolNumberKeysVector                      */
/* File name: Registry.java                                                  */
/* Purpose: to create a Vector containing all protocolNumber keys            */
/* Parameters:                                                               */
/* Returns:                                                                  */
/* Last modified: 06.06.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      int i;
      Enumeration protocolNumberKeysEnumeration;
      Long protocolNumberKey;

                               /* createAndFillProtocolNumberKeysVector() */
/*---------------------------------------------------------------------------*/

      protocolNumberKeysVector = new Vector();

      protocolNumberKeysEnumeration =
        protocolHashtable.keys();

      i = 0;
      while( protocolNumberKeysEnumeration.hasMoreElements() )
        {
          try
            {
              protocolNumberKey = (Long)
                 protocolNumberKeysEnumeration.nextElement() ;

              protocolNumberKeysVector.addElement(
                (Object) protocolNumberKey );
            }
          catch( NoSuchElementException e )
            {
              break;                                             /* break ! */
            }
        /*end of try-catch*/
          i++;
        }
    /*end of while-loop on protocolNumberKeysEnumeration*/

      currentProtocolNumberKey = (Long)
        protocolNumberKeysVector.firstElement();

    }
/*end of createAndFillProtocolNumberKeysVector()*/


  private
  synchronized
  void

  getNewProgramNumberKeyAndRemoveTheOld()
/*****************************************************************************/
/* Function name: getNewProgramNumberKeyAndRemoveTheOld                      */
/* File name: Registry.java                                                  */
/* Purpose: to get a new programNumberKey from the Vector and remove         */
/*          the old element from the vector                                  */
/* Parameters:                                                               */
/* Returns:                                                                  */
/* Last modified: 07.06.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
                               /* getNewProgramNumberKeyAndRemoveTheOld */
/*---------------------------------------------------------------------------*/

      try
        {
          programNumberKeysVector.removeElementAt( 0 );

          currentProgramNumberKey = (Long)
            programNumberKeysVector.firstElement();
        }
      catch( NoSuchElementException e )
        {
          currentProgramNumberKey = null;
        }
      catch( ArrayIndexOutOfBoundsException e )
        {
          currentProgramNumberKey = null;
        }
    /*end of try-catch*/

    }
/*end of getNewProgramNumberKeyAndRemoveTheOld*/


  private
  synchronized
  void

  getNewVersionNumberKeyAndRemoveTheOld()
/*****************************************************************************/
/* Function name: getNewVersionNumberKeyAndRemoveTheOld                      */
/* File name: Registry.java                                                  */
/* Purpose: to get a new versionNumberKey from the Vector and remove         */
/*          the old element from the vector                                  */
/* Parameters:                                                               */
/* Returns:                                                                  */
/* Last modified: 07.06.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
                               /* getNewVersionNumberKeyAndRemoveTheOld */
/*---------------------------------------------------------------------------*/

      try
        {
          versionNumberKeysVector.removeElementAt( 0 );

          currentVersionNumberKey = (Long)
            versionNumberKeysVector.firstElement();
        }
      catch( NoSuchElementException e )
        {
          currentVersionNumberKey = null;
        }
      catch( ArrayIndexOutOfBoundsException e )
        {
          currentVersionNumberKey = null;
        }
    /*end of try-catch*/

    }
/*end of getNewVersionNumberKeyAndRemoveTheOld*/


  private
  synchronized
  void

  getNewProtocolNumberKeyAndRemoveTheOld()
/*****************************************************************************/
/* Function name: getNewProtocolNumberKeyAndRemoveTheOld                     */
/* File name: Registry.java                                                  */
/* Purpose: to get a new protocolNumberKey from the Vector and remove        */
/*          the old element from the vector                                  */
/* Parameters:                                                               */
/* Returns:                                                                  */
/* Last modified: 07.06.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
                               /* getNewProtocolNumberKeyAndRemoveTheOld */
/*---------------------------------------------------------------------------*/

      try
        {

          protocolNumberKeysVector.removeElementAt( 0 );

          currentProtocolNumberKey = (Long)
            protocolNumberKeysVector.firstElement();

        }
      catch( NoSuchElementException e )
        {
          currentProtocolNumberKey = null;
        }
      catch( ArrayIndexOutOfBoundsException e )
        {
          currentProtocolNumberKey = null;
        }
    /*end of try-catch*/

    }
/*end of getNewProtocolNumberKeyAndRemoveTheOld*/


  private
  synchronized
  void

  getNewVersionHashtable()
/*****************************************************************************/
/* Function name: getNewVersionHashtable                                     */
/* File name: Registry.java                                                  */
/* Purpose: to get a new versionHashtable                                    */
/* Parameters:                                                               */
/* Throws: NoSuchElementException if there are no more versionHashtables     */
/* Returns:                                                                  */
/* Last modified: 17.06.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
                                           /* getNewVersionHashtable */
/*---------------------------------------------------------------------------*/

      do
        {
          if (currentProgramNumberKey == null)
            {
              getNewProgramNumberKeyAndRemoveTheOld();
              if (currentProgramNumberKey == null)
                {
                  nullAllInstanceVariables();
                  throw new
                    NoSuchElementException(
                      "RegistryEnumerator");               /* throw ! */
                }
              else
                ;
            /*end of if on null*/
            }
          else
            ;
        /*end of if on currentProgramNumberKey*/

          versionHashtable = (VersionHashtable)
            registry.programHashtable.get(
              (Object) currentProgramNumberKey );

          if (versionHashtable == null)
            getNewProgramNumberKeyAndRemoveTheOld();
          else
            ;
        /*end of if*/

        }
      while( (versionHashtable == null)        &&
             (currentProgramNumberKey != null)
           );

      if ( (currentProgramNumberKey == null) ||
           (versionHashtable == null)
         )
        {
          nullAllInstanceVariables();
          throw new
            NoSuchElementException("RegistryEnumerator");      /* throw ! */
        }
      else
        {
          createAndFillVersionNumberKeysVector();
        }
    /*end of if*/

    }
/*end of getNewVersionHashtable*/


  private
  synchronized
  void

  getNewProtocolHashtable() throws NoSuchElementException
/*****************************************************************************/
/* Function name: getNewProtocolHashtable                                    */
/* File name: Registry.java                                                  */
/* Purpose: to get a new protocolHashtable                                   */
/* Parameters:                                                               */
/* Throws: NoSuchElementException if there are no more protocolHashtables    */
/* Returns:                                                                  */
/* Last modified: 06.06.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
                                           /* getNewProtocolHashtable */
/*---------------------------------------------------------------------------*/

      do
        {
          if (versionHashtable == null)
            getNewVersionHashtable();
          else
            ;
        /*end of if*/

          do
            {
              if (currentVersionNumberKey == null)
                getNewVersionNumberKeyAndRemoveTheOld();
              else
                ;
            /*end of if on currentVersionNumberKey*/

              if (currentVersionNumberKey == null)
                {
                  getNewProgramNumberKeyAndRemoveTheOld();
                  if (currentProgramNumberKey == null)
                    {
                      nullAllInstanceVariables();
                      throw new
                        NoSuchElementException(
                          "RegistryEnumerator");               /* throw ! */
                    }
                  else
                    getNewVersionHashtable();
                /*end of if on currentProgramNumberKey*/
                }
              else
                ;
            /*end of if on currentVersionNumberKey*/

              protocolHashtable = (ProtocolHashtable)
                versionHashtable.get(
                  (Object) currentVersionNumberKey );

              if (protocolHashtable == null)
                getNewVersionNumberKeyAndRemoveTheOld();
              else
                ;
            /*end of if*/

            }
          while( (protocolHashtable == null)       &&
                 (currentVersionNumberKey != null)
               );
        }
      while( (currentVersionNumberKey == null) &&
             (protocolHashtable == null)
         );

      if (protocolHashtable != null)
        createAndFillProtocolNumberKeysVector();
      else
        {
          nullAllInstanceVariables();
          throw new
            NoSuchElementException(
              "RegistryEnumerator");               /* throw ! */
        }
    /*end of if*/

    }
/*end of getNewProtocolHashtable*/


  public
  Object

  nextElement() throws NoSuchElementException
/*****************************************************************************/
/* Function name: nextElement                                                */
/* File name: Registry.java                                                  */
/* Purpose: to get a next element (a mapping) from the registry              */
/* Parameters:                                                               */
/* Throws: NoSuchElementException if there are no more mappings left         */
/* Returns: the next mapping                                                 */
/* Last modified: 14.06.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      Mapping mapping;
                                                         /* nextElement */
/*---------------------------------------------------------------------------*/

      if (programNumberKeysVector == null)
        createAndFillProgramNumberKeysVector();
      else
        ;
    /*end of if*/

      do
        {
          if (protocolHashtable == null)
            getNewProtocolHashtable();
          else
            ;
        /*end of if*/

          if (currentProtocolNumberKey == null)
            getNewProtocolNumberKeyAndRemoveTheOld();
          else
            ;
        /*end of if on currentProtocolNumberKey*/

          if (currentProtocolNumberKey == null)
            {
              getNewVersionNumberKeyAndRemoveTheOld();
              getNewProtocolHashtable();
            }
          else
            ;
        /*end of if on currentProtocolNumberKey*/

          mapping = (Mapping)
            protocolHashtable.get(
              (Object) currentProtocolNumberKey );

          if (mapping != null)
            {
              getNewProtocolNumberKeyAndRemoveTheOld();
              count++;
              return (Object) mapping;                   /* return ! */
            }
          else
            getNewProtocolNumberKeyAndRemoveTheOld();
        /*end of if*/
        }
      while( true ); /* control goes out of the do-while loop either */
                     /* through return or by exception               */
                     /* in the getNewProtocolHashtable               */
    }
/*end of nextElement*/

} /* end of RegistryEnumerator class */

/*****************************************************************************/
/* End of file: Registry.java                                                */
/*****************************************************************************/
