/* Copyright (C) 2021-2025 Free Software Foundation, Inc.
   Contributed by Oracle.

   This file is part of GNU Binutils.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3, or (at your option)
   any later version.

   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.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */

#include "config.h"
#include <ctype.h>
#include <stdio.h>
#include <dirent.h>
#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include <sys/param.h>

#include "util.h"
#include "Application.h"
#include "Experiment.h"
#include "ExpGroup.h"
#include "Expression.h"
#include "DataObject.h"
#include "Elf.h"
#include "Function.h"
#include "DbeSession.h"
#include "LoadObject.h"
#include "DbeSyncMap.h"
#include "DbeThread.h"
#include "ClassFile.h"
#include "IndexObject.h"
#include "PathTree.h"
#include "Print.h"

// Bison 3.0 doesn't define YY_NULLPTR. I copied this from QLParser.tab.cc.
// Why this is not in QLParser.tab.hh ? YY_NULLPTR is used in QLParser.tab.hh
# ifndef YY_NULLPTR
#  if defined __cplusplus && 201103L <= __cplusplus
#   define YY_NULLPTR nullptr
#  else
#   define YY_NULLPTR 0
#  endif
# endif
#include "QLParser.tab.hh"
#include "DbeView.h"
#include "MemorySpace.h"
#include "Module.h"
#include "SourceFile.h"
#include "StringBuilder.h"
#include "BaseMetric.h"
#include "BaseMetricTreeNode.h"
#include "Command.h"
#include "UserLabel.h"
#include "StringMap.h"
#include "DbeFile.h"
#include "DbeJarFile.h"
#include "IOActivity.h"
#include "HeapActivity.h"

// This is a universal List structure to organize objects
// of various types, even if different.
struct List
{
  List *next;
  void *val;
};

struct Countable
{
  Countable (void *_item)
  {
    item = _item;
    ref_count = 0;
  }

  void *item;
  int ref_count;
};

Platform_t DbeSession::platform =
#if ARCH(SPARC)
	Sparc;
#elif ARCH(Aarch64)
	Aarch64;
#elif ARCH(RISCV)
	RISCV;
#else   // ARCH(Intel)
	Intel;
#endif

// This constant determines the size of the data object name hash table.
static const int HTableSize         = 8192;
static int DEFAULT_TINY_THRESHOLD   = -1;

unsigned int mpmt_debug_opt = 0;
DbeSession *dbeSession = NULL;

DbeSession::DbeSession (Settings *_settings, bool _ipc_mode, bool _rdt_mode)
{
  dbeSession = this;
  ipc_mode = _ipc_mode;
  rdt_mode = _rdt_mode;
  settings = new Settings (_settings);
  views = new Vector<DbeView*>;
  exps = new Vector<Experiment*>;
  lobjs = new Vector<LoadObject*>;
  objs = new Vector<Histable*>;
  dobjs = new Vector<DataObject*>;
  metrics = new Vector<Countable*>;
  reg_metrics = new Vector<BaseMetric*>;
  hwcentries = NULL;
  reg_metrics_tree = NULL; // BaseMetric() requires DbeSession::ql_parse
  idxobjs = new Vector<HashMap<uint64_t, Histable*>*>;
  tmp_files = new Vector<char*>;
  search_path = new Vector<char*>;
  classpath = new Vector<char*>;
  classpath_df = NULL;
  expGroups = new Vector<ExpGroup*>;
  sourcesMap = new HashMap<char*, SourceFile*>;
  sources = new Vector<SourceFile*>;
  comp_lobjs = new HashMap<char*, LoadObject*>;
  comp_dbelines = new HashMap<char*, DbeLine*>;
  comp_sources = new HashMap<char*, SourceFile*>;
  loadObjMap = new DbeSyncMap<LoadObject>;
  f_special = new Vector<Function*>(LastSpecialFunction);
  omp_functions = new Vector<Function*>(OMP_LAST_STATE);
  interactive = false;
  lib_visibility_used = false;

  // Define all known property names
  propNames = new Vector<PropDescr*>;
  propNames_name_store (PROP_NONE, NTXT (""));
  propNames_name_store (PROP_ATSTAMP, NTXT ("ATSTAMP"));
  propNames_name_store (PROP_ETSTAMP, NTXT ("ETSTAMP"));
  propNames_name_store (PROP_TSTAMP, NTXT ("TSTAMP"));
  propNames_name_store (PROP_THRID, NTXT ("THRID"));
  propNames_name_store (PROP_LWPID, NTXT ("LWPID"));
  propNames_name_store (PROP_CPUID, NTXT ("CPUID"));
  propNames_name_store (PROP_FRINFO, NTXT ("FRINFO"));
  propNames_name_store (PROP_EVT_TIME, NTXT ("EVT_TIME"));

  // Samples
  propNames_name_store (PROP_SMPLOBJ, NTXT ("SMPLOBJ"));
  propNames_name_store (PROP_SAMPLE, NTXT ("SAMPLE"));

  // GCEvents
  propNames_name_store (PROP_GCEVENTOBJ, NTXT ("GCEVENTOBJ"));
  propNames_name_store (PROP_GCEVENT, NTXT ("GCEVENT"));

  // Metadata used by some packet types
  propNames_name_store (PROP_VOIDP_OBJ, NTXT ("VOIDP_OBJ"),
			NULL, TYPE_UINT64, DDFLAG_NOSHOW);

  // Clock profiling properties
  propNames_name_store (PROP_UCPU, NTXT ("UCPU"));
  propNames_name_store (PROP_SCPU, NTXT ("SCPU"));
  propNames_name_store (PROP_TRAP, NTXT ("TRAP"));
  propNames_name_store (PROP_TFLT, NTXT ("TFLT"));
  propNames_name_store (PROP_DFLT, NTXT ("DFLT"));
  propNames_name_store (PROP_KFLT, NTXT ("KFLT"));
  propNames_name_store (PROP_ULCK, NTXT ("ULCK"));
  propNames_name_store (PROP_TSLP, NTXT ("TSLP"));
  propNames_name_store (PROP_WCPU, NTXT ("WCPU"));
  propNames_name_store (PROP_TSTP, NTXT ("TSTP"));

  propNames_name_store (PROP_MSTATE, NTXT ("MSTATE"));
  propNames_name_store (PROP_NTICK, NTXT ("NTICK"));
  propNames_name_store (PROP_OMPSTATE, NTXT ("OMPSTATE"));

  // Synchronization tracing properties
  propNames_name_store (PROP_SRQST, NTXT ("SRQST"));
  propNames_name_store (PROP_SOBJ, NTXT ("SOBJ"));

  // Hardware counter profiling properties
  propNames_name_store (PROP_HWCTAG, NTXT ("HWCTAG"));
  propNames_name_store (PROP_HWCINT, NTXT ("HWCINT"));
  propNames_name_store (PROP_VADDR, NTXT ("VADDR"));
  propNames_name_store (PROP_PADDR, NTXT ("PADDR"));
  propNames_name_store (PROP_VIRTPC, NTXT ("VIRTPC"));
  propNames_name_store (PROP_PHYSPC, NTXT ("PHYSPC"));
  propNames_name_store (PROP_LWP_LGRP_HOME, NTXT ("LWP_LGRP_HOME"));
  propNames_name_store (PROP_PS_LGRP_HOME, NTXT ("PS_LGRP_HOME"));
  propNames_name_store (PROP_EA_PAGESIZE, NTXT ("EA_PAGESIZE"));
  propNames_name_store (PROP_EA_LGRP, NTXT ("EA_LGRP"));
  propNames_name_store (PROP_PC_PAGESIZE, NTXT ("PC_PAGESIZE"));
  propNames_name_store (PROP_PC_LGRP, NTXT ("PC_LGRP"));
  propNames_name_store (PROP_HWCDOBJ, NTXT ("HWCDOBJ"));
  propNames_name_store (PROP_MEM_LAT, NTXT ("MEM_LAT"));
  propNames_name_store (PROP_MEM_SRC, NTXT ("MEM_SRC"));

  // Heap tracing properties
  propNames_name_store (PROP_HTYPE, NTXT ("HTYPE"));
  propNames_name_store (PROP_HSIZE, NTXT ("HSIZE"));
  propNames_name_store (PROP_HVADDR, NTXT ("HVADDR"));
  propNames_name_store (PROP_HOVADDR, NTXT ("HOVADDR"));
  propNames_name_store (PROP_HLEAKED, NTXT ("HLEAKED"),
			GTXT ("Leaked bytes"), TYPE_UINT64, 0);
  propNames_name_store (PROP_HMEM_USAGE, NTXT ("HMEM_USAGE"));
  propNames_name_store (PROP_HFREED, NTXT ("HFREED"),
			GTXT ("Freed bytes"), TYPE_UINT64, 0);
  propNames_name_store (PROP_HCUR_ALLOCS, NTXT ("HCUR_ALLOCS"),
			GTXT ("Current allocations"), TYPE_INT64, 0);
  propNames_name_store (PROP_HCUR_NET_ALLOC, NTXT ("HCUR_NET_ALLOC"),
			NULL, TYPE_INT64, DDFLAG_NOSHOW);
  propNames_name_store (PROP_HCUR_LEAKS, NTXT ("HCUR_LEAKS"),
			GTXT ("Current leaks"), TYPE_UINT64, 0);
  propNames_name_store (PROP_DDSCR_LNK, NTXT ("DDSCR_LNK"),
			NULL, TYPE_UINT64, DDFLAG_NOSHOW);

  // IO tracing properties
  propNames_name_store (PROP_IOTYPE, NTXT ("IOTYPE"));
  propNames_name_store (PROP_IOFD, NTXT ("IOFD"));
  propNames_name_store (PROP_IONBYTE, NTXT ("IONBYTE"));
  propNames_name_store (PROP_IORQST, NTXT ("IORQST"));
  propNames_name_store (PROP_IOOFD, NTXT ("IOOFD"));
  propNames_name_store (PROP_IOFNAME, NTXT ("IOFNAME"));
  propNames_name_store (PROP_IOVFD, NTXT ("IOVFD"));
  propNames_name_store (PROP_IOFSTYPE, NTXT ("IOFSTYPE"));

  // omptrace raw properties
  propNames_name_store (PROP_CPRID, NTXT ("CPRID"));
  propNames_name_store (PROP_PPRID, NTXT ("PPRID"));
  propNames_name_store (PROP_TSKID, NTXT ("TSKID"));
  propNames_name_store (PROP_PTSKID, NTXT ("PTSKID"));
  propNames_name_store (PROP_PRPC, NTXT ("PRPC"));

  // Data race detection properties
  propNames_name_store (PROP_RID, NTXT ("RID"));
  propNames_name_store (PROP_RTYPE, NTXT ("RTYPE"));
  propNames_name_store (PROP_LEAFPC, NTXT ("LEAFPC"));
  propNames_name_store (PROP_RVADDR, NTXT ("RVADDR"));
  propNames_name_store (PROP_RCNT, NTXT ("RCNT"));

  // Deadlock detection properties
  propNames_name_store (PROP_DID, NTXT ("DID"));
  propNames_name_store (PROP_DLTYPE, NTXT ("DLTYPE"));
  propNames_name_store (PROP_DTYPE, NTXT ("DTYPE"));
  propNames_name_store (PROP_DVADDR, NTXT ("DVADDR"));

  // Synthetic properties (queries only)
  propNames_name_store (PROP_STACK, NTXT ("STACK"));
  propNames_name_store (PROP_MSTACK, NTXT ("MSTACK"));
  propNames_name_store (PROP_USTACK, NTXT ("USTACK"));
  propNames_name_store (PROP_XSTACK, NTXT ("XSTACK"));
  propNames_name_store (PROP_HSTACK, NTXT ("HSTACK"));
  propNames_name_store (PROP_STACKID, NTXT ("STACKID"));
  //propNames_name_store( PROP_CPRID,   NTXT("CPRID") );
  //propNames_name_store( PROP_TSKID,   NTXT("TSKID") );
  propNames_name_store (PROP_JTHREAD, NTXT ("JTHREAD"),
			GTXT ("Java thread number"), TYPE_UINT64, 0);

  propNames_name_store (PROP_LEAF, NTXT ("LEAF"));
  propNames_name_store (PROP_DOBJ, NTXT ("DOBJ"));
  propNames_name_store (PROP_SAMPLE_MAP, NTXT ("SAMPLE_MAP"));
  propNames_name_store (PROP_GCEVENT_MAP, NTXT ("GCEVENT_MAP"));
  propNames_name_store (PROP_PID, NTXT ("PID"),
			GTXT ("Process id"), TYPE_UINT64, 0);
  propNames_name_store (PROP_EXPID, NTXT ("EXPID"),
			GTXT ("Experiment id"), TYPE_UINT64, DDFLAG_NOSHOW);
  propNames_name_store (PROP_EXPID_CMP, NTXT ("EXPID_CMP"),
			GTXT ("Comparable Experiment Id"), TYPE_UINT64,
			DDFLAG_NOSHOW); //YXXX find better description
  propNames_name_store (PROP_EXPGRID, NTXT ("EXPGRID"),
			GTXT ("Comparison Group id"), TYPE_UINT64, 0);
  propNames_name_store (PROP_PARREG, NTXT ("PARREG"));
  propNames_name_store (PROP_TSTAMP_LO, NTXT ("TSTAMP_LO"),
			GTXT ("Start Timestamp (nanoseconds)"), TYPE_UINT64, 0);
  propNames_name_store (PROP_TSTAMP_HI, NTXT ("TSTAMP_HI"),
			GTXT ("End Timestamp (nanoseconds)"), TYPE_UINT64, 0);
  propNames_name_store (PROP_TSTAMP2, NTXT ("TSTAMP2"),
			GTXT ("End Timestamp (nanoseconds)"), TYPE_UINT64,
			DDFLAG_NOSHOW);
  propNames_name_store (PROP_FREQ_MHZ, NTXT ("FREQ_MHZ"),
			GTXT ("CPU Frequency, MHz"), TYPE_UINT32, 0);
  propNames_name_store (PROP_NTICK_USEC, NTXT ("NTICK_USEC"),
			GTXT ("Clock Profiling Interval, Microseconds"),
			TYPE_UINT64, 0);

  propNames_name_store (PROP_IOHEAPBYTES, NTXT ("IOHEAPBYTES"));

  propNames_name_store (PROP_STACKL, NTXT ("STACKL"));
  propNames_name_store (PROP_MSTACKL, NTXT ("MSTACKL"));
  propNames_name_store (PROP_USTACKL, NTXT ("USTACKL"));
  propNames_name_store (PROP_XSTACKL, NTXT ("XSTACKL"));

  propNames_name_store (PROP_STACKI, NTXT ("STACKI"));
  propNames_name_store (PROP_MSTACKI, NTXT ("MSTACKI"));
  propNames_name_store (PROP_USTACKI, NTXT ("USTACKI"));
  propNames_name_store (PROP_XSTACKI, NTXT ("XSTACKI"));

  // Make sure predefined names are not used for dynamic properties
  propNames_name_store (PROP_LAST, NTXT (""));

  localized_SP_UNKNOWN_NAME = GTXT ("(unknown)");

  // define Index objects
  dyn_indxobj = new Vector<IndexObjType_t*>();
  dyn_indxobj_indx = 0;
  char *s = dbe_sprintf (NTXT ("((EXPID_CMP<<%llu) | THRID)"),
			 (unsigned long long) IndexObject::INDXOBJ_EXPID_SHIFT);
  indxobj_define (NTXT ("Threads"), GTXT ("Threads"), s, NULL, NULL);
  free (s);
  indxobj_define (NTXT ("CPUs"), GTXT ("CPUs"), NTXT ("(CPUID)"), NULL, NULL);
  indxobj_define (NTXT ("Samples"), GTXT ("Samples"), NTXT ("(SAMPLE_MAP)"),
		  NULL, NULL);
  indxobj_define (NTXT ("GCEvents"), GTXT ("GCEvents"), NTXT ("(GCEVENT_MAP)"),
		  NULL, NULL);
  indxobj_define (NTXT ("Seconds"), GTXT ("Seconds"),
		  NTXT ("(TSTAMP/1000000000)"), NULL, NULL);
  indxobj_define (NTXT ("Processes"), GTXT ("Processes"), NTXT ("(EXPID_CMP)"),
		  NULL, NULL);
  s = dbe_sprintf (NTXT ("((EXPGRID<<%llu) | (EXPID<<%llu))"),
		   (unsigned long long) IndexObject::INDXOBJ_EXPGRID_SHIFT,
		   (unsigned long long) IndexObject::INDXOBJ_EXPID_SHIFT);
  indxobj_define (NTXT ("Experiment_IDs"), GTXT ("Experiment_IDs"), s, NULL, NULL);
  free (s);
  indxobj_define (NTXT ("Datasize"), GTXT ("Datasize"),
		  "(IOHEAPBYTES==0?0:"
		  "((IOHEAPBYTES<=(1<<0)?(1<<0):"
		  "((IOHEAPBYTES<=(1<<2)?(1<<2):"
		  "((IOHEAPBYTES<=(1<<4)?(1<<4):"
		  "((IOHEAPBYTES<=(1<<6)?(1<<6):"
		  "((IOHEAPBYTES<=(1<<8)?(1<<8):"
		  "((IOHEAPBYTES<=(1<<10)?(1<<10):"
		  "((IOHEAPBYTES<=(1<<12)?(1<<12):"
		  "((IOHEAPBYTES<=(1<<14)?(1<<14):"
		  "((IOHEAPBYTES<=(1<<16)?(1<<16):"
		  "((IOHEAPBYTES<=(1<<18)?(1<<18):"
		  "((IOHEAPBYTES<=(1<<20)?(1<<20):"
		  "((IOHEAPBYTES<=(1<<22)?(1<<22):"
		  "((IOHEAPBYTES<=(1<<24)?(1<<24):"
		  "((IOHEAPBYTES<=(1<<26)?(1<<26):"
		  "((IOHEAPBYTES<=(1<<28)?(1<<28):"
		  "((IOHEAPBYTES<=(1<<30)?(1<<30):"
		  "((IOHEAPBYTES<=(1<<32)?(1<<32):"
		  "((IOHEAPBYTES<=(1<<34)?(1<<34):"
		  "((IOHEAPBYTES<=(1<<36)?(1<<36):"
		  "((IOHEAPBYTES<=(1<<38)?(1<<38):"
		  "((IOHEAPBYTES<=(1<<40)?(1<<40):"
		  "((IOHEAPBYTES<=(1<<42)?(1<<42):"
		  "((IOHEAPBYTES<=(1<<44)?(1<<44):"
		  "((IOHEAPBYTES<=(1<<46)?(1<<46):"
		  "((IOHEAPBYTES<=(1<<48)?(1<<48):"
		  "((IOHEAPBYTES<=(1<<50)?(1<<50):"
		  "(IOHEAPBYTES==-1?-1:(1<<50|1)"
		  "))))))))))))))))))))))))))))))))))))))))))))))))))))))",
		  NULL, NULL);
  indxobj_define (NTXT ("Duration"), GTXT ("Duration"),
		  "((TSTAMP_HI-TSTAMP_LO)==0?0:"
		  "(((TSTAMP_HI-TSTAMP_LO)<=1000?1000:"
		  "(((TSTAMP_HI-TSTAMP_LO)<=10000?10000:"
		  "(((TSTAMP_HI-TSTAMP_LO)<=100000?100000:"
		  "(((TSTAMP_HI-TSTAMP_LO)<=1000000?1000000:"
		  "(((TSTAMP_HI-TSTAMP_LO)<=10000000?10000000:"
		  "(((TSTAMP_HI-TSTAMP_LO)<=100000000?100000000:"
		  "(((TSTAMP_HI-TSTAMP_LO)<=1000000000?1000000000:"
		  "(((TSTAMP_HI-TSTAMP_LO)<=10000000000?10000000000:"
		  "(((TSTAMP_HI-TSTAMP_LO)<=100000000000?100000000000:"
		  "(((TSTAMP_HI-TSTAMP_LO)<=1000000000000?1000000000000:"
		  "(((TSTAMP_HI-TSTAMP_LO)<=10000000000000?10000000000000:"
		  "(10000000000001))))))))))))))))))))))))", NULL, NULL);
  dyn_indxobj_indx_fixed = dyn_indxobj_indx;
  Elf::elf_init ();
  defExpName = NULL;
  mach_model_loaded = NULL;
  tmp_dir_name = NULL;
  settings->read_rc (ipc_mode || rdt_mode);

  init ();
}

