public String toString() {
   String roles_image = "";
   for (Enumeration e = myRoles.elements(); e.hasMoreElements(); ) {
     roles_image = roles_image + "/" + (String) e.nextElement();
   }
   String relations_image = "";
   for (Enumeration e = mySupportRelations.elements(); e.hasMoreElements(); ) {
     relations_image = relations_image + "/" + (SupportRelation) e.nextElement();
   }
   return "#<Organization "
       + myName
       + " "
       + myUIC
       + " "
       + myUTC
       + " "
       + mySRC
       + " "
       + mySuperior
       + " "
       + myEchelon
       + " "
       + myAgency
       + " "
       + myService
       + " "
       + myNomenclature
       + " "
       + myPrototype
       + " "
       + roles_image
       + " "
       + relations_image
       + ">";
 }
  // Generate files for given node
  // Given Hashtable mapping node_name to Vector of cluster names
  // <Node>.ini File format:
  // [ Clusters ]
  // cluster = <clustername>
  // ...
  private void dumpNodeInfo(Hashtable all_nodes, String path) throws IOException {
    PrintWriter node_file;
    // Iterate over hashtable of nodes and write <Node>.ini file for each
    for (Enumeration e = all_nodes.keys(); e.hasMoreElements(); ) {
      String node_name = (String) (e.nextElement());

      try {
        if (path != null) {
          node_file = createPrintWriter(path + File.separator + node_name + ".ini");
        } else {
          node_file = createPrintWriter(node_name + ".ini");
        }
        node_file.println("[ Clusters ]");
        Vector clusters = (Vector) all_nodes.get(node_name);
        for (Enumeration c = clusters.elements(); c.hasMoreElements(); ) {
          String cluster_name = (String) (c.nextElement());
          node_file.println("cluster = " + cluster_name);
        }
        node_file.close();
      } catch (IOException exc) {
        System.out.println("IOException:  " + exc);
        System.exit(-1);
      }
    }
  }
  // Write <Cluster>.ini file
  // Given Hashtable mapping cluster name to Vector of plugin names
  // <Cluster>.ini File format:
  // [ Cluster ]
  // uic = <Agentname>
  // cloned = false
  // [ Plugins ]
  // plugin = <pluginname>
  // ...
  //
  private void dumpClusterInfo(Hashtable all_clusters, String path) throws IOException {
    // Dump hashtable of clusters
    for (Enumeration e = all_clusters.keys(); e.hasMoreElements(); ) {
      String cluster_name = (String) e.nextElement();
      PrintWriter cluster_file;

      try {
        if (path != null) {
          cluster_file = createPrintWriter(path + File.separator + cluster_name + ".ini");
        } else {
          cluster_file = createPrintWriter(cluster_name + ".ini");
        }

        cluster_file.println("[ Cluster ]");
        cluster_file.println("uic = " + cluster_name);
        cluster_file.println("cloned = false\n");
        cluster_file.println("[ Plugins ]");
        Vector plugins = (Vector) (all_clusters.get(cluster_name));
        for (Enumeration p = plugins.elements(); p.hasMoreElements(); ) {
          String plugin = (String) (p.nextElement());
          cluster_file.println("plugin = " + plugin);
        }
        cluster_file.close();
      } catch (IOException exc) {
        System.out.println("IOException:  " + exc);
        System.exit(-1);
      }
    }
  }
  /**
   * INTERNAL: Build and return the appropriate field value for the specified set of nested rows.
   * The database better be expecting an ARRAY. It looks like we can ignore inheritance here....
   */
  public Object buildFieldValueFromNestedRows(
      Vector nestedRows, String structureName, AbstractSession session) throws DatabaseException {
    Object[] fields = new Object[nestedRows.size()];
    java.sql.Connection connection = ((DatabaseAccessor) session.getAccessor()).getConnection();
    boolean reconnected = false;

    try {
      if (connection == null) {
        ((DatabaseAccessor) session.getAccessor()).incrementCallCount(session);
        reconnected = true;
        connection = ((DatabaseAccessor) session.getAccessor()).getConnection();
      }

      int i = 0;
      for (Enumeration stream = nestedRows.elements(); stream.hasMoreElements(); ) {
        AbstractRecord nestedRow = (AbstractRecord) stream.nextElement();
        fields[i++] = this.buildStructureFromRow(nestedRow, session, connection);
      }

      return session.getPlatform().createArray(structureName, fields, session, connection);
    } catch (java.sql.SQLException exception) {
      throw DatabaseException.sqlException(exception, session, false);
    } finally {
      if (reconnected) {
        ((DatabaseAccessor) session.getAccessor()).decrementCallCount();
      }
    }
  }
  /** INTERNAL: Conform the result if specified. */
  protected Object conformResult(
      Object result,
      UnitOfWorkImpl unitOfWork,
      AbstractRecord arguments,
      boolean buildDirectlyFromRows) {
    if (getSelectionCriteria() != null) {
      ExpressionBuilder builder = getSelectionCriteria().getBuilder();
      builder.setSession(unitOfWork.getRootSession(null));
      builder.setQueryClass(getReferenceClass());
    }

    // If the query is redirected then the collection returned might no longer
    // correspond to the original container policy.  CR#2342-S.M.
    ContainerPolicy cp;
    if (getRedirector() != null) {
      cp = ContainerPolicy.buildPolicyFor(result.getClass());
    } else {
      cp = getContainerPolicy();
    }

    // This code is now a great deal different...  For one, registration is done
    // as part of conforming.  Also, this should only be called if one actually
    // is conforming.
    // First scan the UnitOfWork for conforming instances.
    // This will walk through the entire cache of registered objects.
    // Let p be objects from result not in the cache.
    // Let c be objects from cache.
    // Presently p intersect c = empty set, but later p subset c.
    // By checking cache now doesConform will be called p fewer times.
    Map indexedInterimResult =
        unitOfWork.scanForConformingInstances(
            getSelectionCriteria(), getReferenceClass(), arguments, this);

    Cursor cursor = null;
    // In the case of cursors just conform/register the initially read collection.
    if (cp.isCursorPolicy()) {
      cursor = (Cursor) result;
      cp = ContainerPolicy.buildPolicyFor(ClassConstants.Vector_class);
      // In nested UnitOfWork session might have been session of the parent.
      cursor.setSession(unitOfWork);
      result = cursor.getObjectCollection();
      // for later incremental conforming...
      cursor.setInitiallyConformingIndex(indexedInterimResult);
      cursor.setSelectionCriteriaClone(getSelectionCriteria());
      cursor.setTranslationRow(arguments);
    }

    // Now conform the result from the database.
    // Remove any deleted or changed objects that no longer conform.
    // Deletes will only work for simple queries, queries with or's or anyof's may not return
    // correct results when untriggered indirection is in the model.
    Vector fromDatabase = null;

    // When building directly from rows, one of the performance benefits
    // is that we no longer have to wrap and then unwrap the originals.
    // result is just a vector, not a container of wrapped originals.
    if (buildDirectlyFromRows) {
      Vector rows = (Vector) result;
      fromDatabase = new Vector(rows.size());
      for (int i = 0; i < rows.size(); i++) {
        Object object = rows.elementAt(i);
        // null is placed in the row collection for 1-m joining to filter duplicate rows.
        if (object != null) {
          Object clone =
              conformIndividualResult(
                  object,
                  unitOfWork,
                  arguments,
                  getSelectionCriteria(),
                  indexedInterimResult,
                  buildDirectlyFromRows);
          if (clone != null) {
            fromDatabase.addElement(clone);
          }
        }
      }
    } else {
      fromDatabase = new Vector(cp.sizeFor(result));
      AbstractSession sessionToUse = unitOfWork.getParent();
      for (Object iter = cp.iteratorFor(result); cp.hasNext(iter); ) {
        Object object = cp.next(iter, sessionToUse);
        Object clone =
            conformIndividualResult(
                object,
                unitOfWork,
                arguments,
                getSelectionCriteria(),
                indexedInterimResult,
                buildDirectlyFromRows);
        if (clone != null) {
          fromDatabase.addElement(clone);
        }
      }
    }

    // Now add the unwrapped conforming instances into an appropriate container.
    // Wrapping is done automatically.
    // Make sure a vector of exactly the right size is returned.
    Object conformedResult =
        cp.containerInstance(indexedInterimResult.size() + fromDatabase.size());
    Object eachClone;
    for (Iterator enumtr = indexedInterimResult.values().iterator(); enumtr.hasNext(); ) {
      eachClone = enumtr.next();
      cp.addInto(eachClone, conformedResult, unitOfWork);
    }
    for (Enumeration enumtr = fromDatabase.elements(); enumtr.hasMoreElements(); ) {
      eachClone = enumtr.nextElement();
      cp.addInto(eachClone, conformedResult, unitOfWork);
    }

    if (cursor != null) {
      cursor.setObjectCollection((Vector) conformedResult);

      // For nested UOW must copy all in object collection to
      // initiallyConformingIndex, as some of these could have been from
      // the parent UnitOfWork.
      if (unitOfWork.isNestedUnitOfWork()) {
        for (Enumeration enumtr = cursor.getObjectCollection().elements();
            enumtr.hasMoreElements(); ) {
          Object clone = enumtr.nextElement();
          indexedInterimResult.put(clone, clone);
        }
      }
      return cursor;
    } else {
      return conformedResult;
    }
  }