DbeSession::~DbeSession ()
{
  Destroy (views);
  Destroy (exps);
  Destroy (dobjs);
  Destroy (metrics);
  Destroy (search_path);
  Destroy (classpath);
  Destroy (propNames);
  Destroy (expGroups);
  Destroy (userLabels);
  if (hwcentries)
    {
      for (long i = 0, sz = hwcentries->size (); i < sz; i++)
	{
	  Hwcentry *h = hwcentries->get (i);
	  free (h->int_name);
	  free (h->name);
	  delete h;
	}
      delete hwcentries;
    }

  if (idxobjs)
    {
      for (int i = 0; i < idxobjs->size (); ++i)
	{
	  HashMap<uint64_t, Histable*> *hMap = idxobjs->get (i);
	  if (hMap)
	    {
	      hMap->values ()->destroy ();
	      delete hMap;
	    }
	}
      delete idxobjs;
    }

  for (int i = 0; i < HTableSize; i++)
    {
      List *list = dnameHTable[i];
      while (list)
	{
	  List *tmp = list;
	  list = list->next;
	  delete tmp;
	}
    }
  delete[] dnameHTable;
  delete classpath_df;
  Destroy (objs);
  Destroy (reg_metrics);
  Destroy (dyn_indxobj);
  delete lobjs;
  delete f_special;
  destroy_map (DbeFile *, dbeFiles);
  destroy_map (DbeJarFile *, dbeJarFiles);
  delete loadObjMap;
  delete omp_functions;
  delete sourcesMap;
  delete sources;
  delete comp_lobjs;
  delete comp_dbelines;
  delete comp_sources;
  delete reg_metrics_tree;
  delete settings;
  free (mach_model_loaded);

  if (defExpName != NULL)
    {
      StringBuilder *sb = new StringBuilder ();
      sb->append (NTXT ("/bin/rm -rf "));
      sb->append (defExpName);
      char *cmd = sb->toString ();
      system (cmd);
      free (cmd);
      delete sb;
      free (defExpName);
    }
  unlink_tmp_files ();
  delete tmp_files;
  dbeSession = NULL;
}

void
DbeSession::unlink_tmp_files ()
{
  if (tmp_files)
    {
      for (int i = 0, sz = tmp_files->size (); i < sz; i++)
	unlink (tmp_files->fetch (i));
      tmp_files->destroy ();
      delete tmp_files;
      tmp_files = NULL;
    }
  if (tmp_dir_name)
    {
      char *cmd = dbe_sprintf (NTXT ("/bin/rm -rf %s"), tmp_dir_name);
      system (cmd);
      free (cmd);
      free (tmp_dir_name);
      tmp_dir_name = NULL;
    }
}

char *
DbeSession::get_tmp_file_name (const char *nm, bool for_java)
{
  if (tmp_dir_name == NULL)
    {
      tmp_dir_name = dbe_sprintf (NTXT ("/tmp/analyzer.%llu.%lld"),
			 (unsigned long long) getuid (), (long long) getpid ());
      mkdir (tmp_dir_name, S_IRWXU);
    }
  char *fnm = dbe_sprintf (NTXT ("%s/%s"), tmp_dir_name, nm);
  if (for_java)
    for (char *s = fnm + strlen (tmp_dir_name) + 1; *s; s++)
      if (*s == '/')
	*s = '.';
  return fnm;
}

void
DbeSession::init ()
{
  user_exp_id_counter = 0;
  status_ompavail = 0;
  archive_mode = 0;

#if DEBUG
  char *s = getenv (NTXT ("MPMT_DEBUG"));
  if (s)
    mpmt_debug_opt = atoi (s);
#endif /* DEBUG */
  dbeFiles = new StringMap<DbeFile*>();
  dbeJarFiles = new StringMap<DbeJarFile*>(128, 128);

  // set up the initial (after .rc file reading) search path
  set_search_path (settings->str_search_path, true);
  userLabels = NULL;

  // Preset all objects as they may reuse each other
  lo_unknown = NULL;
  f_unknown = NULL;
  j_unknown = NULL;
  lo_total = NULL;
  sf_unknown = NULL;
  f_total = NULL;
  f_jvm = NULL;
  d_total = NULL;
  d_scalars = NULL;
  d_unknown = NULL;
  expGroups->destroy ();
  f_special->reset ();
  for (int i = 0; i < LastSpecialFunction; i++)
    f_special->append (NULL);

  lo_omp = NULL;
  omp_functions->reset ();
  for (int i = 0; i < OMP_LAST_STATE; i++)
    omp_functions->append (NULL);

  // make sure the metric list is initialized
  register_metric (Metric::SIZES);
  register_metric (Metric::ADDRESS);
  register_metric (Metric::ONAME);

  // This is needed only to maintain loadobject id's
  // for <Total> and <Unknown> in tests
  (void) get_Unknown_LoadObject ();
  (void) get_Total_LoadObject ();

  // Create the data object name hash table.
  dnameHTable = new List*[HTableSize];
  for (int i = 0; i < HTableSize; i++)
    dnameHTable[i] = NULL;

  d_total = createDataObject ();
  d_total->set_name (NTXT ("<Total>"));

  // XXXX <Scalars> only appropriate for Program/Data-oriented analyses
  d_scalars = createDataObject ();
  d_scalars->set_name (GTXT ("<Scalars>"));

  d_unknown = createDataObject ();
  d_unknown->set_name (GTXT ("<Unknown>"));

  // assign d_unknown's children so data_olayout has consistent sorting
  for (unsigned pp_code = 1; pp_code < NUM_ABS_PP_CODES + 2; pp_code++)
    {
      char *errcode;
      DataObject* dobj = createDataObject ();
      switch (pp_code)
	{
	case NUM_ABS_PP_CODES + 1:
	  errcode = PTXT (DOBJ_UNDETERMINED);
	  break;
	case NUM_ABS_PP_CODES:
	  errcode = PTXT (DOBJ_UNSPECIFIED);
	  break;
	case NUM_ABS_PP_CODES - 1:
	  errcode = PTXT (DOBJ_UNIDENTIFIED);
	  break;
	default:
	  errcode = PTXT (ABS_PP_CODES[pp_code]);
	}
      dobj->parent = d_unknown;
      dobj->set_dobjname (errcode, NULL); // dobj->parent must already be set
    }

  for (unsigned rt_code = 1; rt_code < NUM_ABS_RT_CODES - 1; rt_code++)
    {
      DataObject* dobj = createDataObject ();
      dobj->parent = d_unknown;
      dobj->set_dobjname (PTXT (ABS_RT_CODES[rt_code]), NULL); // dobj->parent must already be set
    }
}

void
DbeSession::reset_data ()
{
  for (long i = 0, sz = VecSize (idxobjs); i < sz; ++i)
    if (idxobjs->get (i))
      idxobjs->get (i)->reset ();
}

void
DbeSession::reset ()
{
  loadObjMap->reset ();
  DbeView *dbev;
  int index;

  Vec_loop (DbeView*, views, index, dbev)
  {
    dbev->reset ();
  }

  destroy_map (DbeFile *, dbeFiles);
  destroy_map (DbeJarFile *, dbeJarFiles);
  exps->destroy ();
  lobjs->reset ();      // all LoadObjects belong to objs
  dobjs->destroy ();    // deletes d_unknown and d_total as well
  objs->destroy ();
  comp_lobjs->clear ();
  comp_dbelines->clear ();
  comp_sources->clear ();
  sourcesMap->clear ();
  sources->reset ();

  // Delete the data object name hash table.
  for (int i = 0; i < HTableSize; i++)
    {
      List *list = dnameHTable[i];
      while (list)
	{
	  List *tmp = list;
	  list = list->next;
	  delete tmp;
	}
    }
  delete[] dnameHTable;

  // IndexObect definitions remain, objects themselves may go
  for (int i = 0; i < idxobjs->size (); ++i)
    {
      HashMap<uint64_t, Histable*> *v = idxobjs->fetch (i);
      if (v != NULL)
	{
	  v->values ()->destroy ();
	  v->clear ();
	}
    }
  init ();
}

Vector<SourceFile*> *
DbeSession::get_sources ()
{
  return sources;
}

DbeFile *
DbeSession::getDbeFile (char *filename, int filetype)
{
  Dprintf (DEBUG_DBE_FILE, NTXT ("DbeSession::getDbeFile  filetype=0x%x %s\n"), filetype, filename);
  if (strncmp (filename, NTXT ("./"), 2) == 0)
    filename += 2;
  DbeFile *dbeFile = dbeFiles->get (filename);
  if (dbeFile == NULL)
    {
      dbeFile = new DbeFile (filename);
      dbeFiles->put (filename, dbeFile);
    }
  dbeFile->filetype |= filetype;
  return dbeFile;
}

LoadObject *
DbeSession::get_Total_LoadObject ()
{
  if (lo_total == NULL)
    {
      lo_total = createLoadObject (NTXT ("<Total>"));
      lo_total->dbeFile->filetype |= DbeFile::F_FICTION;
    }
  return lo_total;
}

Function *
DbeSession::get_Total_Function ()
{
  if (f_total == NULL)
    {
      f_total = createFunction ();
      f_total->flags |= FUNC_FLAG_SIMULATED | FUNC_FLAG_NO_OFFSET;
      f_total->set_name (NTXT ("<Total>"));
      Module *mod = get_Total_LoadObject ()->noname;
      f_total->module = mod;
      mod->functions->append (f_total);
    }
  return f_total;
}

LoadObject *
DbeSession::get_Unknown_LoadObject ()
{
  if (lo_unknown == NULL)
    {
      lo_unknown = createLoadObject (GTXT ("<Unknown>"));
      lo_unknown->type = LoadObject::SEG_TEXT; // makes it expandable
      lo_unknown->dbeFile->filetype |= DbeFile::F_FICTION;

      // force creation of the <Unknown> function
      (void) get_Unknown_Function ();
    }
  return lo_unknown;
}

SourceFile *
DbeSession::get_Unknown_Source ()
{
  if (sf_unknown == NULL)
    {
      sf_unknown = createSourceFile (localized_SP_UNKNOWN_NAME);
      sf_unknown->dbeFile->filetype |= DbeFile::F_FICTION;
      sf_unknown->flags |= SOURCE_FLAG_UNKNOWN;
    }
  return sf_unknown;
}

Function *
DbeSession::get_Unknown_Function ()
{
  if (f_unknown == NULL)
    {
      f_unknown = createFunction ();
      f_unknown->flags |= FUNC_FLAG_SIMULATED;
      f_unknown->set_name (GTXT ("<Unknown>"));
      Module *mod = get_Unknown_LoadObject ()->noname;
      f_unknown->module = mod;
      mod->functions->append (f_unknown);
    }
  return f_unknown;
}

// LIBRARY_VISIBILITY

Function *
DbeSession::create_hide_function (LoadObject *lo)
{
  Function *h_function = createFunction ();
  h_function->set_name (lo->get_name ());
  h_function->module = lo->noname;
  h_function->isHideFunc = true;
  lo->noname->functions->append (h_function);
  return h_function;
}

Function *
DbeSession::get_JUnknown_Function ()
{
  if (j_unknown == NULL)
    {
      j_unknown = createFunction ();
      j_unknown->flags |= FUNC_FLAG_SIMULATED;
      j_unknown->set_name (GTXT ("<no Java callstack recorded>"));
      Module *mod = get_Unknown_LoadObject ()->noname;
      j_unknown->module = mod;
      mod->functions->append (j_unknown);
    }
  return j_unknown;
}

Function *
DbeSession::get_jvm_Function ()
{
  if (f_jvm == NULL)
    {
      f_jvm = createFunction ();
      f_jvm->flags |= FUNC_FLAG_SIMULATED | FUNC_FLAG_NO_OFFSET;
      f_jvm->set_name (GTXT ("<JVM-System>"));

      // Find the JVM LoadObject
      LoadObject *jvm = get_Unknown_LoadObject ();
      for (int i = 0; i < lobjs->size (); ++i)
	{
	  LoadObject *lo = lobjs->fetch (i);
	  if (lo->flags & SEG_FLAG_JVM)
	    {
	      jvm = lo;
	      break;
	    }
	}
      Module *mod = jvm->noname;
      f_jvm->module = mod;
      mod->functions->append (f_jvm);
      // XXXX is it required? no consistency among all special functions
      // jvm->functions->append( f_jvm );
    }
  return f_jvm;
}

Function *
DbeSession::getSpecialFunction (SpecialFunction kind)
{
  if (kind < 0 || kind >= LastSpecialFunction)
    return NULL;

  Function *func = f_special->fetch (kind);
  if (func == NULL)
    {
      char *fname;
      switch (kind)
	{
	case TruncatedStackFunc:
	  fname = GTXT ("<Truncated-stack>");
	  break;
	case FailedUnwindFunc:
	  fname = GTXT ("<Stack-unwind-failed>");
	  break;
	default:
	  return NULL;
	}
      func = createFunction ();
      func->flags |= FUNC_FLAG_SIMULATED | FUNC_FLAG_NO_OFFSET;
      Module *mod = get_Total_LoadObject ()->noname;
      func->module = mod;
      mod->functions->append (func);
      func->set_name (fname);
      f_special->store (kind, func);
    }
  return func;
}

LoadObject *
DbeSession::get_OMP_LoadObject ()
{
  if (lo_omp == NULL)
    {
      for (int i = 0, sz = lobjs->size (); i < sz; i++)
	{
	  LoadObject *lo = lobjs->fetch (i);
	  if (lo->flags & SEG_FLAG_OMP)
	    {
	      lo_omp = lo;
	      return lo_omp;
	    }
	}
      lo_omp = createLoadObject (GTXT ("<OMP>"));
      lo_omp->type = LoadObject::SEG_TEXT;
      lo_omp->dbeFile->filetype |= DbeFile::F_FICTION;
    }
  return lo_omp;
}

Function *
DbeSession::get_OMP_Function (int n)
{
  if (n < 0 || n >= OMP_LAST_STATE)
    return NULL;

  Function *func = omp_functions->fetch (n);
  if (func == NULL)
    {
      char *fname;
      switch (n)
	{
	case OMP_OVHD_STATE:
	  fname = GTXT ("<OMP-overhead>");
	  break;
	case OMP_IDLE_STATE:
	  fname = GTXT ("<OMP-idle>");
	  break;
	case OMP_RDUC_STATE:
	  fname = GTXT ("<OMP-reduction>");
	  break;
	case OMP_IBAR_STATE:
	  fname = GTXT ("<OMP-implicit_barrier>");
	  break;
	case OMP_EBAR_STATE:
	  fname = GTXT ("<OMP-explicit_barrier>");
	  break;
	case OMP_LKWT_STATE:
	  fname = GTXT ("<OMP-lock_wait>");
	  break;
	case OMP_CTWT_STATE:
	  fname = GTXT ("<OMP-critical_section_wait>");
	  break;
	case OMP_ODWT_STATE:
	  fname = GTXT ("<OMP-ordered_section_wait>");
	  break;
	case OMP_ATWT_STATE:
	  fname = GTXT ("<OMP-atomic_wait>");
	  break;
	default:
	  return NULL;
	}
      func = createFunction ();
      func->flags |= FUNC_FLAG_SIMULATED | FUNC_FLAG_NO_OFFSET;
      func->set_name (fname);

      LoadObject *omp = get_OMP_LoadObject ();
      func->module = omp->noname;
      omp->noname->functions->append (func);
      omp->functions->append (func);
      omp_functions->store (n, func);
    }
  return func;
}

// Divide the original createExperiment() into two steps
// In part1, we just create the data structure, in part2, if
// we decide to keep the experiment around, add it to various
// lists in DbeSession
Experiment *
DbeSession::createExperimentPart1 ()
{
  Experiment *exp = new Experiment ();
  return exp;
}

void
DbeSession::createExperimentPart2 (Experiment *exp)
{
  int ind = expGroups->size ();
  if (ind > 0)
    {
      ExpGroup *gr = expGroups->fetch (ind - 1);
      exp->groupId = gr->groupId;
      gr->append (exp);
    }
  exp->setExpIdx (exps->size ());
  exp->setUserExpId (++user_exp_id_counter);
  exps->append (exp);
}

Experiment *
DbeSession::createExperiment ()
{
  Experiment *exp = new Experiment ();
  append (exp);
  return exp;
}

void
DbeSession::append (Experiment *exp)
{
  exp->setExpIdx (exps->size ());
  exp->setUserExpId (++user_exp_id_counter);
  exps->append (exp);
  if (exp->founder_exp)
    {
      if (exp->founder_exp->children_exps == NULL)
	exp->founder_exp->children_exps = new Vector<Experiment *>;
      exp->founder_exp->children_exps->append (exp);
      if (exp->founder_exp->groupId > 0)
	{
	  exp->groupId = exp->founder_exp->groupId;
	  expGroups->get (exp->groupId - 1)->append (exp);
	}
    }
  if (exp->groupId == 0)
    {
      long ind = VecSize (expGroups);
      if (ind > 0)
	{
	  ExpGroup *gr = expGroups->get (ind - 1);
	  exp->groupId = gr->groupId;
	  gr->append (exp);
	}
    }
}

void
DbeSession::append (Hwcentry *h)
{
  if (hwcentries == NULL)
    hwcentries = new Vector<Hwcentry*>;
  hwcentries->append (h);
}

int
DbeSession::ngoodexps ()
{
  return exps->size ();
}

int
DbeSession::createView (int index, int cloneindex)
{
  // ensure that there is no view with that index
  DbeView *dbev = getView (index);
  if (dbev != NULL)
    abort ();

  // find the view to be cloned
  dbev = getView (cloneindex);
  DbeView *newview;
  if (dbev == NULL)
    newview = new DbeView (theApplication, settings, index);
  else
    newview = new DbeView (dbev, index);
  views->append (newview);
  return index;
}

DbeView *
DbeSession::getView (int index)
{
  int i;
  DbeView *dbev;
  Vec_loop (DbeView*, views, i, dbev)
  {
    if (dbev->vindex == index)
      return dbev;
  }
  return NULL;
}

void
DbeSession::dropView (int index)
{
  int i;
  DbeView *dbev;

  Vec_loop (DbeView*, views, i, dbev)
  {
    if (dbev->vindex == index)
      {
	views->remove (i);
	delete dbev;
	return;
      }
  }
  // view not found; ignore for now
}

Vector<char*> *
DbeSession::get_group_or_expt (char *path)
{
  Vector<char*> *exp_list = new Vector<char*>;
  FILE *fptr;
  char *new_path, buf[MAXPATHLEN], name[MAXPATHLEN];

  fptr = fopen (path, NTXT ("r"));
  if (!fptr || !fgets (buf, (int) sizeof (buf), fptr)
      || strncmp (buf, SP_GROUP_HEADER, strlen (SP_GROUP_HEADER)))
    {
      // it's not an experiment group
      new_path = dbe_strdup (path);
      new_path = canonical_path (new_path);
      exp_list->append (new_path);
    }
  else
    {
      // it is an experiment group, read the list to get them all
      while (fgets (buf, (int) sizeof (buf), fptr))
	{
	  if ((*buf != '#') && (sscanf (buf, NTXT ("%s"), name) == 1))
	    {
	      new_path = dbe_strdup (name);
	      new_path = canonical_path (new_path);
	      exp_list->append (new_path);
	    }
	}
    }
  if (fptr)
    fclose (fptr);
  return exp_list;
}

#define GET_INT_VAL(v, s, len) \
    for (v = len = 0; isdigit(*s); s++, len++) { v = v * 10 + (*s -'0'); }

static int
dir_name_cmp (const void *a, const void *b)
{
  char *s1 = *((char **) a);
  char *s2 = *((char **) b);
  while (*s1)
    {
      if (isdigit (*s1) && isdigit (*s2))
	{
	  int v1, v2, len1, len2;
	  GET_INT_VAL (v1, s1, len1);
	  GET_INT_VAL (v2, s2, len2);
	  if (v1 != v2)
	    return v1 - v2;
	  if (len1 != len2)
	    return len2 - len1;
	  continue;
	}
      if (*s1 != *s2)
	break;
      s1++;
      s2++;
    }
  return *s1 - *s2;
}

static int
read_experiment_data_in_parallel (void *arg)
{
  exp_ctx *ctx = (exp_ctx *) arg;
  Experiment *dexp = ctx->exp;
  bool read_ahead = ctx->read_ahead;
  dexp->read_experiment_data (read_ahead);
  free (ctx);
  return 0;
}

void
DbeSession::open_experiment (Experiment *exp, char *path)
{
  exp->open (path);
  if (exp->get_status () != Experiment::FAILURE)
    exp->read_experiment_data (false);
  exp->open_epilogue ();

  // Update all DbeViews
  for (int i = 0, sz = views->size (); i < sz; i++)
    {
      DbeView *dbev = views->fetch (i);
      dbev->add_experiment (exp->getExpIdx (), true);
    }

  if (exp->get_status () == Experiment::FAILURE)
    {
      check_tab_avail ();
      return;
    }

  char *discard_tiny = getenv (NTXT ("SP_ANALYZER_DISCARD_TINY_EXPERIMENTS"));
  int user_specified_tiny_threshold = DEFAULT_TINY_THRESHOLD; // in milliseconds
  if (discard_tiny != NULL)
    {
      user_specified_tiny_threshold = (atoi (discard_tiny));
      if (user_specified_tiny_threshold < 0)
	user_specified_tiny_threshold = DEFAULT_TINY_THRESHOLD;
    }

  // Open descendant experiments
  DIR *exp_dir = opendir (path);
  if (exp_dir == NULL)
    {
      check_tab_avail ();
      return;
    }

  Vector<char*> *exp_names = new Vector<char*>();
  struct dirent *entry = NULL;
  while ((entry = readdir (exp_dir)) != NULL)
    {
      if (entry->d_name[0] != '_')
	continue;
      size_t len = strlen (entry->d_name);
      if (len < 3 || strcmp (entry->d_name + len - 3, NTXT (".er")) != 0)
	continue;
      exp_names->append (dbe_strdup (entry->d_name));
    }
  closedir (exp_dir);
  exp_names->sort (dir_name_cmp);
  Experiment **t_exp_list = new Experiment *[exp_names->size ()];
  for (int j = 0, jsz = exp_names->size (); j < jsz; j++)
    {
      t_exp_list[j] = NULL;

      char *lineage_name = exp_names->fetch (j);
      dbe_stat_t sbuf;
      char *dpath = dbe_sprintf (NTXT ("%s/%s"), path, lineage_name);

      // look for experiments with no profile collected
      if (user_specified_tiny_threshold == DEFAULT_TINY_THRESHOLD)
	{
	  char *frinfoname = dbe_sprintf (NTXT ("%s/%s"), dpath, "data." SP_FRINFO_FILE);
	  int st = dbe_stat (frinfoname, &sbuf);
	  free (frinfoname);
	  if (st == 0)
	    {
	      // if no profile/trace data do not process this experiment any further
	      if (sbuf.st_size == 0)
		{
		  free (dpath);
		  continue;
		}
	    }
	}
      else
	{ // check if dpath is a directory
	  if (dbe_stat (dpath, &sbuf) != 0)
	    {
	      free (dpath);
	      continue;
	    }
	  else if (!S_ISDIR (sbuf.st_mode))
	    {
	      free (dpath);
	      continue;
	    }
	}
      size_t lineage_name_len = strlen (lineage_name);
      lineage_name[lineage_name_len - 3] = 0; /* remove .er */
      Experiment *dexp = new Experiment ();
      dexp->founder_exp = exp;
      if (user_specified_tiny_threshold > DEFAULT_TINY_THRESHOLD)
	{
	  dexp->setTinyThreshold (user_specified_tiny_threshold);
	  dexp->open (dpath);
	  if (dexp->isDiscardedTinyExperiment ())
	    {
	      delete dexp;
	      free (dpath);
	      continue;
	    }
	}
      else
	dexp->open (dpath);
      append (dexp);
      t_exp_list[j] = dexp;
      dexp->set_clock (exp->clock);

      // DbeView add_experiment() is split into two parts
      // add_subexperiment() is called repeeatedly for
      // all sub_experiments, later add_experiment_epilogue() finishes up the task
      for (int i = 0, sz = views->size (); i < sz; i++)
	{
	  DbeView *dbev = views->fetch (i);
	  bool enabled = settings->check_en_desc (lineage_name, dexp->utargname);
	  dbev->add_subexperiment (dexp->getExpIdx (), enabled);
	}
      free (dpath);
    }

  for (int i = 0, sz = views->size (); i < sz; i++)
    {
      DbeView *dbev = views->fetch (i);
      dbev->add_experiment_epilogue ();
    }

  DbeThreadPool * threadPool = new DbeThreadPool (-1);
  for (int j = 0, jsz = exp_names->size (); j < jsz; j++)
    {
      if (t_exp_list[j] == NULL) continue;
      Experiment *dexp = t_exp_list[j];
      exp_ctx *new_ctx = (exp_ctx*) xmalloc (sizeof (exp_ctx));
      new_ctx->path = NULL;
      new_ctx->exp = dexp;
      new_ctx->ds = this;
      new_ctx->read_ahead = true;
      DbeQueue *q = new DbeQueue (read_experiment_data_in_parallel, new_ctx);
      threadPool->put_queue (q);
    }
  threadPool->wait_queues ();
  delete threadPool;

  for (long j = 0, jsz = exp_names->size (); j < jsz; j++)
    {
      if (t_exp_list[j] == NULL) continue;
      Experiment *dexp = t_exp_list[j];
      dexp->open_epilogue ();
    }
  exp_names->destroy ();
  delete[] t_exp_list;
  delete exp_names;

  // update setting for leaklist and dataspace
  check_tab_avail ();
}

void
DbeSession::append_mesgs (StringBuilder *sb, char *path, Experiment *exp)
{
  if (exp->fetch_errors () != NULL)
    {
      // yes, there were errors
      char *ststr = pr_mesgs (exp->fetch_errors (), NTXT (""), NTXT (""));
      sb->append (path);
      sb->append (NTXT (": "));
      sb->append (ststr);
      free (ststr);
    }

  Emsg *m = exp->fetch_warnings ();
  if (m != NULL)
    {
      sb->append (path);
      sb->append (NTXT (": "));
      if (!is_interactive ())
	sb->append (GTXT ("Experiment has warnings, see header for details\n"));
      else
	sb->append (GTXT ("Experiment has warnings, see experiment panel for details\n"));
    }

  // Check for descendant experiments that are not loaded
  int num_desc = VecSize (exp->children_exps);
  if ((num_desc > 0) && !settings->check_en_desc (NULL, NULL))
    {
      char *s;
      if (!is_interactive ())
	s = dbe_sprintf (GTXT ("Has %d descendant(s), use commands controlling selection to load descendant data\n"), num_desc);
      else
	s = dbe_sprintf (GTXT ("Has %d descendant(s), use filter panel to load descendant data\n"), num_desc);
      sb->append (path);
      sb->append (NTXT (": "));
      sb->append (s);
      free (s);
    }
}

Experiment *
DbeSession::get_exp (int exp_ind)
{
  if (exp_ind < 0 || exp_ind >= exps->size ())
    return NULL;
  Experiment *exp = exps->fetch (exp_ind);
  exp->setExpIdx (exp_ind);
  return exp;
}

Vector<Vector<char*>*> *
DbeSession::getExperimensGroups ()
{
  if (dbeSession->expGroups == NULL || dbeSession->expGroups->size () == 0)
    return NULL;
  bool compare_mode = expGroups->size () > 1;
  Vector<Vector<char*>*> *groups = new Vector<Vector<char*>*> (
					 compare_mode ? expGroups->size () : 1);
  for (int i = 0; i < expGroups->size (); i++)
    {
      ExpGroup *grp = expGroups->fetch (i);
      Vector<Experiment*> *founders = grp->get_founders ();
      if (founders && founders->size () != 0)
	{
	  Vector<char *> *names = new Vector<char*> (founders->size ());
	  for (int j = 0; j < founders->size (); j++)
	    {
	      Experiment *exp = founders->fetch (j);
	      names->append (dbe_strdup (exp->get_expt_name ()));
	    }
	  if (compare_mode || groups->size () == 0)
	    groups->append (names);
	  else
	    groups->fetch (0)->addAll (names);
	}
      delete founders;
    }
  return groups;
}

char *
DbeSession::setExperimentsGroups (Vector<Vector<char*>*> *groups)
{
  StringBuilder sb;
  for (int i = 0; i < groups->size (); i++)
    {
      Vector<char *> *names = groups->fetch (i);
      ExpGroup *grp;
      if (names->size () == 1)
	grp = new ExpGroup (names->fetch (0));
      else
	{
	  char *nm = dbe_sprintf (GTXT ("Group %d"), i + 1);
	  grp = new ExpGroup (nm);
	  free (nm);
	}
      expGroups->append (grp);
      grp->groupId = expGroups->size ();

      for (int j = 0; j < names->size (); j++)
	{
	  char *path = names->fetch (j);
	  size_t len = strlen (path);
	  if ((len > 4) && !strcmp (path + len - 4, NTXT (".erg")))
	    {
	      Vector<char*> *lst = get_group_or_expt (path);
	      for (int j1 = 0; j1 < lst->size (); j1++)
		{
		  Experiment *exp = new Experiment ();
		  append (exp);
		  open_experiment (exp, lst->get (j1));
		  if (exp->get_status () == Experiment::FAILURE)
		    append_mesgs (&sb, path, exp);
		}
	      lst->destroy ();
	      delete lst;
	    }
	  else
	    {
	      Experiment *exp = new Experiment ();
	      append (exp);
	      open_experiment (exp, path);
	      if (exp->get_status () == Experiment::FAILURE)
		append_mesgs (&sb, path, exp);
	    }
	}
    }

  for (int i = 0, sz = views->size (); i < sz; i++)
    {
      DbeView *dbev = views->fetch (i);
      dbev->update_advanced_filter ();
      int cmp = dbev->get_settings ()->get_compare_mode ();
      dbev->set_compare_mode (CMP_DISABLE);
      dbev->set_compare_mode (cmp);
    }
  return sb.length () == 0 ? NULL : sb.toString ();
}

char *
DbeSession::drop_experiment (int exp_ind)
{
  DbeView *dbev;
  int index;
  Experiment *exp2;

  status_ompavail = -1;
  Experiment *exp = exps->fetch (exp_ind);

  // If this is a sub experiment, don't do it
  if (exp->founder_exp != NULL)     // this is a sub experiment; don't do it
    return (dbe_strdup (GTXT ("Can not drop subexperiments")));

  if (VecSize (exp->children_exps) > 0)
    for (;;)
      {
	// search the list of experiments to find all that have this one as founder
	bool found = false;
	Vec_loop (Experiment*, exps, index, exp2)
	{
	  if (exp2->founder_exp == exp)
	    {
	      exp2->founder_exp = NULL;
	      drop_experiment (index);
	      found = true;
	      break;
	    }
	}
	if (found == false)
	  break;
      }

  // then proceed to finish the drop
  Vec_loop (DbeView*, views, index, dbev)
  {
    dbev->drop_experiment (exp_ind);
  }

  int old_cnt = expGroups->size ();
  for (int i = 0; i < old_cnt; i++)
    {
      ExpGroup *gr = expGroups->fetch (i);
      if (gr->groupId == exp->groupId)
	{
	  gr->drop_experiment (exp);
	  if ((gr->founder == NULL) && (gr->exps->size () == 0))
	    {
	      delete gr;
	      expGroups->remove (i);
	    }
	  break;
	}
    }
  delete exps->remove (exp_ind);
  if (old_cnt != expGroups->size ())
    {
      for (int i = 0, sz = expGroups->size (); i < sz; i++)
	{
	  ExpGroup *gr = expGroups->fetch (i);
	  gr->groupId = i + 1;
	  Vector<Experiment*> *expList = gr->exps;
	  for (int i1 = 0, sz1 = expList->size (); i1 < sz1; i1++)
	    expList->fetch (i1)->groupId = gr->groupId;
	}
      for (int i = 0, sz = views->size (); i < sz; i++)
	{
	  dbev = views->fetch (i);
	  int cmp = dbev->get_compare_mode ();
	  dbev->set_compare_mode (CMP_DISABLE);
	  dbev->set_compare_mode (cmp);
	}
    }
  check_tab_avail ();   // update tab availability
  return NULL;
}

int
DbeSession::find_experiment (char *path)
{
  Experiment *exp;
  int index;
  Vec_loop (Experiment*, exps, index, exp)
  {
    if (strcmp (exp->get_expt_name (), path) == 0)
      return exp->getExpIdx ();
  }
  return -1;
}

LoadObject *
DbeSession::createLoadObject (const char *nm, int64_t cksum)
{
  return loadObjMap->sync_create_item (nm, cksum);
}

LoadObject *
DbeSession::createLoadObject (const char *nm, const char *runTimePath, DbeFile *df)
{
  return loadObjMap->sync_create_item (nm, runTimePath, df);
}

void
DbeSession::append (LoadObject *lobj)
{
  Histable *obj = lobj; // workaround for a C++ problem
  objs->append (obj);
  lobj->id = objs->size () - 1;
  lobjs->append (lobj);
  lobj->seg_idx = lobjs->size () - 1;
  char *loname = lobj->get_pathname ();
  dbeFiles->put (loname, lobj->dbeFile);
}

DbeJarFile *
DbeSession::get_JarFile (const char *name)
{
  DbeJarFile *jf = dbeJarFiles->get (name);
  if (jf == NULL)
    {
      jf = new DbeJarFile (name);
      dbeJarFiles->put (name, jf);
    }
  return jf;
}

Module *
DbeSession::createModule (LoadObject *lo, const char *nm)
{
  Module *mod = new Module ();
  Histable *obj = mod; // workaround for a C++ problem
  objs->append (obj);
  mod->id = objs->size () - 1;
  mod->loadobject = lo;
  mod->set_name (dbe_strdup (nm ? nm : localized_SP_UNKNOWN_NAME));
  lo->seg_modules->append (mod);
  return mod;
}

Module *
DbeSession::createUnknownModule (LoadObject *lo)
{
  Module *mod = createModule (lo, localized_SP_UNKNOWN_NAME);
  mod->flags |= MOD_FLAG_UNKNOWN;
  mod->set_file_name (dbe_strdup (localized_SP_UNKNOWN_NAME));
  return mod;
}

SourceFile *
DbeSession::createSourceFile (const char *_path)
{
  char *path = (char *) _path;
  if (strncmp (path, NTXT ("./"), 2) == 0)
    path += 2;
  SourceFile *source = sourcesMap->get (path);
  if (source == NULL)
    {
      source = new SourceFile (path);
      (void) sourcesMap->put (path, source);
      append (source);
    }
  return source;
}

Function *
DbeSession::createFunction ()
{
  Function *func = new Function (objs->size ());
  Histable *obj = func; // workaround for a C++ problem
  objs->append (obj);
  return func;
}

JMethod *
DbeSession::createJMethod ()
{
  JMethod *jmthd = new JMethod (objs->size ());
  Histable *obj = jmthd; // workaround for a C++ problem
  objs->append (obj);
  return jmthd;
}

Module *
DbeSession::createClassFile (char *className)
{
  ClassFile *cls = new ClassFile ();
  cls->set_name (className);
  char *clpath = cls->get_java_file_name (className, true);
  cls->dbeFile = getDbeFile (clpath, DbeFile::F_JAVACLASS);
  free (clpath);
  Histable *obj = cls; // workaround for a C++ problem
  objs->append (obj);
  cls->id = objs->size () - 1;
  return cls;
}

Histable *
DbeSession::createHistObject (Histable::Type type)
{
  switch (type)
    {
    case Histable::DOBJECT:
      {
	DataObject *dataobj = new DataObject ();
	dobjs->append (dataobj);
	dataobj->id = dobjs->size () - 1;
	return dataobj;
      }
    default:
      assert (0);
    }
  return NULL;
}

DataObject *
DbeSession::createDataObject ()
{
  DataObject *dataobj = new DataObject ();
  dobjs->append (dataobj);
  dataobj->id = dobjs->size () - 1;
  return dataobj;
}

DataObject *
DbeSession::createDataObject (DataObject *dobj, DataObject *parent)
{
  DataObject *dataobj = new DataObject ();
  dataobj->size = dobj->size;
  dataobj->offset = dobj->offset;
  dataobj->parent = parent;
  dataobj->set_dobjname (dobj->get_typename (), dobj->get_instname ());
  dobjs->append (dataobj);
  dataobj->id = dobjs->size () - 1;
  return dataobj;
}

DataObject *
DbeSession::createMasterDataObject (DataObject *dobj)
{
  DataObject *parent = NULL;
  if (dobj->parent)
    { // define master parent first
      parent = find_dobj_master (dobj->parent);
      if (!parent)
	{ // clone master from this dataobject parent
	  parent = createDataObject (dobj->parent);
	  parent->scope = NULL; // master is scope-less
	  Dprintf (DEBUG_DATAOBJ,
		   "Master DataObject(%llu) cloned from (%llu) %s\n",
		   (ull_t) parent->id, (ull_t) dobj->parent->id,
		   dobj->parent->get_name ());
	  // clone master DataObject elements
	  Vector<DataObject*> *delem = get_dobj_elements (dobj->parent);
	  int element_index = 0;
	  DataObject *element = NULL;
	  Vec_loop (DataObject*, delem, element_index, element)
	  {
	    DataObject *master_element = createDataObject (element, parent);
	    master_element->scope = NULL; // master is scope-less
	    Dprintf (DEBUG_DATAOBJ,
		     "Member DataObject(%llu) cloned from (%llu) %s\n",
		     (ull_t) master_element->id, (ull_t) element->id,
		     element->get_name ());
	  }
	}
      else
	Dprintf (DEBUG_DATAOBJ, "Master DataObject(%llu) clone found (%llu) %s\n",
		 (ull_t) parent->id, (ull_t) dobj->parent->id,
		 dobj->parent->get_name ());
    }

  DataObject *master = find_dobj_master (dobj);
  if (!master)
    { // clone master from this dataobject
      master = createDataObject (dobj, parent);
      master->scope = NULL; // master is scope-less
      Dprintf (DEBUG_DATAOBJ, "Master DataObject(%llu) cloned from (%llu) %s\n",
	       (ull_t) master->id, (ull_t) dobj->id, dobj->get_name ());
    }
  else
    Dprintf (DEBUG_DATAOBJ, "Master DataObject(%llu) clone found (%llu) %s\n",
	     (ull_t) master->id, (ull_t) dobj->id, dobj->get_name ());
  return master;
}

void
DbeSession::insert_metric (BaseMetric *mtr, Vector<BaseMetric*> *mlist)
{
  if ((mtr->get_flavors () & Metric::STATIC) == 0)
    {
      // insert in front of the first STATIC
      for (int i = 0, mlist_sz = mlist->size (); i < mlist_sz; i++)
	{
	  BaseMetric *m = mlist->fetch (i);
	  if (m->get_flavors () & Metric::STATIC)
	    {
	      mlist->insert (i, mtr);
	      return;
	    }
	}
    }
  mlist->append (mtr);
}

BaseMetricTreeNode*
DbeSession::get_reg_metrics_tree ()
{
  if (reg_metrics_tree == NULL)
    // Can't init earlier because BaseMetric() requires DbeSession::ql_parse
    reg_metrics_tree = new BaseMetricTreeNode ();
  return reg_metrics_tree;
}

void
DbeSession::update_metric_tree (BaseMetric *m)
{
  get_reg_metrics_tree ()->register_metric (m);
}

BaseMetric *
DbeSession::register_metric_expr (BaseMetric::Type type, char *cmd, char *expr_spec)
{
  BaseMetric *m = find_metric (type, cmd, expr_spec);
  if (m)
    return m;
  BaseMetric *bm = find_metric (type, cmd, NULL); // clone this version
  m = new BaseMetric (*bm);
  m->set_expr_spec (expr_spec);
  insert_metric (m, reg_metrics);
  return m;
}

BaseMetric *
DbeSession::register_metric (BaseMetric::Type type)
{
  BaseMetric *m = find_metric (type, NULL, NULL);
  if (m)
    return m;
  m = new BaseMetric (type);
  insert_metric (m, reg_metrics);
  update_metric_tree (m);
  return m;
}

BaseMetric *
DbeSession::register_metric (Hwcentry *ctr, const char* aux, const char* username)
{
  BaseMetric *m = find_metric (BaseMetric::HWCNTR, aux, NULL);
  if (m)
    // That may be a problem when metrics aren't an exact match.
    // For example, memoryspace is disabled in one experiment and not in another.
    return m;
  if (ctr->timecvt)
    {
      char *time_cmd = dbe_sprintf (NTXT ("t%s"), aux);
      char *time_username = dbe_sprintf (GTXT ("%s Time"),
				       ctr->metric ? ctr->metric :
				       (ctr->name ? ctr->name : ctr->int_name));
      BaseMetric *m1;
      if (ipc_mode)
	{
	  // Two visible metrics are presented in GUI
	  m1 = new BaseMetric (ctr, aux, time_cmd, time_username, VAL_TIMEVAL);
	  insert_metric (m1, reg_metrics);
	  update_metric_tree (m1);
	  m = new BaseMetric (ctr, aux, username, VAL_VALUE, m1);
	}
      else
	{
	  // Only one visible metric is presented in er_print
	  m1 = new BaseMetric (ctr, aux, time_cmd, time_username, VAL_TIMEVAL | VAL_INTERNAL);
	  insert_metric (m1, reg_metrics);
	  m = new BaseMetric (ctr, aux, username, VAL_TIMEVAL | VAL_VALUE, m1);
	}
      free (time_cmd);
      free (time_username);
    }
  else
    m = new BaseMetric (ctr, aux, username, VAL_VALUE);
  insert_metric (m, reg_metrics);
  update_metric_tree (m);
  return m;
}

BaseMetric *
DbeSession::register_metric (char *name, char *username, char *_def)
{
  BaseMetric *m = find_metric (BaseMetric::DERIVED, name, NULL);
  if (m)
    return m;
  Definition *p = Definition::add_definition (_def);
  if (p == NULL)
    return NULL;
  m = new BaseMetric (name, username, p);
  insert_metric (m, reg_metrics);
  update_metric_tree (m);
  return m;
}

void
DbeSession::drop_metric (BaseMetric *mtr)
{
  Countable *cnt;
  int index;

  Vec_loop (Countable*, metrics, index, cnt)
  {
    if (mtr == (BaseMetric *) cnt->item)
      {
	cnt->ref_count--;
	if (cnt->ref_count == 0)
	  {
	    // Remove this metric from all views
	    DbeView *dbev;
	    int index2;
	    Vec_loop (DbeView*, views, index2, dbev)
	    {
	      dbev->reset_metrics ();
	    }
	    delete metrics->remove (index);
	    delete mtr;
	    return;
	  }
      }
  }
}

BaseMetric *
DbeSession::find_metric (BaseMetric::Type type, const char *cmd, const char *expr_spec)
{
  for (int i = 0, sz = reg_metrics->size (); i < sz; i++)
    {
      BaseMetric *bm = reg_metrics->fetch (i);
      if (bm->get_type () == type && dbe_strcmp (bm->get_expr_spec (), expr_spec) == 0)
	{
	  if ((type == BaseMetric::DERIVED || type == BaseMetric::HWCNTR)
	       && dbe_strcmp (bm->get_cmd (), cmd) != 0)
	    continue;
	  return bm;
	}
    }
  return NULL;
}

BaseMetric *
DbeSession::find_base_reg_metric (char * mcmd)
{
  for (int i = 0, sz = reg_metrics->size (); i < sz; i++)
    {
      BaseMetric *bm = reg_metrics->fetch (i);
      if (bm->get_expr_spec () != NULL)
	continue; // skip compare metrics
      if (dbe_strcmp (bm->get_cmd (), mcmd) == 0)
	return bm;
    }
  return NULL;
}

Vector<BaseMetric*> *
DbeSession::get_base_reg_metrics ()
{
  Vector<BaseMetric*> *mlist = new Vector<BaseMetric*>;
  Vector<BaseMetric*> *ml = get_all_reg_metrics ();
  for (int i = 0, sz = ml->size (); i < sz; i++)
    {
      BaseMetric *m = ml->fetch (i);
      if (m->get_expr_spec () == NULL)
	mlist->append (m);
    }
  return mlist;
}

void
DbeSession::check_tab_avail ()
{
  DbeView *dbev;
  int index;
  // tell the views to update their tab lists
  Vec_loop (DbeView*, views, index, dbev)
  {
    dbev->get_settings ()->updateTabAvailability ();
  }
}

bool
DbeSession::is_datamode_available ()
{
  Experiment *exp;
  int index;
  Vec_loop (Experiment*, exps, index, exp)
  {
    if (exp->dataspaceavail)
      return true;
  }
  return false;
}

bool
DbeSession::is_leaklist_available ()
{
  Experiment *exp;
  int index;
  Vec_loop (Experiment*, exps, index, exp)
  {
    if (exp->leaklistavail)
      return true;
  }
  return false;
}

bool
DbeSession::is_heapdata_available ()
{
  Experiment *exp;
  int index;
  Vec_loop (Experiment*, exps, index, exp)
  {
    if (exp->heapdataavail)
      return true;
  }
  return false;
}

bool
DbeSession::is_iodata_available ()
{
  Experiment *exp;
  int index;
  Vec_loop (Experiment*, exps, index, exp)
  {
    if (exp->iodataavail)
      return true;
  }
  return false;
}

bool
DbeSession::is_racelist_available ()
{
  Experiment *exp;
  int index;
  Vec_loop (Experiment*, exps, index, exp)
  {
    if (exp->racelistavail)
      return true;
  }
  return false;
}

bool
DbeSession::is_deadlocklist_available ()
{
  Experiment *exp;
  int index;
  Vec_loop (Experiment*, exps, index, exp)
  {
    if (exp->deadlocklistavail)
      return true;
  }
  return false;
}

bool
DbeSession::is_timeline_available ()
{
  Experiment *exp;
  int index;
  Vec_loop (Experiment*, exps, index, exp)
  {
    if (exp->timelineavail)
      return true;
  }
  return false;
}

bool
DbeSession::is_ifreq_available ()
{
  Experiment *exp;
  int index;
  Vec_loop (Experiment*, exps, index, exp)
  {
    if (exp->ifreqavail)
      return true;
  }
  return false;
}

bool
DbeSession::is_omp_available ()
{
  if (status_ompavail == -1)
    {
      status_ompavail = 0;
      for (int i = 0, sz = exps ? exps->size () : 0; i < sz; i++)
	{
	  Experiment *exp = exps->fetch (i);
	  if (exp->ompavail)
	    {
	      status_ompavail = 1;
	      break;
	    }
	}
    }
  return status_ompavail == 1;
}

bool
DbeSession::is_bigendian ()
{
#ifdef WORDS_BIGENDIAN
  return true;
#else
  return false;
#endif

}

bool
DbeSession::has_java ()
{
  int status_has_java = 0;
  for (int i = 0, sz = exps ? exps->size () : 0; i < sz; i++)
    {
      Experiment *exp = exps->fetch (i);
      if (exp->has_java)
	{
	  status_has_java = 1;
	  break;
	}
    }
  return status_has_java == 1;
}

bool
DbeSession::has_ompavail ()
{
  int status_has_ompavail = 0;
  for (int i = 0, sz = exps ? exps->size () : 0; i < sz; i++)
    {
      Experiment *exp = exps->fetch (i);
      if (exp->ompavail)
	{
	  status_has_ompavail = 1;
	  break;
	}
    }
  return status_has_ompavail == 1;
}

int
DbeSession::get_clock (int whichexp)
{
  // XXXX clock frequency should be an attribute of each CPU,
  // XXX  and not a property of the session
  // if whichexp is -1, pick the first exp that has a clock
  // otherwise return the clock from the numbered experiment
  Experiment *exp;
  if (whichexp != -1)
    {
      exp = get_exp (whichexp);
      if (exp != NULL)
	return exp->clock;
      return 0;
    }
  int n = nexps ();
  for (int i = 0; i < n; i++)
    {
      exp = get_exp (i);
      if (exp != NULL && exp->clock != 0)
	return exp->clock;
    }
  return 0;
}

LoadObject *
DbeSession::find_lobj_by_name (const char *lobj_name, int64_t cksum)
{
  return loadObjMap->get (lobj_name, cksum);
}

static unsigned
hash (char *s)
{
  unsigned res = 0;
  for (int i = 0; i < 64 && *s; i++)
    res = res * 13 + *s++;
  return res;
}

// This method is introduced to fix performance
// problems with the data space profiling in the
// current release. A better design is desired.
void
DbeSession::dobj_updateHT (DataObject *dobj)
{
  unsigned index = hash (dobj->get_unannotated_name ()) % HTableSize;
  List *list = new List;
  list->val = (void*) dobj;
  list->next = dnameHTable[index];
  dnameHTable[index] = list;
}

DataObject *
DbeSession::find_dobj_by_name (char *dobj_name)
{
  unsigned index = hash (dobj_name) % HTableSize;
  List *list = dnameHTable[index];
  for (; list; list = list->next)
    {
      DataObject *d = (DataObject*) list->val;
      if (strcmp (d->get_unannotated_name (), dobj_name) == 0)
	return d;
    }
  return (DataObject *) NULL;
}

DataObject *
DbeSession::find_dobj_match (DataObject *dobj)
{
  char *dobj_name = dobj->get_unannotated_name ();
  unsigned index = hash (dobj_name) % HTableSize;
  List *list = dnameHTable[index];
  for (; list; list = list->next)
    {
      DataObject *d = (DataObject*) list->val;
      if (strcmp (d->get_unannotated_name (), dobj_name) == 0
	  && d->size == dobj->size && d->offset == dobj->offset
	  && d->scope == dobj->scope)
	return d;
    }
  return (DataObject *) NULL;
}

DataObject *
DbeSession::find_dobj_master (DataObject *dobj)
{
  char *dobj_name = dobj->get_unannotated_name ();
  unsigned index = hash (dobj_name) % HTableSize;
  List *list = dnameHTable[index];
  for (; list; list = list->next)
    {
      DataObject *d = (DataObject*) list->val;
      // XXXX should parent also match?
      if (strcmp (d->get_unannotated_name (), dobj_name) == 0
	  && d->size == dobj->size && d->offset == dobj->offset
	  && d->master == NULL && d->scope == NULL)
	return d;
    }
  return (DataObject *) NULL;
}

Vector<DataObject*>*
DbeSession::get_dobj_elements (DataObject *dobj)
{
  DataObject *d;
  int index;
  Vector<DataObject*> *elements = new Vector<DataObject*>;
  if (dobj == d_total)
    return elements;
  Vec_loop (DataObject*, dobjs, index, d)
  {
    if (d->get_parent () && d->get_parent () == dobj)
      elements->append (d);
  }
  return elements;
}

Vector<LoadObject*>*
DbeSession::get_text_segments ()
{
  LoadObject *lo;
  int index;
  Vector<LoadObject*> *tlobjs = new Vector<LoadObject*>;
  Vec_loop (LoadObject*, lobjs, index, lo)
  {
    if (lo->type == LoadObject::SEG_TEXT)
      tlobjs->append (lo);
  }
  return tlobjs;
}

static long long
getNumber (const char *s, char * &last)
{
  long long val;
  char *sp;
  errno = 0;
  val = strtoll (s, &sp, 0);
  if (errno == EINVAL)
    last = NULL;
  else
    {
      while (isspace (*sp))
	sp++;
      last = sp;
    }
  return (val);
}

bool
DbeSession::find_obj (FILE *dis_file, FILE *inp_file, Histable *&obj,
		      char *name, const char *sel, Histable::Type type, bool xdefault)
{
  Vector<Histable*> *obj_lst;
  int which = -1;
  char *last = NULL;
  if (type != Histable::FUNCTION && sel)
    {
      // check that a number has been provided
      which = (int) getNumber (sel, last);
      if (last == NULL || *last != '\0')
	{
	  fprintf (stderr, GTXT ("Error: Invalid number entered: %s\n"), sel);
	  sel = NULL;
	  which = 0;
	}
      which--;
    }
  obj_lst = new Vector<Histable*>;
  switch (type)
    {
    case Histable::FUNCTION:
      obj = map_NametoFunction (name, obj_lst, sel);
      break;
    case Histable::MODULE:
      obj = map_NametoModule (name, obj_lst, which);
      break;
    case Histable::LOADOBJECT:
      obj = map_NametoLoadObject (name, obj_lst, which);
      break;
    case Histable::DOBJECT:
      obj = map_NametoDataObject (name, obj_lst, which);
      break;
    default:
      abort (); // unexpected Histable!
    }

  if ((obj == NULL) && (obj_lst->size () > 0))
    {
      if (obj_lst->size () == 1)
	which = 0;
      else
	{
	  if (sel && (which < 0 || which >= obj_lst->size ()))
	    fprintf (stderr, GTXT ("Error: Invalid number entered: %s\n"), sel);
	  if (xdefault)
	    {
	      fprintf (stderr, GTXT ("Default selection \"1\" made\n"));
	      which = 0;
	    }
	  else
	    {
	      which = ask_which (dis_file, inp_file, obj_lst, name);
	      if (which == -1)
		{
		  delete obj_lst;
		  return false;
		}
	    }
	}
      obj = obj_lst->fetch (which);
    }
  delete obj_lst;
  return true;
}

int
DbeSession::ask_which (FILE *dis_file, FILE *inp_file,
		       Vector<Histable*> *list, char *name)
{
  Histable *hitem;
  Function *func;
  Module *module;
  int which, index, index1;
  char *item_name, *lo_name, *fname, *last;
  char buf[BUFSIZ];
  for (;;)
    {
      fprintf (dis_file, GTXT ("Available name list:\n"));
      fprintf (dis_file, GTXT ("%8d) Cancel\n"), 0);
      Vec_loop (Histable*, list, index, hitem)
      {
	index1 = index + 1;
	item_name = hitem->get_name ();
	switch (hitem->get_type ())
	  {
	  case Histable::FUNCTION:
	    func = (Function *) hitem;
	    module = func->module;

	    // id == -1 indicates er_src invocation
	    if (module == NULL || (module->lang_code == Sp_lang_java
				   && module->loadobject->id == -1))
		fprintf (dis_file, NTXT ("%8d) %s\n"), index1, item_name);
	    else
	      {
		lo_name = module->loadobject->get_pathname ();
		fname = (module->file_name && *module->file_name) ?
			module->file_name : module->get_name ();
		if (fname && *fname)
		  fprintf (dis_file, NTXT ("%8d) %s %s:0x%llx (%s)\n"), index1,
			   item_name, lo_name, (ull_t) func->img_offset, fname);
		else
		  fprintf (dis_file, NTXT ("%8d) %s %s:0x%llx\n"), index1,
			   item_name, lo_name, (ull_t) func->img_offset);
	      }
	    break;
	  case Histable::MODULE:
	    module = (Module *) hitem;
	    lo_name = module->loadobject->get_pathname ();
	    if (name[strlen (name) - 1] ==
		module->file_name[strlen (module->file_name) - 1])
	      fprintf (dis_file, NTXT ("%8d) %s(%s)\n"), index1,
		       module->file_name, lo_name);
	    else
	      fprintf (dis_file, NTXT ("%8d) %s(%s)\n"), index1, item_name,
		       lo_name);
	    break;
	  default:
	    fprintf (dis_file, NTXT ("%8d) %s\n"), index1, item_name);
	    break;
	  }
      }
      if (inp_file != stdin)
	return -1;
      fprintf (dis_file, GTXT ("Enter selection: "));
      if (fgets (buf, (int) sizeof (buf), inp_file) == NULL)
	{
	  fprintf (stderr, GTXT ("Error: Invalid number entered:\n"));
	  return -1;
	}
      which = (int) getNumber (buf, last);
      if (last && *last == '\0')
	if (which >= 0 && which <= list->size ())
	  return which - 1;
      fprintf (stderr, GTXT ("Error: Invalid number entered: %s\n"), buf);
    }
}

static bool
match_basename (char *name, char *full_name, int len = -1)
{
  if (full_name == NULL)
    return false;
  if (!strchr (name, '/'))
    full_name = get_basename (full_name);
  if (len == -1)
    return streq (name, full_name);
  return strncmp (name, full_name, len) == 0;
}

LoadObject *
DbeSession::map_NametoLoadObject (char *name, Vector<Histable*> *list, int which)
{
  // Search the tree to find the first module whose module name
  //	matches "name" or whose source file name matches "name"
  //  Issues: is the name a pathname, or a base name?
  //	Should we look at suffix to disambiguate?
  LoadObject *loitem;
  int index;
  Vec_loop (LoadObject*, lobjs, index, loitem)
  {
    // try pathname first
    // if failed, try object name next
    if (match_basename (name, loitem->get_pathname ()) ||
	match_basename (name, loitem->get_name ()))
      {
	if (which == list->size ())
	  return loitem;
	list->append (loitem);
      }
  }
  return (LoadObject *) NULL;
}

Module *
DbeSession::map_NametoModule (char *name, Vector<Histable*> *list, int which)
{
  // Search the tree to find the first loadobject whose loadobject name
  //	matches "name".

  //  Issues: is the name a pathname, or a base name?
  //	Should we look at suffix to disambiguate?
  LoadObject *loitem;
  Module *mitem;
  int index1, index2;
  Vec_loop (LoadObject*, lobjs, index1, loitem)
  {
    Vec_loop (Module*, loitem->seg_modules, index2, mitem)
    {
      // try source name first
      // if failed, try object name next
      if (match_basename (name, mitem->file_name) ||
	  match_basename (name, mitem->get_name ()))
	{
	  if (which == list->size ())
	    return mitem;
	  list->append (mitem);
	}
    }
  }
  return (Module *) NULL;
}

Function *
DbeSession::map_NametoFunction (char *name, Vector<Histable*> *list,
				const char *sel)
{
  // Search the tree to find the first function whose
  //	name matches "name".
  //  Issues: is the name a full name, or a short name?
  //	Is it a demangled name?  If so, what about spaces
  //		within the name?
  //	Is there a way to return all names that match?
  //	How can the user specify a particular function of that name?
  LoadObject *loitem;
  Function *fitem, *main_func = NULL;
  Module *mitem, *main_mod = NULL;
  int index1, index2, index3, which = -1;
  if (sel)
    {
      char *last = NULL;
      if (*sel == '@')
	{ // 'sel' is "@seg_num:address"
	  which = (int) getNumber (sel + 1, last);
	  if (last == NULL || *last != ':' || (which < 0) || (which >= lobjs->size ()))
	    {
	      fprintf (stderr, GTXT ("Error: Invalid number entered: %s\n"), sel);
	      return NULL;
	    }
	  uint64_t address = getNumber (last + 1, last);
	  if (last == NULL || *last != '\0')
	    {
	      fprintf (stderr, GTXT ("Error: Invalid number entered: %s\n"), sel);
	      return NULL;
	    }
	  loitem = lobjs->fetch (which);
	  Vec_loop (Module*, loitem->seg_modules, index2, mitem)
	  {
	    Vec_loop (Function*, mitem->functions, index3, fitem)
	    {
	      if (address == fitem->img_offset && match_FName (name, fitem))
		return fitem;
	    }
	  }
	  return NULL;
	}

      which = (int) getNumber (sel, last);
      if (last == NULL || *last != '\0')
	{
	  fprintf (stderr, GTXT ("Error: Invalid number entered: %s\n"), sel);
	  return NULL;
	}
      which--;
    }

  int len_path = 0;
  char *with_path = name;
  name = StrRchr (name, '`');
  if (name != with_path)
    len_path = (int) (name - with_path);
  else
    with_path = NULL;

  Vec_loop (LoadObject*, lobjs, index1, loitem)
  {
    Vec_loop (Module*, loitem->seg_modules, index2, mitem)
    {
      if (with_path)
	{ // with file name
	  // try source name first
	  // if failed, try object name next
	  if (!match_basename (with_path, mitem->file_name, len_path) &&
	      !match_basename (with_path, mitem->get_name (), len_path))
	    continue;
	}
      Vec_loop (Function*, mitem->functions, index3, fitem)
      {
	if (match_FName (name, fitem))
	  {
	    if (which == list->size ())
	      return fitem;
	    list->append (fitem);
	    continue;
	  }
	if (streq (fitem->get_name (), NTXT ("MAIN_")) && mitem->is_fortran ())
	  {
	    main_func = fitem;
	    main_mod = mitem;
	  }
      }
    }
  }

  if (main_mod && main_func)
    {
      main_mod->read_stabs ();
      if (streq (main_func->get_match_name (), name) && which <= 1)
	return main_func;
    }
  return (Function *) NULL;
}

DataObject *
DbeSession::map_NametoDataObject (char *name, Vector<Histable*> *list,
				  int which)
{
  // Search master list to find dataobjects whose names match "name"
  // selecting only the entry corresponding to "which" if it is not -1.
  // Issues: is the name fully qualified or only partially?
  DataObject *ditem = NULL;
  int index;
  char *full_name;
  Vec_loop (DataObject*, dobjs, index, ditem)
  {
    if (ditem->scope) continue; // skip non-master dataobjects

    // try fully-qualified dataobject name first
    if ((full_name = ditem->get_name ()) != NULL)
      {
	if (streq (name, full_name))
	  {
	    if (which == list->size ())
	      return ditem;
	    list->append (ditem);
	  }
      }
  }
  if (list->size () > 0)
    return ditem; // return fully-qualified match

  // if fully-qualified name doesn't match anything, try a partial match
  Vec_loop (DataObject*, dobjs, index, ditem)
  {
    if (ditem->scope) continue; // skip non-master dataobjects

    // try fully-qualified dataobject name first
    if ((full_name = ditem->get_name ()) != NULL)
      {
	if (strstr (full_name, name))
	  {
	    if (which == list->size ())
	      return ditem;
	    list->append (ditem);
	  }
      }
  }
  return (DataObject *) NULL;
}

bool
DbeSession::match_FName (char *name, Function *func)
{
  size_t len;
  char buf[MAXDBUF];
  char *full_name;
  if (streq (func->get_name (), name)) // try full name comparison
    return true;
  if (streq (func->get_mangled_name (), name)) // try mangled name
    return true;
  if (streq (func->get_match_name (), name)) // try match name
    return true;

  Module *md = func->module; // try FORTRAN name
  if (md && md->is_fortran ())
    {
      char *mangled_name = func->get_mangled_name ();
      len = strlen (name);
      if (((len + 1) == strlen (mangled_name)) &&
	  (strncmp (name, mangled_name, len) == 0))
	return true;
    }
  snprintf (buf, sizeof (buf), NTXT ("%s"), func->get_name ());
  full_name = buf;
  char *arg = NULL; // find modifier and C++ class name
  int i = get_paren (buf);
  if (i >= 0)
    {
      arg = buf + i;
      *arg = '\0';
    }

  char *mod = strchr (full_name, ' ');
  char *cls = strchr (full_name, ':');

  if (mod)
    {
      len = mod - full_name + 1;
      if (!strncmp (full_name, name, len))
	name += len;
      full_name += len;
      if (streq (full_name, name)) // try without modifier
	return true;
    }

  size_t len_cmp = strlen (name);
  if (arg)
    {
      *arg = '(';
      len = arg - full_name; // try without 'args'
      if (len_cmp == len && !strncmp (full_name, name, len))
	return true;
      if (cls)
	{
	  len = arg - cls - 2; // and without 'class name'
	  if ((len_cmp == len) && !strncmp (cls + 2, name, len))
	    return true;
	}
    }

  if (cls)
    {
      len = cls - full_name; // try C++ class name only
      if (len_cmp == len && !strncmp (full_name, name, len))
	return true;
      if (streq (cls + 2, name)) // try without 'class name'
	return true;
    }
  return false;
}

bool
DbeSession::add_path (char *path)
{
  return add_path (path, get_search_path ());
}

bool
DbeSession::add_classpath (char *path)
{
  return add_path (path, classpath);
}

Vector<DbeFile*> *
DbeSession::get_classpath ()
{
  if (classpath_df == NULL)
    classpath_df = new Vector<DbeFile*>;
  for (int i = classpath_df->size (), sz = classpath->size (); i < sz; i++)
    classpath_df->store (i, getDbeFile (classpath->fetch (i),
					DbeFile::F_DIR_OR_JAR));
  return classpath_df;
}

bool
DbeSession::add_path (char *path, Vector<char*> *pathes)
{
  bool result = false;
  Vector <char *> *tokens = split_str (path, ':');
  for (long j = 0, jsz = VecSize (tokens); j < jsz; j++)
    {
      char *spath = tokens->get (j);
      // Don't append path if it's already there
      bool got = false;
      for (int i = 0, sz = pathes->size (); i < sz; i++)
	{
	  char *nm = pathes->get (i);
	  if (streq (nm, spath))
	    {
	      got = true;
	      break;
	    }
	}
      if (!got)
	{
	  pathes->append (spath);
	  result = true;
	}
      else
	free (spath);
    }
  delete tokens;
  return result;
}

void
DbeSession::set_need_refind ()
{
  Vector<DbeFile*> *f_list = dbeFiles->values ();
  for (long i = 0, sz = f_list == NULL ? 0 : f_list->size (); i < sz; i++)
    {
      DbeFile *f = f_list->get (i);
      f->set_need_refind (true);
    }
  delete f_list;
  for (long i = 0, sz = sources == NULL ? 0 : sources->size (); i < sz; i++)
    {
      SourceFile *f = sources->get (i);
      if (f && f->dbeFile)
	f->dbeFile->set_need_refind (true);
    }
}

void
DbeSession::set_search_path (Vector<char*> *path, bool reset)
{
  if (reset)
    search_path->destroy ();
  for (int i = 0, sz = path == NULL ? 0 : path->size (); i < sz; i++)
    {
      char *name = path->fetch (i);
      if (add_path (name))
	reset = true;
    }
  if (reset)
    {
      set_need_refind ();

      // now reset the string setting for it
      StringBuilder sb;
      for (int i = 0, sz = search_path == NULL ? 0 : search_path->size (); i < sz; i++)
	{
	  char *name = search_path->fetch (i);
	  if (sb.length () != 0)
	    sb.append (':');
	  sb.append (name);
	}
      free (settings->str_search_path);
      settings->str_search_path = sb.toString ();
    }
}

void
DbeSession::set_search_path (char *_lpath, bool reset)
{
  Vector<char *> *path = new Vector<char*>;
  char *lpath = dbe_strdup (_lpath);
  for (char *s = lpath; s;)
    {
      path->append (s);
      s = strchr (s, ':');
      if (s)
	{
	  *s = 0;
	  s++;
	}
    }
  set_search_path (path, reset);
  delete path;
  free (lpath);
}

void
DbeSession::set_pathmaps (Vector<pathmap_t*> *newPathMap)
{
  set_need_refind ();
  settings->set_pathmaps (newPathMap);
}

Vector<pathmap_t*> *
DbeSession::get_pathmaps ()
{
  return settings->pathmaps;
}

void
DbeSession::mobj_define (MemObjType_t *mobj)
{
  settings->mobj_define (mobj, false);
  DbeView *dbev;
  int index;
  Vec_loop (DbeView*, views, index, dbev)
  {
    dbev->get_settings ()->mobj_define (mobj, false);
  }
}

void
DbeSession::dump_segments (FILE *out)
{
  int index;
  LoadObject *loitem;
  Vec_loop (LoadObject*, lobjs, index, loitem)
  {
    fprintf (out, NTXT ("Segment %d -- %s -- %s\n\n"),
	     index, loitem->get_name (), loitem->get_pathname ());
    loitem->dump_functions (out);
    fprintf (out, NTXT ("\n End Segment %d -- %s -- %s\n\n"),
	     index, loitem->get_name (), loitem->get_pathname ());
  }
}

void
DbeSession::dump_dataobjects (FILE *out)
{
  DataObject *ditem;
  int index;

  fprintf (out, NTXT ("\nMaster list of DataObjects:\n"));
  Vec_loop (DataObject*, dobjs, index, ditem)
  {
    Histable* scope = ditem->get_scope ();
    DataObject* parent = ditem->get_parent ();
    DataObject* master = ditem->get_master ();
    if (parent != NULL)
      fprintf (out, "id %6lld: [%4lld] parent = %6lld, offset = %+4lld %s\n",
	       (ll_t) ditem->id, (ll_t) ditem->get_size (),
	       (ll_t) parent->id, (ll_t) ditem->get_offset (),
	       ditem->get_name ());
    else
      {
	// parent is NULL
	fprintf (out, NTXT ("id %6lld: [%4lld] %s "),
		 (ll_t) ditem->id, (ll_t) ditem->get_size (),
		 ditem->get_name ());
	if (master != NULL)
	  fprintf (out, NTXT (" master=%lld "), (ll_t) master->id);
	else if (scope != NULL)
	  fprintf (out, NTXT (" master=?? "));
	else
	  fprintf (out, NTXT (" MASTER "));
#if DEBUG
	if (scope != NULL)
	  {
	    switch (scope->get_type ())
	      {
	      case Histable::LOADOBJECT:
	      case Histable::FUNCTION:
		fprintf (out, NTXT ("%s"), scope->get_name ());
		break;
	      case Histable::MODULE:
		{
		  char *filename = get_basename (scope->get_name ());
		  fprintf (out, NTXT ("%s"), filename);
		  break;
		}
	      default:
		fprintf (out, NTXT (" Unexpected scope %d:%s"),
			 scope->get_type (), scope->get_name ());
	      }
	  }
#endif
	fprintf (out, NTXT ("\n"));
      }
  }
}

void
DbeSession::dump_map (FILE *out)
{
  Experiment *exp;
  int index;
  Vec_loop (Experiment*, exps, index, exp)
  {
    exp->dump_map (out);
  }
}

void
DbeSession::dump_stacks (FILE *outfile)
{
  Experiment *exp;
  int n = nexps ();
  FILE *f = (outfile == NULL ? stderr : outfile);
  for (int i = 0; i < n; i++)
    {
      exp = get_exp (i);
      fprintf (f, GTXT ("Experiment %d -- %s\n"), i, exp->get_expt_name ());
      exp->dump_stacks (f);
    }
}

void
DbeSession::propNames_name_store (int propId, const char *propName)
{
  PropDescr *prop = new PropDescr (propId, propName);
  prop->flags = PRFLAG_NOSHOW; // do not show descriptions
  propNames->store (propId, prop);
}

void
DbeSession::propNames_name_store (int propId, const char* propName,
				  const char* propUname, VType_type dataType,
				  int flags)
{
  PropDescr *prop = new PropDescr (propId, propName);
  prop->vtype = dataType;
  prop->uname = dbe_strdup (propUname);
  prop->flags = flags;
  propNames->store (propId, prop);
}

char *
DbeSession::propNames_name_fetch (int i)
{
  PropDescr *prop = propNames->fetch (i);
  if (prop)
    return prop->name;
  return NULL;
}

int
DbeSession::registerPropertyName (const char *name)
{
  if (name == NULL)
    return PROP_NONE;
  for (int i = 0; i < propNames->size (); i++)
    {
      char *pname = propNames_name_fetch (i);
      if (pname && strcasecmp (pname, name) == 0)
	return i;
    }
  int propId = propNames->size ();
  propNames_name_store (propId, name);
  return propId;
}

int
DbeSession::getPropIdByName (const char *name)
{
  if (name == NULL)
    return PROP_NONE;
  for (int i = 0; i < propNames->size (); i++)
    {
      char *pname = propNames_name_fetch (i);
      if (pname && strcasecmp (pname, name) == 0)
	return i;
    }
  return PROP_NONE;
}

char *
DbeSession::getPropName (int propId)
{
  if (!propNames)
    return NULL;
  if (propId < 0 || propId >= propNames->size ())
    return NULL;
  return dbe_strdup (propNames_name_fetch (propId));
}

char *
DbeSession::getPropUName (int propId)
{
  if (!propNames)
    return NULL;
  if (propId < 0 || propId >= propNames->size ())
    return NULL;
  PropDescr *prop = propNames->fetch (propId);
  if (prop)
    return dbe_strdup (prop->uname);
  return NULL;
}

void
DbeSession::append (UserLabel *lbl)
{
  if (lbl->expr)
    {
      if (userLabels == NULL)
	 userLabels = new Vector<UserLabel*> ();
      userLabels->append (lbl);
    }
}

void
DbeSession::append (SourceFile *sf)
{
  sources->append (sf);
  objs->append (sf);
}

UserLabel *
DbeSession::findUserLabel (const char *name)
{
  for (int i = 0, sz = userLabels ? userLabels->size () : 0; i < sz; i++)
    {
      UserLabel *lbl = userLabels->fetch (i);
      if (strcasecmp (lbl->name, name) == 0)
	return lbl;
    }
  return NULL;
}

Expression *
DbeSession::findObjDefByName (const char *name)
{
  Expression *expr = NULL;

  MemObjType_t *mot = MemorySpace::findMemSpaceByName (name);
  if (mot != NULL)
    {
      char *index_expr_str = mot->index_expr;
      expr = ql_parse (index_expr_str);
    }

  if (expr == NULL)
    {
      int indxtype = findIndexSpaceByName (name);
      expr = getIndexSpaceExpr (indxtype);
    }
  if (expr == NULL)
    {
      UserLabel *ulbl = findUserLabel (name);
      if (ulbl)
	expr = ulbl->expr;
    }
  return expr;
}

Expression *
DbeSession::ql_parse (const char *expr_spec)
{
  if (expr_spec == NULL)
    expr_spec = "";
  QL::Result result (expr_spec);
  QL::Parser qlparser (result);
  if (qlparser.parse () != 0)
    return NULL;
  return result ();
}

Vector<void*> *
DbeSession::getIndxObjDescriptions ()
{
  int size = dyn_indxobj_indx;
  if (size == 0)
    return NULL;
  Vector<int> *type = new Vector<int>(dyn_indxobj_indx);
  Vector<char*> *desc = new Vector<char*>(dyn_indxobj_indx);
  Vector<char*> *i18ndesc = new Vector<char*>(dyn_indxobj_indx);
  Vector<char> *mnemonic = new Vector<char>(dyn_indxobj_indx);
  Vector<int> *orderList = new Vector<int>(dyn_indxobj_indx);
  Vector<char*> *exprList = new Vector<char*>(dyn_indxobj_indx);
  Vector<char*> *sdesc = new Vector<char*>(dyn_indxobj_indx);
  Vector<char*> *ldesc = new Vector<char*>(dyn_indxobj_indx);

  for (long i = 0, sz = VecSize (dyn_indxobj); i < sz; i++)
    {
      IndexObjType_t *tot = dyn_indxobj->get (i);
      if (tot->memObj == NULL)
	{
	  type->append ((int) tot->type);
	  desc->append (dbe_strdup (tot->name));
	  i18ndesc->append (dbe_strdup (tot->i18n_name));
	  sdesc->append (dbe_strdup (tot->short_description));
	  ldesc->append (dbe_strdup (tot->long_description));
	  mnemonic->append (tot->mnemonic);
	  orderList->append (settings->indx_tab_order->fetch (i));
	  exprList->append (dbe_strdup (tot->index_expr_str));
	}
    }
  Vector<void*> *res = new Vector<void*>(8);
  res->store (0, type);
  res->store (1, desc);
  res->store (2, mnemonic);
  res->store (3, i18ndesc);
  res->store (4, orderList);
  res->store (5, exprList);
  res->store (6, sdesc);
  res->store (7, ldesc);
  return (res);
}

// Static function to get a vector of custom index object definitions
Vector<void*> *
DbeSession::getCustomIndxObjects ()
{
  Vector<char*> *name = new Vector<char*>;
  Vector<char*> *formula = new Vector<char*>;
  for (long i = dyn_indxobj_indx_fixed, sz = VecSize (dyn_indxobj); i < sz; i++)
    {
      IndexObjType_t *tot = dyn_indxobj->get (i);
      if (tot->memObj == NULL)
	{
	  name->append (dbe_strdup (tot->name));
	  formula->append (dbe_strdup (tot->index_expr_str));
	}
    }
  Vector<void*> *res = new Vector<void*>(2);
  res->store (0, name);
  res->store (1, formula);
  return (res);
}

// Static function to define a new index object type
char *
DbeSession::indxobj_define (const char *mname, char *i18nname, const char *index_expr_str, char *short_description, char *long_description)
{
  if (mname == NULL)
    return dbe_strdup (GTXT ("No index object type name has been specified."));
  if (isalpha ((int) (mname[0])) == 0)
    return dbe_sprintf (GTXT ("Index Object type name %s does not begin with an alphabetic character"),
			  mname);
  const char *p = mname;
  while (*p != 0)
    {
      if ((isalnum ((int) (*p)) == 0) && (*p != '_'))
	return dbe_sprintf (GTXT ("Index Object type name %s contains a non-alphanumeric character"),
			    mname);
      p++;
    }

  // make sure the name is not in use
  if (MemorySpace::findMemSpaceByName (mname) != NULL)
    return dbe_sprintf (GTXT ("Memory/Index Object type name %s is already defined"),
			  mname);

  int idxx = findIndexSpaceByName (mname);
  if (idxx >= 0)
    {
      IndexObjType_t *mt = dyn_indxobj->fetch (idxx);
      if (strcmp (mt->index_expr_str, index_expr_str) == 0)
	// It's a redefinition, but the new definition is the same
	return NULL;
      return dbe_sprintf (GTXT ("Memory/Index Object type name %s is already defined"),
			  mname);
    }
  if (index_expr_str == NULL)
    return dbe_strdup (GTXT ("No index-expr has been specified."));
  if (strlen (index_expr_str) == 0)
    return dbe_sprintf (GTXT ("Index Object index expression is invalid: %s"),
			index_expr_str);

  // verify that the index expression parses correctly
  char *expr_str = dbe_strdup (index_expr_str);
  Expression *expr = ql_parse (expr_str);
  if (expr == NULL)
    return dbe_sprintf (GTXT ("Index Object index expression is invalid: %s"),
			expr_str);

  // It's OK, create the new table entry
  IndexObjType_t *tot = new IndexObjType_t;
  tot->type = dyn_indxobj_indx++;
  tot->name = dbe_strdup (mname);
  tot->i18n_name = dbe_strdup (i18nname);
  tot->short_description = dbe_strdup (short_description);
  tot->long_description = dbe_strdup (long_description);
  tot->index_expr_str = expr_str;
  tot->index_expr = expr;
  tot->mnemonic = mname[0];

  // add it to the list
  dyn_indxobj->append (tot);
  idxobjs->append (new HashMap<uint64_t, Histable*>);

  // tell the session
  settings->indxobj_define (tot->type, false);

  DbeView *dbev;
  int index;
  Vec_loop (DbeView*, views, index, dbev)
  {
    dbev->addIndexSpace (tot->type);
  }
  return NULL;
}

char *
DbeSession::getIndexSpaceName (int index)
{
  if (index < 0 || index >= dyn_indxobj->size ())
    return NULL;
  return dyn_indxobj->fetch (index)->name;
}

char *
DbeSession::getIndexSpaceDescr (int index)
{
  if (index < 0 || index >= dyn_indxobj->size ())
    return NULL;
  return dyn_indxobj->fetch (index)->i18n_name;
}

Expression *
DbeSession::getIndexSpaceExpr (int index)
{
  if (index < 0 || index >= dyn_indxobj->size ())
    return NULL;
  return dyn_indxobj->fetch (index)->index_expr;
}

char *
DbeSession::getIndexSpaceExprStr (int index)
{
  if (index < 0 || index >= dyn_indxobj->size ())
    return NULL;
  return dyn_indxobj->fetch (index)->index_expr_str;
}

int
DbeSession::findIndexSpaceByName (const char *mname)
{
  int idx;
  IndexObjType_t *mt;
  Vec_loop (IndexObjType_t*, dyn_indxobj, idx, mt)
  {
    if (strcasecmp (mt->name, mname) == 0)
      return idx;
  }
  return -1;
}

void
DbeSession::removeIndexSpaceByName (const char *mname)
{
  IndexObjType_t *indObj = findIndexSpace (mname);
  if (indObj)
    indObj->name[0] = 0;
}

IndexObjType_t *
DbeSession::getIndexSpace (int index)
{
  return ((index < 0) || (index >= VecSize (dyn_indxobj))) ? NULL : dyn_indxobj->get (index);
}

IndexObjType_t *
DbeSession::findIndexSpace (const char *mname)
{
  return getIndexSpace (findIndexSpaceByName (mname));
}

void
DbeSession::get_filter_keywords (Vector<void*> *res)
{
  Vector <char*> *kwCategory = (Vector<char*>*) res->fetch (0);
  Vector <char*> *kwCategoryI18N = (Vector<char*>*) res->fetch (1);
  Vector <char*> *kwDataType = (Vector<char*>*) res->fetch (2);
  Vector <char*> *kwKeyword = (Vector<char*>*) res->fetch (3);
  Vector <char*> *kwFormula = (Vector<char*>*) res->fetch (4);
  Vector <char*> *kwDescription = (Vector<char*>*) res->fetch (5);
  Vector <void*> *kwEnumDescs = (Vector<void*>*) res->fetch (6);

  char *vtypeNames[] = VTYPE_TYPE_NAMES;
  for (long i = 0, sz = userLabels ? userLabels->size () : 0; i < sz; i++)
    {
      UserLabel *lbl = userLabels->fetch (i);
      kwCategory->append (dbe_strdup (NTXT ("FK_LABEL")));
      kwCategoryI18N->append (dbe_strdup (GTXT ("Labels")));
      kwDataType->append (dbe_strdup (vtypeNames[TYPE_BOOL]));
      kwKeyword->append (dbe_strdup (lbl->name));
      kwFormula->append (dbe_strdup (lbl->str_expr));
      kwDescription->append (dbe_strdup (lbl->comment));
      kwEnumDescs->append (NULL);
    }

  for (long i = 0, sz = propNames ? propNames->size () : 0; i < sz; i++)
    {
      PropDescr *prop = propNames->fetch (i);
      char *pname = prop ? prop->name : NULL;
      if (pname == NULL || *pname == 0 || prop->flags & PRFLAG_NOSHOW)
	continue;
      int vtypeNum = prop->vtype;
      if (vtypeNum < 0 || vtypeNum >= TYPE_LAST)
	vtypeNum = TYPE_NONE;
      kwCategory->append (dbe_strdup (NTXT ("FK_EVTPROP"))); //Event Property
      kwCategoryI18N->append (dbe_strdup (GTXT ("Misc. Definitions")));
      kwDataType->append (dbe_strdup (vtypeNames[vtypeNum]));
      kwKeyword->append (dbe_strdup (pname));
      kwFormula->append (NULL);
      kwDescription->append (dbe_strdup (prop->uname));
      kwEnumDescs->append (NULL);
    }

  for (long i = 0, sz = dyn_indxobj ? dyn_indxobj->size () : 0; i < sz; i++)
    {
      IndexObjType_t *obj = dyn_indxobj->get (i);
      if (obj->memObj)
	continue;
      kwCategory->append (dbe_strdup (NTXT ("FK_IDXOBJ")));
      kwCategoryI18N->append (dbe_strdup (GTXT ("Index Object Definitions")));
      kwDataType->append (dbe_strdup (vtypeNames[TYPE_INT64]));
      kwKeyword->append (dbe_strdup (obj->name));
      kwFormula->append (dbe_strdup (obj->index_expr_str));
      kwDescription->append (dbe_strdup (obj->i18n_name));
      kwEnumDescs->append (NULL);
    }
}

Histable *
DbeSession::findIndexObject (int idxtype, uint64_t idx)
{
  HashMap<uint64_t, Histable*> *iobjs = idxobjs->fetch (idxtype);
  return iobjs->get (idx);
}

Histable *
DbeSession::createIndexObject (int idxtype, int64_t idx)
{
  HashMap<uint64_t, Histable*> *iobjs = idxobjs->fetch (idxtype);

  Histable *idxobj = iobjs->get (idx);
  if (idxobj == NULL)
    {
      idxobj = new IndexObject (idxtype, idx);
      if (idx == -1)
	idxobj->set_name (dbe_strdup (GTXT ("<Unknown>")));
      iobjs->put (idx, idxobj);
    }

  return idxobj;
}

Histable *
DbeSession::createIndexObject (int idxtype, Histable *hobj)
{
  HashMap<uint64_t, Histable*> *iobjs = idxobjs->fetch (idxtype);
  int64_t idx = hobj ? hobj->id : -1;
  Histable *idxobj = iobjs->get (idx);
  if (idxobj == NULL)
    {
      idxobj = new IndexObject (idxtype, hobj);
      if (idx == -1)
	idxobj->set_name (dbe_strdup (GTXT ("<Unknown>")));
      iobjs->put (idx, idxobj);
    }

  return idxobj;
}

Histable *
DbeSession::findObjectById (Histable::Type type, int subtype, uint64_t id)
{
  switch (type)
    {
    case Histable::FUNCTION:
    case Histable::MODULE:
    case Histable::LOADOBJECT:
      return ( id < (uint64_t) objs->size ()) ? objs->fetch ((int) id) : NULL;
    case Histable::INDEXOBJ:
      return findIndexObject (subtype, id);
      // ignoring the following cases
    case Histable::INSTR:
    case Histable::LINE:
    case Histable::EADDR:
    case Histable::MEMOBJ:
    case Histable::PAGE:
    case Histable::DOBJECT:
    case Histable::SOURCEFILE:
    case Histable::IOACTFILE:
    case Histable::IOACTVFD:
    case Histable::IOCALLSTACK:
    case Histable::HEAPCALLSTACK:
    case Histable::OTHER:
    case Histable::EXPERIMENT:
      break;
    }
  return NULL;
}

// return a vector of Functions that match the regular expression input string
Vector<JThread *> *
DbeSession::match_java_threads (char *ustr, int matchParent,
				Vector<uint64_t> * &grids,
				Vector<uint64_t> * &expids)
{
  if (ustr == NULL)
    return NULL;

  char *str = dbe_sprintf (NTXT ("^%s$"), ustr);
  regex_t regex_desc;
  int rc = regcomp (&regex_desc, str, REG_EXTENDED | REG_NOSUB | REG_NEWLINE);
  free (str);
  if (rc)   // syntax error in parsing string
    return NULL;

  // allocate the new vector
  Vector<JThread *> *ret = new Vector<JThread*>;
  grids = new Vector<uint64_t>;
  expids = new Vector<uint64_t>;

  int index;
  JThread *jthread;
  int expid;
  Experiment* exp;
  Vec_loop (Experiment*, exps, expid, exp)
  {

    Vec_loop (JThread*, exp->get_jthreads (), index, jthread)
    {
      const char * name;
      if (matchParent)
	name = jthread->parent_name;
      else
	name = jthread->group_name;
      if (name == NULL)
	name = "";
      if (!regexec (&regex_desc, name, 0, NULL, 0))
	{
	  // this one matches
	  ret->append (jthread);
	  grids->append (exp->groupId);
	  expids->append (exp->getUserExpId ());
	}
    }
  }

  regfree (&regex_desc);
  return ret;
}

// return a vector of Functions that match the regular expression input string
Vector<Function *> *
DbeSession::match_func_names (const char *ustr, Histable::NameFormat nfmt)
{
  if (ustr == NULL)
    return NULL;
  char *str = dbe_sprintf (NTXT ("^%s$"), ustr);
  regex_t regex_desc;
  int rc = regcomp (&regex_desc, str, REG_EXTENDED | REG_NOSUB | REG_NEWLINE);
  free (str);
  if (rc)   // syntax error in parsing string
    return NULL;

  // allocate the new vector
  Vector<Function *> *ret = new Vector<Function*>;

  int index;
  Histable *obj;
  Vec_loop (Histable*, objs, index, obj)
  {
    if (obj->get_type () == Histable::FUNCTION)
      {
	Function *func = (Function*) obj;
	if (!regexec (&regex_desc, func->get_name (nfmt), 0, NULL, 0))
	  // this one matches
	  ret->append (func);
      }
  }
  regfree (&regex_desc);
  return ret;
}

// return a vector of Functions that match the regular expression input string
Vector<FileData *> *
DbeSession::match_file_names (char *ustr, Histable::NameFormat nfmt)
{
  if (ustr == NULL)
    return NULL;
  char *str = dbe_sprintf (NTXT ("^%s$"), ustr);
  regex_t regex_desc;
  int rc = regcomp (&regex_desc, str, REG_EXTENDED | REG_NOSUB | REG_NEWLINE);
  free (str);
  if (rc)   // syntax error in parsing string
    return NULL;

  // allocate the new vector
  Vector<FileData *> *ret = new Vector<FileData*>;
  int numExps = nexps ();
  DefaultMap<int64_t, FileData*>* fDataMap;
  Vector<FileData *> *fDataObjs;
  FileData *fData;
  int size;
  for (int i = 0; i < numExps; i++)
    {
      Experiment *exp = get_exp (i);
      fDataMap = exp->getFDataMap ();
      fDataObjs = fDataMap->values ();
      size = fDataObjs->size ();
      for (int j = 0; j < size; j++)
	{
	  fData = fDataObjs->fetch (j);
	  if (fData
	      && !regexec (&regex_desc, fData->get_raw_name (nfmt), 0, NULL, 0))
	    // this one matches
	    ret->append (fData);
	}
    }
  regfree (&regex_desc);
  return ret;
}

// return a vector of DataObjects that match the regular expression input string
Vector<DataObject *> *
DbeSession::match_dobj_names (char *ustr)
{
  if (ustr == NULL)
    return NULL;
  char *str = dbe_sprintf (NTXT ("^%s$"), ustr);
  regex_t regex_desc;
  int rc = regcomp (&regex_desc, str, REG_EXTENDED | REG_NOSUB | REG_NEWLINE);
  free (str);
  if (rc)   // syntax error in parsing string
    return NULL;

  // allocate the new vector
  Vector<DataObject *> *ret = new Vector<DataObject*>;
  int index;
  DataObject *ditem;
  Vec_loop (DataObject*, dobjs, index, ditem)
  {
    // does this one match
    if (!regexec (&regex_desc, ditem->get_name (), 0, NULL, 0))
      // this one matches
      ret->append (ditem);
  }
  regfree (&regex_desc);
  return ret;
}

void
DbeSession::dump (char *msg, Vector<BaseMetric*> *mlist)
{
  if (msg)
    fprintf (stderr, "%s\n", msg);
  int sz = mlist ? mlist->size () : -1;
  for (int i = 0; i < sz; i++)
    {
      BaseMetric *m = mlist->fetch (i);
      char *s = m->dump ();
      fprintf (stderr, "%2d %s\n", i, s);
      free (s);
    }
  fprintf (stderr, "======END of mlist[%d] =========\n", sz);
}

void
DbeSession::dump (char *msg, Vector<Metric*> *mlist)
{
  if (msg)
    fprintf (stderr, "%s\n", msg);
  int sz = mlist ? mlist->size () : -1;
  for (int i = 0; i < sz; i++)
    {
      Metric *m = mlist->fetch (i);
      char *s = m->dump ();
      fprintf (stderr, "%2d %s\n", i, s);
      free (s);
    }
  fprintf (stderr, "======END of mlist[%d] =========\n", sz);
}
