/* Copyright (C) 2021 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 <errno.h>
#include <sys/types.h> // open, chmod
#include <signal.h>
#include <fcntl.h>     // open
#include <strings.h>
#include <unistd.h>

#include "util.h"
#include "Histable.h"
#include "DbeSession.h"
#include "DbeView.h"
#include "BaseMetric.h"
#include "CallStack.h"
#include "collctrl.h"
#include "Command.h"
#include "Dbe.h"
#include "DbeApplication.h"
#include "DefaultMap.h"
#include "LoadObject.h"
#include "Experiment.h"
#include "IndexObject.h"
#include "IOActivity.h"
#include "PreviewExp.h"
#include "Function.h"
#include "Hist_data.h"
#include "MetricList.h"
#include "Module.h"
#include "DataSpace.h"
#include "MemorySpace.h"
#include "DataObject.h"
#include "MemObject.h"
#include "Filter.h"
#include "FilterSet.h"
#include "FilterExp.h"
#include "Sample.h"
#include "Print.h"
#include "StringBuilder.h"
#include "dbe_types.h"
#include "ExpGroup.h"
#include "vec.h"
#include "UserLabel.h"
#include "DbeFile.h"
#include "PathTree.h"

// Data structures for managing the collector control info for Collection GUI
static Coll_Ctrl *col_ctr = NULL;

template<> VecType Vector<int>::type ()
{
  return VEC_INTEGER;
}

template<> VecType Vector<unsigned>::type ()
{
  return VEC_INTEGER;
}

template<> VecType Vector<char>::type ()
{
  return VEC_CHAR;
}

template<> VecType Vector<bool>::type ()
{
  return VEC_BOOL;
}

template<> VecType Vector<double>::type ()
{
  return VEC_DOUBLE;
}

template<> VecType Vector<long long>::type ()
{
  return VEC_LLONG;
}

template<> VecType Vector<uint64_t>::type ()
{
  return VEC_LLONG;
}

template<> VecType Vector<void*>::type ()
{
  return VEC_VOIDARR;
}

template<> VecType Vector<char*>::type ()
{
  return VEC_STRING;
}

template<> VecType Vector<Vector<int>*>::type ()
{
  return VEC_INTARR;
}

template<> VecType Vector<Vector<char*>*>::type ()
{
  return VEC_STRINGARR;
}

template<> VecType Vector<Vector<long long>*>::type ()
{
  return VEC_LLONGARR;
}

// gcc won't instantiate Vector<unsigned>::type() without it
Vector<unsigned> __dummy_unsigned_vector;

#define CASE_S(x)   case x: return #x
static const char *
dsp_type_to_string (int t)
{
  switch (t)
    {
      CASE_S (DSP_FUNCTION);
      CASE_S (DSP_LINE);
      CASE_S (DSP_PC);
      CASE_S (DSP_SOURCE);
      CASE_S (DSP_DISASM);
      CASE_S (DSP_SELF);
      CASE_S (DSP_CALLER);
      CASE_S (DSP_CALLEE);
      CASE_S (DSP_CALLTREE);
      CASE_S (DSP_TIMELINE);
      CASE_S (DSP_STATIS);
      CASE_S (DSP_EXP);
      CASE_S (DSP_LEAKLIST);
      CASE_S (DSP_MEMOBJ);
      CASE_S (DSP_DATAOBJ);
      CASE_S (DSP_DLAYOUT);
      CASE_S (DSP_SRC_FILE);
      CASE_S (DSP_IFREQ);
      CASE_S (DSP_RACES);
      CASE_S (DSP_INDXOBJ);
      CASE_S (DSP_DUALSOURCE);
      CASE_S (DSP_SOURCE_DISASM);
      CASE_S (DSP_DEADLOCKS);
      CASE_S (DSP_SOURCE_V2);
      CASE_S (DSP_DISASM_V2);
      CASE_S (DSP_IOACTIVITY);
      CASE_S (DSP_OVERVIEW);
      CASE_S (DSP_IOCALLSTACK);
      CASE_S (DSP_HEAPCALLSTACK);
      CASE_S (DSP_SAMPLE);
    default:
      break;
    }
  return NTXT ("ERROR");
}

enum
{
  COMPARE_BIT       = 1 << 8,
  MTYPE_MASK        = (1 << 8) - 1,
  GROUP_ID_SHIFT    = 16
};

static DbeView *
getDbeView (int dbevindex)
{
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  return dbev;
}


Vector<char*> *
dbeGetInitMessages ()
{
  // If any comments from the .rc files, send them to the GUI
  Emsg *msg = theDbeApplication->fetch_comments ();
  int size = 0;
  while (msg != NULL)
    {
      size++;
      msg = msg->next;
    }

  // Initialize Java String array
  Vector<char*> *list = new Vector<char*>(size);
  msg = theDbeApplication->fetch_comments ();
  size = 0;
  int i = 0;
  while (msg != NULL)
    {
      char *str = msg->get_msg ();
      list->store (i, dbe_strdup (str));
      i++;
      msg = msg->next;
    }

  // now delete the comments
  theDbeApplication->delete_comments ();
  return list;
}

Vector<char*> *
dbeGetExpPreview (int /*dbevindex*/, char *exp_name)
{
  PreviewExp *preview = new PreviewExp ();
  preview->experiment_open (exp_name);
  preview->open_epilogue ();

  // Initialize Java String array
  Vector<char*> *info = preview->preview_info ();
  int size = info->size ();
  Vector<char*> *list = new Vector<char*>(size);

  // Get experiment names
  for (int i = 0; i < size; i++)
    {
      char *str = info->fetch (i);
      if (str == NULL)
	str = GTXT ("N/A");
      list->store (i, dbe_strdup (str));
    }
  delete info;
  delete preview;
  return list;
}

char *
dbeGetExpParams (int /*dbevindex*/, char *exp_name)
{
  PreviewExp *preview = new PreviewExp ();
  preview->experiment_open (exp_name);

  // Initialize Java String array
  char *arg_list = dbe_strdup (preview->getArgList ());
  delete preview;
  return arg_list;
}

/**
 * Gets File Attributes according to the specified format
 * Supported formats:
 * "/bin/ls -dl " - see 'man ls' for details
 * @param filename
 * @param format
 * @return char * attributes
 */
char *
dbeGetFileAttributes (const char *filename, const char *format)
{
  if (format != NULL)
    {
      if (!strcmp (format, NTXT ("/bin/ls -dl ")))
	{
	  // A kind of "/bin/ls -dl " simulation
	  struct stat64 sbuf;
	  sbuf.st_mode = 0;
	  dbe_stat (filename, &sbuf);
	  if (S_IREAD & sbuf.st_mode)
	    { // Readable
	      if (S_ISDIR (sbuf.st_mode) != 0)
		return dbe_sprintf (NTXT ("%s %s\n"), NTXT ("drwxrwxr-x"), filename);
	      else if (S_ISREG (sbuf.st_mode) != 0)
		return dbe_sprintf (NTXT ("%s %s\n"), NTXT ("-rwxrwxr-x"), filename);
	    }
	}
    }
  return dbe_strdup (NTXT (""));
}

/**
 * Gets list of files for specified directory according to the specified format
 * Supported formats:
 * "/bin/ls -a" - see 'man ls' for details
 * "/bin/ls -aF" - see 'man ls' for details
 * @param dirname
 * @param format
 * @return char * files
 */
char *
dbeGetFiles (const char *dirname, const char *format)
{
  if (format != NULL)
    return dbe_read_dir (dirname, format);
  return dbe_strdup (NTXT (""));
}

/**
 * Creates the directory named by this full path name, including any
 * necessary but nonexistent parent directories.
 * @param dirname
 * @return result
 */
char *
dbeCreateDirectories (const char *dirname)
{
  if (dirname != NULL)
    {
      char *res = dbe_create_directories (dirname);
      if (res != NULL)
	return res;
    }
  return dbe_strdup (NTXT (""));
}

/**
 * Deletes the file or the directory named by the specified path name.
 * If this pathname denotes a directory, then the directory must be empty in order to be deleted.
 * @param const char *pathname
 * @return int result
 */
char *
dbeDeleteFile (const char *pathname)
{
  // return unlink(pathname);
  if (pathname != NULL)
    {
      char *res = dbe_delete_file (pathname);
      if (res != NULL)
	return res;
    }
  return dbe_strdup (NTXT (""));
}

/**
 * Reads the file named by the specified path name.
 * Temporary limitation: file should be "text only" and its size should be less than the 1 MB limit.
 * If the operation was successful, the contents is in the first element, and second element is NULL.
 * If the operation failed, then first element is NULL, and second element contains the error message.
 * @param const char *pathname
 * @return Vector<char*> *result
 */
Vector<char*> *
dbeReadFile (const char *pathname)
{
  Vector<char*> *result = new Vector<char*>(2);
  int limit = 1024 * 1024; // Temporary limit: 1 MB
  char * contents = (char *) malloc (limit);
  StringBuilder sb;
  if (NULL == contents)
    {
      sb.sprintf (NTXT ("\nError: Cannot allocate %d bytes\n"), limit);
      result->store (0, NULL);
      result->store (1, sb.toString ()); // failure
      return result;
    }
  int fd = open (pathname, O_RDONLY);
  if (fd >= 0)
    {
      int64_t bytes = read_from_file (fd, contents, limit);
      close (fd);
      if (bytes >= limit)
	{
	  sb.sprintf (NTXT ("\nError: file size is greater than the limit (%d bytes)\n"), limit);
	  result->store (0, NULL);
	  result->store (1, sb.toString ()); // failure
	}
      else
	{
	  contents[bytes] = '\0'; // add string terminator
	  result->store (0, contents);
	  result->store (1, NULL); // success
	}
    }
  else
    {
      sb.sprintf (NTXT ("\nError: Cannot open file %s\n"), pathname);
      result->store (0, NULL);
      result->store (1, sb.toString ()); // failure
      free (contents);
    }
  return result;
}

/**
 * Writes the file named by the specified path name.
 * Temporary limitation: file should be "text only" and its size should be less than the 1 MB limit.
 * If the operation failed, then -1 is returned.
 * @param const char *pathname
 * @return int result  (written bytes)
 */
int
dbeWriteFile (const char *pathname, const char *contents)
{
  int result = -1; // error
  size_t len = 0;
  if (NULL != contents)
    len = strlen (contents);
  size_t limit = 1024 * 1024; // Temporary limit: 1 MB
  if (len > limit) return result;
  unlink (pathname);
  mode_t mode = S_IRUSR | S_IWUSR;
  int fd = open (pathname, O_WRONLY | O_CREAT | O_TRUNC, mode);
  if (fd >= 0)
    {  // replace file contents
      chmod (pathname, /*S_IRUSR || S_IWUSR*/ 0600); // rw for owner only
      ssize_t bytes = 0;
      if (len > 0)
	bytes = write (fd, contents, len);
      close (fd);
      result = (int) bytes;
    }
  return result;
}

/**
 * Gets list of running processes according to the specified format
 * Supported formats:
 * "/bin/ps -ef" - see 'man ps' for details
 * @param format
 * @return char * processes
 */
char *
dbeGetRunningProcesses (const char *format)
{
  if (format != NULL)
    return dbe_get_processes (format);
  return dbe_strdup (NTXT (""));
}

//
// Open experiment
//
char *
dbeOpenExperimentList (int /* dbevindex */, Vector<Vector<char*>*> *groups,
		       bool sessionRestart)
{
  if (sessionRestart)
    dbeSession->reset ();
  char *errstr;
  // Open experiments
  try
    {
      errstr = dbeSession->setExperimentsGroups (groups);
    }
  catch (ExperimentLoadCancelException *)
    {
      errstr = dbe_strdup (NTXT ("Experiment Load Cancelled"));
    }
  return errstr;
}

//
// Drop experiments
//
char *
dbeDropExperiment (int /* dbevindex */, Vector<int> *drop_index)
{
  for (int i = drop_index->size () - 1; i >= 0; i--)
    {
      char *ret = dbeSession->drop_experiment (drop_index->fetch (i));
      if (ret != NULL)
	  return ret;
    }
  return NULL;
}

/**
 * Read .er.rc file from the specified location
 * @param path
 * @return
 */
char *
dbeReadRCFile (int dbevindex, char* path)
{
  DbeView *dbev = getDbeView (dbevindex);
  char *err_msg = dbev->get_settings ()->read_rc (path);
  return err_msg;
}

char *
dbeSetExperimentsGroups (Vector<Vector<char*>*> *groups)
{
  int cmp_mode = dbeSession->get_settings ()->get_compare_mode ();
  if (groups->size () < 2)
    cmp_mode = CMP_DISABLE;
  else if (cmp_mode == CMP_DISABLE)
    cmp_mode = CMP_ENABLE;
  for (int i = 0;; i++)
    {
      DbeView *dbev = dbeSession->getView (i);
      if (dbev == NULL)
	break;
      dbev->get_settings ()->set_compare_mode (cmp_mode);
    }
  char *err_msg = dbeSession->setExperimentsGroups (groups);

  // automatically load machine model if applicable
  dbeDetectLoadMachineModel (0);
  return err_msg;
}

Vector<Vector<char*>*> *
dbeGetExperimensGroups ()
{
  Vector<Vector<char*>*> *grops = dbeSession->getExperimensGroups ();
  return grops;
}

Vector<int> *
dbeGetFounderExpId (Vector<int> *expIds)
{
  Vector<int> *ret = new Vector<int>(expIds->size ());
  for (int i = 0; i < expIds->size (); i++)
    {
      int expId = expIds->fetch (i);
      Experiment *exp = dbeSession->get_exp (expId);
      if (exp != NULL)
	{
	  int founderExpId = exp->getBaseFounder ()->getExpIdx ();
	  ret->store (i, founderExpId);
	}
      else
	ret->store (i, -1);
    }
  return ret;
}

Vector<int> *
dbeGetUserExpId (Vector<int> *expIds)
{
  // returns "User Visible" ids used for EXPID filters and timeline processes
  Vector<int> *ret = new Vector<int>(expIds->size ());
  for (int i = 0; i < expIds->size (); i++)
    {
      int expId = expIds->fetch (i);
      Experiment *exp = dbeSession->get_exp (expId);
      if (exp != NULL)
	{
	  int userExpId = exp->getUserExpId ();
	  ret->store (i, userExpId);
	}
      else
	ret->store (i, -1);
    }
  return ret;
}

//
// Get experiment groupid
//
Vector<int> *
dbeGetExpGroupId (Vector<int> *expIds)
{
  Vector<int> *ret = new Vector<int>(expIds->size ());
  for (int i = 0; i < expIds->size (); i++)
    {
      int expId = expIds->fetch (i);
      Experiment *exp = dbeSession->get_exp (expId);
      if (exp != NULL)
	{
	  int gId = exp->groupId;
	  ret->store (i, gId);
	}
      else
	ret->store (i, -1);
    }
  return ret;
}

Vector<char*> *
dbeGetExpsProperty (const char *prop_name)
{
  long nexps = dbeSession->nexps ();
  if (prop_name == NULL || nexps == 0)
    return NULL;
  Vector<char*> *list = new Vector<char*>(nexps);
  StringBuilder sb;
  int empty = 1;
  int prop = 99;
  if (strcasecmp (prop_name, NTXT ("ERRORS")) == 0)
    prop = 1;
  else if (strcasecmp (prop_name, NTXT ("WARNINGS")) == 0)
    prop = 2;
  if (prop < 3)
    {
      for (long i = 0; i < nexps; i++)
	{
	  Experiment *exp = dbeSession->get_exp (i);
	  char *nm = exp->get_expt_name ();
	  sb.setLength (0);
	  for (Emsg *emsg = (prop == 1) ? exp->fetch_errors () : exp->fetch_warnings ();
		  emsg; emsg = emsg->next)
	    sb.appendf (NTXT ("%s: %s\n"), STR (nm), STR (emsg->get_msg ()));
	  char *s = NULL;
	  if (sb.length () > 0)
	    {
	      s = sb.toString ();
	      empty = 0;
	    }
	  list->append (s);
	}
    }
  if (empty)
    {
      delete list;
      list = NULL;
    }
  return list;
}

//
// Get experiment names
//
Vector<char*> *
dbeGetExpName (int /*dbevindex*/)
{
  int size = dbeSession->nexps ();
  if (size == 0)
    return NULL;
  // Initialize Java String array
  Vector<char*> *list = new Vector<char*>(size);

  // Get experiment names
  for (int i = 0; i < size; i++)
    {
      Experiment *texp = dbeSession->get_exp (i);
      char *buf = dbe_sprintf (NTXT ("%s [%s]"), texp->get_expt_name (),
			       texp->utargname != NULL ? texp->utargname : GTXT ("(unknown)"));
      list->store (i, buf);
    }
  return list;
}

//
// Get experiment state
//
Vector<int> *
dbeGetExpState (int /* dbevindex */)
{
  int size = dbeSession->nexps ();
  if (size == 0)
    return NULL;
  // Initialize Java array
  Vector<int> *state = new Vector<int>(size);

  // Get experiment state
  for (int i = 0; i < size; i++)
    {
      Experiment *exp = dbeSession->get_exp (i);
      int set = EXP_SUCCESS;
      if (exp->get_status () == Experiment::FAILURE)
	set |= EXP_FAILURE;
      if (exp->get_status () == Experiment::INCOMPLETE)
	set |= EXP_INCOMPLETE;
      if (exp->broken)
	set |= EXP_BROKEN;
      if (exp->obsolete)
	set |= EXP_OBSOLETE;
      state->store (i, set);
    }
  return state;
}

//
// Get enabled experiment indices
//
Vector<bool> *
dbeGetExpEnable (int dbevindex)
{
  DbeView *dbev = getDbeView (dbevindex);
  int size = dbeSession->nexps ();
  if (dbev == NULL || size == 0)
    return NULL;

  // Get enabled experiment
  Vector<bool> *enable = new Vector<bool>(size);
  for (int i = 0; i < size; i++)
    {
      bool val = dbev->get_exp_enable (i) && !dbeSession->get_exp (i)->broken;
      enable->store (i, val);
    }
  return enable;
}

//
// Get enabled experiment indices
//
bool
dbeSetExpEnable (int dbevindex, Vector<bool> *enable)
{
  DbeView *dbev = getDbeView (dbevindex);
  bool ret = false;
  int size = dbeSession->nexps ();
  if (dbev == NULL || size == 0)
    return false;

  // set enable, as per input vector
  for (int i = 0; i < size; i++)
    if (!dbeSession->get_exp (i)->broken
	&& dbev->get_exp_enable (i) != enable->fetch (i))
      {
	dbev->set_exp_enable (i, enable->fetch (i));
	ret = true;
      }
  return ret;
}

//
// Get experiment info
//
Vector<char*> *
dbeGetExpInfo (int dbevindex)
{
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  int size = dbeSession->nexps ();
  if (size == 0)
    return NULL;

  // Initialize Java String array
  Vector<char*> *list = new Vector<char*>(size * 2 + 1);

  // Get experiment names
  Vector<LoadObject*> *text_segments = dbeSession->get_text_segments ();
  char *msg = pr_load_objects (text_segments, NTXT (""));
  delete text_segments;
  list->store (0, msg);
  int k = 1;
  for (int i = 0; i < size; i++)
    {
      Experiment *exp = dbeSession->get_exp (i);
      char *msg0 = pr_mesgs (exp->fetch_notes (), NTXT (""), NTXT (""));
      char *msg1 = pr_mesgs (exp->fetch_errors (), GTXT ("No errors\n"), NTXT (""));
      char *msg2 = pr_mesgs (exp->fetch_warnings (), GTXT ("No warnings\n"), NTXT (""));
      char *msg3 = pr_mesgs (exp->fetch_comments (), NTXT (""), NTXT (""));
      char *msg4 = pr_mesgs (exp->fetch_pprocq (), NTXT (""), NTXT (""));
      msg = dbe_sprintf (NTXT ("%s%s%s%s"), msg1, msg2, msg3, msg4);
      list->store (k++, msg0);
      list->store (k++, msg);
      free (msg1);
      free (msg2);
      free (msg3);
      free (msg4);
    }
  return list;
}

bool
dbeGetViewModeEnable ()
{
  return dbeSession->has_ompavail () || dbeSession->has_java ();
}

bool
dbeGetJavaEnable ()
{
  return dbeSession->has_java ();
}

int
dbeUpdateNotes (int dbevindex, int exp_id, int type, char* text, bool handle_file)
{
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  int size = dbeSession->nexps ();
  if (size == 0)
    return -1;
  Experiment *exp = dbeSession->get_exp (exp_id);
  return (type == 0) ? exp->save_notes (text, handle_file) : exp->delete_notes (handle_file);
}

//
// Get load object names
//
Vector<char*> *
dbeGetLoadObjectName (int /* dbevindex */)
{
  Vector<LoadObject*> *lobjs = dbeSession->get_text_segments ();
  int size = lobjs->size ();

  // Initialize Java String array
  Vector<char*> *list = new Vector<char*>(size);

  // Get load object names
  LoadObject *lo;
  int index;
  Vec_loop (LoadObject*, lobjs, index, lo)
  {
    list->store (index, dbe_strdup (lo->get_name ()));
  }
  delete lobjs;
  return list;
}

// XXX Will use later when order has to be passed too,
// Get complete List of tabs
//
Vector<void*> *
dbeGetTabList (int /* dbevindex */)
{
  //DbeView *dbev = getDbeView (dbevindex);
  //Vector<void*> *tabs = dbeSession->get_TabList();
  //return tabs;
  return NULL;
}

//
// Returns list of available tabs
//
Vector<void*> *
dbeGetTabListInfo (int dbevindex)
{
  int index;
  DispTab *dsptab;
  DbeView *dbev = getDbeView (dbevindex);

  // make sure the tabs are initialized properly
  dbev->get_settings ()->proc_tabs (theDbeApplication->rdtMode);
  Vector<DispTab*> *tabs = dbev->get_TabList ();

  // Get number of available tabs
  int size = 0;
  Vec_loop (DispTab*, tabs, index, dsptab)
  {
    if (!dsptab->available)
      continue;
    size++;
  }
  Vector<void*> *data = new Vector<void*>(2);
  Vector<int> *typelist = new Vector<int>(size);
  Vector<char*> *cmdlist = new Vector<char*>(size);
  Vector<int> *ordlist = new Vector<int>(size);

  // Build list of avaliable tabs
  int i = 0;

  Vec_loop (DispTab*, tabs, index, dsptab)
  {
    if (!dsptab->available)
      continue;
    typelist->store (i, dsptab->type);
    cmdlist->store (i, dbe_strdup (Command::get_cmd_str (dsptab->cmdtoken)));
    ordlist->store (i, dsptab->order);
    i++;
  }
  data->store (0, typelist);
  data->store (1, cmdlist);
  data->store (2, ordlist);
  return data;
}

// Return visibility state for all available tabs
//
Vector<bool> *
dbeGetTabSelectionState (int dbevindex)
{
  int index;
  DispTab *dsptab;
  DbeView *dbev = getDbeView (dbevindex);
  Vector<DispTab*> *tabs = dbev->get_TabList ();

  // Get number of available tabs
  int size = 0;
  Vec_loop (DispTab*, tabs, index, dsptab)
  {
    if (!dsptab->available)
      continue;
    size++;
  }
  Vector<bool> *states = new Vector<bool>(size);

  // Get visibility bit for all available tabs
  int i = 0;
  Vec_loop (DispTab*, tabs, index, dsptab)
  {
    if (!dsptab->available)
      continue;
    states->store (i++, dsptab->visible);
  }
  return states;
}

// Set visibility bit for a tab
void
dbeSetTabSelectionState (int dbevindex, Vector<bool> *selected)
{
  int index;
  DispTab *dsptab;
  DbeView *dbev = getDbeView (dbevindex);
  Vector<DispTab*> *tabs = dbev->get_TabList ();
  int i = 0;
  Vec_loop (DispTab*, tabs, index, dsptab)
  {
    if (!dsptab->available)
      continue;
    dsptab->visible = selected->fetch (i++);
  }
}

// Return visibility state for all available MemObj tabs
Vector<bool> *
dbeGetMemTabSelectionState (int dbevindex)
{
  int index;
  bool dsptab;
  DbeView *dbev = getDbeView (dbevindex);
  Vector<bool> *memtabs = dbev->get_MemTabState ();

  // set the output vector
  int size = memtabs->size ();
  Vector<bool> *states = new Vector<bool>(size);

  // Get visibility bit for all available tabs
  int i = 0;
  Vec_loop (bool, memtabs, index, dsptab)
  {
    states->store (i++, dsptab);
  }
  return states;
}

// Set visibility bit for a memory tab
//
void
dbeSetMemTabSelectionState (int dbevindex, Vector<bool> *selected)
{
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  dbev->set_MemTabState (selected);
}

// Return visibility state for all available index tabs
Vector<bool> *
dbeGetIndxTabSelectionState (int dbevindex)
{
  int index;
  bool dsptab;
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  Vector<bool> *indxtabs = dbev->get_IndxTabState ();

  // set the output vector
  int size = indxtabs->size ();
  Vector<bool> *states = new Vector<bool>(size);

  // Get visibility bit for all available tabs
  int i = 0;
  Vec_loop (bool, indxtabs, index, dsptab)
  {
    states->store (i++, dsptab);
  }
  return states;
}

// Set visibility bit for a index tab
void
dbeSetIndxTabSelectionState (int dbevindex, Vector<bool> *selected)
{
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  dbev->set_IndxTabState (selected);
}

//
// Get search path
//
Vector<char*> *
dbeGetSearchPath (int /*dbevindex*/)
{
  Vector<char*> *path = dbeSession->get_search_path ();
  int size = path->size ();
  Vector<char*> *list = new Vector<char*>(size);
  int index;
  char *name;
  Vec_loop (char*, path, index, name)
  {
    list->store (index, dbe_strdup (name));
  }
  return list;
}

//
// Set search path
//
void
dbeSetSearchPath (int /*dbevindex*/, Vector<char*> *path)
{
  dbeSession->set_search_path (path, true);
  return;
}

//
// Get pathmaps
//
Vector<void*> *
dbeGetPathmaps (int /*dbevindex*/)
{
  int index;
  pathmap_t *pthmap;
  Vector<pathmap_t*> *path = dbeSession->get_pathmaps ();
  int size = path->size ();
  Vector<void*> *data = new Vector<void*>(2);
  Vector<char*> *oldlist = new Vector<char*>(size);
  Vector<char*> *newlist = new Vector<char*>(size);

  int i = 0;
  Vec_loop (pathmap_t*, path, index, pthmap)
  {
    oldlist->store (i, dbe_strdup (pthmap->old_prefix));
    newlist->store (i, dbe_strdup (pthmap->new_prefix));
    i++;
  }
  data->store (0, oldlist);
  data->store (1, newlist);
  return data;
} // dbeGetPathmaps

char *
dbeSetPathmaps (Vector<char*> *from, Vector<char*> *to)
{
  if (from == NULL || to == NULL || from->size () != to->size ())
    return dbe_strdup ("dbeSetPathmaps: size of 'from' does not match for size of 'to'\n");
  Vector<pathmap_t*> *newPath = new Vector<pathmap_t*>(from->size ());
  for (int i = 0, sz = from->size (); i < sz; i++)
    {
      char *err = Settings::add_pathmap (newPath, from->get (i), to->get (i));
      if (err)
	{
	  newPath->destroy ();
	  delete newPath;
	  return err;
	}
    }
  dbeSession->set_pathmaps (newPath);
  return NULL;
}

//
// Add pathmap
char *
dbeAddPathmap (int /* dbevindex */, char *from, char *to)
{
  Vector<pathmap_t*> *pmp = dbeSession->get_pathmaps ();
  char *err = Settings::add_pathmap (pmp, from, to);
  return err;
}

//
// Get error/warning string of data
char *
dbeGetMsg (int dbevindex, int type)
{
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  char *msgstr = NULL;
  if (type == ERROR_MSG)
    msgstr = dbev->get_error_msg ();
  else if (type == WARNING_MSG)
    msgstr = dbev->get_warning_msg ();
  else if (type == PSTAT_MSG)
    msgstr = dbev->get_processor_msg (PSTAT_MSG);
  else if (type == PWARN_MSG)
    msgstr = dbev->get_processor_msg (PWARN_MSG);
  return msgstr ? dbe_strdup (msgstr) : NULL;
}

// Create a DbeView, given new index, and index of view to clone
int
dbeInitView (int id, int cloneid)
{
  return dbeSession->createView (id, cloneid);
}


// Delete a DbeView
void
dbeDeleteView (int dbevindex)
{
  dbeSession->dropView (dbevindex);
  return;
} // dbeDeleteView

MetricList *
dbeGetMetricListV2 (int dbevindex, MetricType mtype,
		    Vector<int> *type, Vector<int> *subtype, Vector<bool> *sort,
		    Vector<int> *vis, Vector<char*> *cmd,
		    Vector<char*> *expr_spec, Vector<char*> *legends)
{
  DbeView *dbev = dbeSession->getView (dbevindex);
  MetricList *mlist = new MetricList (mtype);
  for (int i = 0, msize = type->size (); i < msize; i++)
    {
      BaseMetric *bm = dbev->register_metric_expr ((BaseMetric::Type) type->fetch (i),
						   cmd->fetch (i),
						   expr_spec->fetch (i));
      Metric *m = new Metric (bm, (Metric::SubType) subtype->fetch (i));
      m->set_raw_visbits (vis->fetch (i));
      if (m->legend == NULL)
	m->legend = dbe_strdup (legends->fetch (i));
      mlist->append (m);
      if (sort->fetch (i))
	{
	  mlist->set_sort_ref_index (i);
	}
    }
  return mlist;
}

static Vector<void*> *
dbeGetMetricList (MetricList *mlist)
{
  int clock_val = dbeSession->get_clock (-1);
  Vector<Metric*> *items = mlist->get_items ();
  int size = items->size ();

  Vector<int> *type = new Vector<int>(size);
  Vector<int> *subtype = new Vector<int>(size);
  Vector<int> *clock = new Vector<int>(size);
  Vector<int> *flavors = new Vector<int>(size);
  Vector<int> *vis = new Vector<int>(size);
  Vector<bool> *sorted = new Vector<bool>(size);
  Vector<int> *value_styles = new Vector<int>(size);
  Vector<char*> *aux = new Vector<char*>(size);
  Vector<char*> *name = new Vector<char*>(size);
  Vector<char*> *abbr = new Vector<char*>(size);
  Vector<char*> *comd = new Vector<char*>(size);
  Vector<char*> *unit = new Vector<char*>(size);
  Vector<char*> *user_name = new Vector<char*>(size);
  Vector<char*> *expr_spec = new Vector<char*>(size);
  Vector<char*> *legend = new Vector<char*>(size);
  Vector<int> *valtype = new Vector<int>(size);
  Vector<char*> *data_type_name = new Vector<char*>(size);
  Vector<char*> *data_type_uname = new Vector<char*>(size);
  Vector<char*> *short_desc = new Vector<char*>(size);

  int sort_index = mlist->get_sort_ref_index ();
  // Fill metric elements
  for (int i = 0; i < size; i++)
    {
      Metric *m = items->fetch (i);
      type->append (m->get_type ());
      subtype->append (m->get_subtype ());
      flavors->append (m->get_flavors ());
      abbr->append (dbe_strdup (m->get_abbr ()));
      char *s = m->get_abbr_unit ();
      if ((m->get_visbits () & VAL_RATIO) != 0)
	s = NULL;
      unit->append (dbe_strdup (s ? s : NTXT ("")));
      value_styles->append (m->get_value_styles ());
      vis->append (m->get_visbits ());
      sorted->append (i == sort_index);
      clock->append (m->get_type () == Metric::HWCNTR ? clock_val
		     : m->get_clock_unit ());
      aux->append (dbe_strdup (m->get_aux ()));
      name->append (dbe_strdup (m->get_name ()));
      comd->append (dbe_strdup (m->get_cmd ()));
      user_name->append (dbe_strdup (m->get_username ()));
      expr_spec->append (dbe_strdup (m->get_expr_spec ()));
      legend->append (dbe_strdup (m->legend));
      valtype->append (m->get_vtype2 ());

      char* _data_type_name = NULL;
      char* _data_type_uname = NULL;
      int data_type = m->get_packet_type ();
      if (data_type >= 0 && data_type < DATA_LAST)
	{
	  _data_type_name = dbe_strdup (get_prof_data_type_name (data_type));
	  _data_type_uname = dbe_strdup (get_prof_data_type_uname (data_type));
	}
      data_type_name->append (_data_type_name);
      data_type_uname->append (_data_type_uname);

      char* _short_desc = NULL;
      if (m->get_type () == Metric::HWCNTR)
	{
	  Hwcentry * hwctr = m->get_hw_ctr ();
	  if (hwctr)
	    _short_desc = dbe_strdup (hwctr->short_desc);
	}
      short_desc->append (_short_desc);
    }

  // Set Java array
  Vector<void*> *data = new Vector<void*>(16);
  data->append (type);
  data->append (subtype);
  data->append (clock);
  data->append (flavors);
  data->append (value_styles);
  data->append (user_name);
  data->append (expr_spec);
  data->append (aux);
  data->append (name);
  data->append (abbr);
  data->append (comd);
  data->append (unit);
  data->append (vis);
  data->append (sorted);
  data->append (legend);
  data->append (valtype);
  data->append (data_type_name);
  data->append (data_type_uname);
  data->append (short_desc);
  return data;
}

Vector<void*> *
dbeGetRefMetricsV2 ()
{
  MetricList *mlist = new MetricList (MET_NORMAL);
  Vector<BaseMetric*> *base_metrics = dbeSession->get_base_reg_metrics ();
  for (long i = 0, sz = base_metrics->size (); i < sz; i++)
    {
      BaseMetric *bm = base_metrics->fetch (i);
      Metric *m;
      if (bm->get_flavors () & Metric::EXCLUSIVE)
	{
	  m = new Metric (bm, Metric::EXCLUSIVE);
	  m->enable_all_visbits ();
	  mlist->append (m);
	}
      else if (bm->get_flavors () & BaseMetric::STATIC)
	{
	  m = new Metric (bm, BaseMetric::STATIC);
	  m->enable_all_visbits ();
	  mlist->append (m);
	}
    }
  Vector<void*> *data = dbeGetMetricList (mlist);
  delete mlist;
  return data;
}

Vector<void*> *
dbeGetCurMetricsV2 (int dbevindex, MetricType mtype)
{
  DbeView *dbev = dbeSession->getView (dbevindex);
  MetricList *mlist = dbev->get_metric_list (mtype);
  Vector<void*> *data = dbeGetMetricList (mlist);
  return data;
}

// YXXX we should refactor Metrics/BaseMetrics so that it no longer uses VAL_VALUE to enable time.
static int
convert_visbits_to_gui_checkbox_bits (BaseMetric *bm, const int visbits)
{
  // The purpose of this function is to handle the following case:
  //    When bm->get_value_styles() supports VAL_TIMEVAL but not VAL_VALUE
  //        Metric and BaseMetric use (visbits&VAL_VALUE) to enable time.
  //    However, the Overview expects the VAL_TIMEVAL bit to enable time.
  // Inputs: visbits as returned by BaseMetric->get_default_visbits();
  // Returns: valuebits, as used for checks in GUI checkboxes
  int valuebits = visbits;
  const int value_styles = bm->get_value_styles ();
  if ((value_styles & VAL_TIMEVAL) && // supports time
      !(value_styles & VAL_VALUE))
    { // but not value
      unsigned mask = ~(VAL_VALUE | VAL_TIMEVAL);
      valuebits = (unsigned) valuebits & mask; // clear bits
      if (visbits & VAL_VALUE)
	valuebits |= VAL_TIMEVAL; // set VAL_TIMEVAL
      if (visbits & VAL_TIMEVAL)
	valuebits |= VAL_TIMEVAL; // weird, this should never happen.
    }
  return valuebits;
}

static Vector<void*> *
dbeGetMetricTreeNode (BaseMetricTreeNode* curr, MetricList *mlist,
		      bool include_unregistered, bool has_clock_profiling_data)
{
  Vector<void*> *data = new Vector<void*>(2);

  // ----- fields
  Vector<void*> *fields = new Vector<void*>();
  Vector<char*> *name = new Vector<char*>(1);
  Vector<char*> *username = new Vector<char*>(1);
  Vector<char*> *description = new Vector<char*>(1);
  Vector<int> * flavors = new Vector<int>(1);
  Vector<int> * vtype = new Vector<int>(1);
  Vector<int> * vstyles_capable = new Vector<int>(1);

  // Specifies which default styles should be enabled when a metric is enabled.
  // Also, specifies if metric should start enabled
  Vector<int> *vstyles_e_defaults = new Vector<int>(1);
  Vector<int> *vstyles_i_defaults = new Vector<int>(1);
  Vector<bool> *registered = new Vector<bool>(1);
  Vector<bool> *aggregation = new Vector<bool>(1);
  Vector<bool> *has_value = new Vector<bool>(1);
  Vector<char*> *unit = new Vector<char*>(1);
  Vector<char*> *unit_uname = new Vector<char*>(1);

  char *_name = NULL;
  char *_username = NULL;
  char *_description = dbe_strdup (curr->get_description ());

  // BaseMetric fields
  int _flavors = 0; // SubType bitmask: (e.g. EXCLUSIVE)
  int _vtype = 0; // ValueTag: e.g. VT_INT, VT_FLOAT, ...
  int _vstyles_capable = 0; // ValueType bitmask, e.g. VAL_TIMEVAL
  int _vstyles_e_default_values = 0; // default visibility settings, exclusive/static
  int _vstyles_i_derault_values = 0; // default visibility settings, inclusive
  bool _registered = curr->is_registered ()
	  || curr->get_num_registered_descendents () > 0;
  bool _aggregation = curr->is_composite_metric ()
	  && curr->get_num_registered_descendents () > 0;
  bool _has_value = false; //not used yet; for nodes that don't have metrics
  char *_unit = NULL;
  char *_unit_uname = NULL;

  BaseMetric *bm = curr->get_BaseMetric ();
  if (bm)
    {
      _name = dbe_strdup (bm->get_cmd ());
      _username = dbe_strdup (bm->get_username ());
      if (!include_unregistered && !curr->is_registered ())
	abort ();
      _flavors = bm->get_flavors ();
      _vtype = bm->get_vtype ();
      _vstyles_capable = bm->get_value_styles ();
      int e_visbits = bm->get_default_visbits (BaseMetric::EXCLUSIVE);
      int i_visbits = bm->get_default_visbits (BaseMetric::INCLUSIVE);
      _vstyles_e_default_values = convert_visbits_to_gui_checkbox_bits (bm, e_visbits);
      _vstyles_i_derault_values = convert_visbits_to_gui_checkbox_bits (bm, i_visbits);
      // not all metrics shown in er_print cmd line should be selected in the GUI at startup:
      if (has_clock_profiling_data && bm->get_hw_ctr ())
	{
	  bool hide = true; // by default, hide HWCs
	  if (dbe_strcmp (bm->get_hw_ctr ()->name, NTXT ("c_stalls")) == 0 ||
	      dbe_strcmp (bm->get_hw_ctr ()->name, NTXT ("K_c_stalls")) == 0)
	    {
	      bool is_time = (bm->get_value_styles () & VAL_TIMEVAL) != 0;
	      if (is_time)
		// By default, show time variant of c_stalls
		hide = false;
	    }
	  if (hide)
	    {
	      _vstyles_e_default_values |= VAL_HIDE_ALL;
	      _vstyles_i_derault_values |= VAL_HIDE_ALL;
	    }
	}
    }
  else
    {
      // not a base metric
      _name = dbe_strdup (curr->get_name ());
      _username = dbe_strdup (curr->get_user_name ());
     if (curr->get_unit ())
	{ // represents a value
	  _has_value = true;
	  _unit = dbe_strdup (curr->get_unit ());
	  _unit_uname = dbe_strdup (curr->get_unit_uname ());
	}
    }
  name->append (_name); // unique id string (dmetrics cmd)
  username->append (_username); // user-visible name
  description->append (_description);
  flavors->append (_flavors); // SubType bitmask: (e.g. EXCLUSIVE)
  vtype->append (_vtype); // ValueTag: e.g. VT_INT, VT_FLOAT, ...
  vstyles_capable->append (_vstyles_capable); // ValueType bitmask, e.g. VAL_TIMEVAL
  vstyles_e_defaults->append (_vstyles_e_default_values);
  vstyles_i_defaults->append (_vstyles_i_derault_values);
  registered->append (_registered); // is a "live" metric
  aggregation->append (_aggregation); // value derived from children nodes
  has_value->append (_has_value); // value generated from other source
  unit->append (_unit); // See BaseMetric.h, e.g. UNIT_SECONDS
  unit_uname->append (_unit_uname); //See BaseMetric.h,

  fields->append (name);
  fields->append (username);
  fields->append (description);
  fields->append (flavors);
  fields->append (vtype);
  fields->append (vstyles_capable);
  fields->append (vstyles_e_defaults);
  fields->append (vstyles_i_defaults);
  fields->append (registered);
  fields->append (aggregation);
  fields->append (has_value);
  fields->append (unit);
  fields->append (unit_uname);
  data->append (fields);

  // ----- children
  Vector<BaseMetricTreeNode*> *children = curr->get_children ();
  int num_children = children->size ();
  Vector<void*> *children_list = new Vector<void*>(num_children);
  BaseMetricTreeNode *child_node;
  int index;

  Vec_loop (BaseMetricTreeNode*, children, index, child_node)
  {
    if (include_unregistered /* fetch everything */
	|| child_node->is_registered ()
	|| child_node->get_num_registered_descendents () > 0)
      {
	//Special case for metrics that aren't registered
	// but have registered children
	// Linux example: Total Time is unregistered, CPU Time is registered
	if (!include_unregistered && /* not fetching everything */
	    !child_node->is_registered () &&
	    (child_node->get_BaseMetric () != NULL ||
	     child_node->is_composite_metric ()))
	  {
	    Vector<BaseMetricTreeNode*> *registered_descendents =
		    new Vector<BaseMetricTreeNode*>();
	    child_node->get_nearest_registered_descendents (registered_descendents);
	    int idx2;
	    BaseMetricTreeNode*desc_node;
	    Vec_loop (BaseMetricTreeNode*, registered_descendents, idx2, desc_node)
	    {
	      Vector<void*> *desc_data;
	      desc_data = dbeGetMetricTreeNode (desc_node, mlist,
				include_unregistered, has_clock_profiling_data);
	      children_list->append (desc_data);
	    }
	    delete registered_descendents;
	    continue;
	  }
	Vector<void*> *child_data;
	child_data = dbeGetMetricTreeNode (child_node, mlist,
				include_unregistered, has_clock_profiling_data);
	children_list->append (child_data);
      }
  }
  data->append (children_list);
  return data;
}

Vector<void*> *
dbeGetRefMetricTree (int dbevindex, bool include_unregistered)
{
  DbeView *dbev = dbeSession->getView (dbevindex);
  MetricList *mlist = dbev->get_metric_list (MET_NORMAL);
  bool has_clock_profiling_data = false;
  for (long i = 0, sz = mlist->get_items ()->size (); i < sz; i++)
    {
      Metric *m = mlist->get_items ()->fetch (i);
      if (m->get_packet_type () == DATA_CLOCK)
	{
	  has_clock_profiling_data = true;
	  break;
	}
    }
  BaseMetricTreeNode *curr = dbeSession->get_reg_metrics_tree ();
  return dbeGetMetricTreeNode (curr, mlist, include_unregistered, has_clock_profiling_data);
}

static Vector<void*> *
dbeGetTableDataV2Data (DbeView *dbev, Hist_data *data);

static Vector<void*> *dbeGetTableDataOneColumn (Hist_data *data, int met_ind);
static Vector<void*> *
dbeGetTableDataOneColumn (DbeView *dbev, Vector<Hist_data::HistItem*> *data,
			  ValueTag vtype, int metricColumnNumber);

static hrtime_t
dbeCalcGroupDuration (int grInd)
{
  int thisGroupSize = 1;
  hrtime_t max_time = 0;
  Experiment *exp;
  if (dbeSession->expGroups->size () > 0)
    {
      ExpGroup *grp = dbeSession->expGroups->fetch (grInd);
      thisGroupSize = grp->exps->size ();
      for (int ii = 0; ii < thisGroupSize; ii++)
	{
	  exp = grp->exps->fetch (ii);
	  Vector<DataDescriptor*> *ddscr = exp->getDataDescriptors ();
	  delete ddscr;// getDataDescriptors() forces reading of experiment data
	  if (exp != NULL)
	    {
	      hrtime_t tot_time = exp->getLastEvent () - exp->getStartTime ()
		      + exp->getRelativeStartTime ();
	      if (max_time < tot_time)
		max_time = tot_time;
	    }
	}
    }
  else
    {
      exp = dbeSession->get_exp (0);
      if (exp != NULL)
	max_time = exp->getLastEvent () - exp->getStartTime ();
    }
  return max_time; //nanoseconds
}

static hrtime_t
dbeCalcGroupGCDuration (int grInd)
{
  int thisGroupSize = 1;
  hrtime_t tot_time = 0;
  Experiment *exp;
  if (dbeSession->expGroups->size () > 0)
    {
      ExpGroup *grp = dbeSession->expGroups->fetch (grInd);
      thisGroupSize = grp->exps->size ();
      for (int ii = 0; ii < thisGroupSize; ii++)
	{
	  exp = grp->exps->fetch (ii);
	  Vector<DataDescriptor*> *ddscr = exp->getDataDescriptors ();
	  delete ddscr; // getDataDescriptors() forces reading of experiment data
	  if (exp != NULL)
	    tot_time += exp->getGCDuration ();
	}
    }
  else
    {
      exp = dbeSession->get_exp (0);
      if (exp != NULL)
	tot_time = exp->getGCDuration ();
    }
  return tot_time; //nanoseconds
}

Vector<void*> *
dbeGetRefMetricTreeValues (int dbevindex, Vector<char *> *metric_cmds,
			   Vector<char *> *non_metric_cmds)
{
  DbeView *dbev = dbeSession->getView (dbevindex);
  // valueTable will have N "columns" of values, where N is the number of
  //   requested metrics and non-metrics.
  // Each column will be a vector with M "rows", where M is the number of
  //   compare groups.
  // highlightTable mirrors the structure of valueTable.  Each cell indicates
  //   if the corresponding valueTable cell is "hot" (interesting)
  int numMetrics = metric_cmds->size ();
  int numNonMetrics = non_metric_cmds->size ();
  int totalColumns = numMetrics + numNonMetrics; // Columns
  Vector<void*> *valueTable = new Vector<void*>(totalColumns);
  Vector<void*> *highlightTable = new Vector<void*>(totalColumns);

  // the return value consists of the two tables discussed above.
  Vector<void*> *rc = new Vector<void*>(2);
  rc->append (valueTable);
  rc->append (highlightTable);
  if (dbeSession->nexps () == 0)
    { // no experiments are loaded
      for (int jj = 0; jj < totalColumns; jj++)
	{
	  Vector<void *> *columnData = new Vector<void *>();
	  valueTable->append (columnData);
	  highlightTable->append (columnData);
	}
      return rc;
    }

  int ngroups = dbeSession->expGroups->size (); // Rows (one per compare group)
  if (ngroups == 0 || !dbev->comparingExperiments ())
    ngroups = 1;

  Vector<double> *groupTotalTime = new Vector<double>(ngroups);
  Vector<double> *groupCpuTime = new Vector<double>(ngroups);
  // initialize highlight table
  for (int ii = 0; ii < totalColumns; ii++)
    { // metrics
      Vector<bool> *columnData = new Vector<bool>(ngroups);
      highlightTable->append (columnData);
      for (int grInd = 0; grInd < ngroups; grInd++)
	columnData->store (grInd, false); // non-highlight
    }

  if (numMetrics > 0)
    {
      MetricList *bmlist;
      // set bmlist to list of requested base metrics
      BaseMetricTreeNode *root = dbeSession->get_reg_metrics_tree ();
      int index;
      char *mcmd;
      Vector<BaseMetric*> *base_metrics = new Vector<BaseMetric*>();
      Vec_loop (char *, metric_cmds, index, mcmd)
      {
	BaseMetricTreeNode *bmt_node = root->find (mcmd);
	if (!bmt_node)
	  abort (); //YXXX weird
	BaseMetric * baseNetric = bmt_node->get_BaseMetric ();
	if (!baseNetric)
	  abort ();
	base_metrics->append (baseNetric);
      }

      // MET_INDX will create MetricList of Exclusive metrics
      bmlist = new MetricList (base_metrics, MET_SRCDIS);

      // Use the Function List to fetch <Total> values
      // A temporary table, v_totals, stores <total> by group
      Vector<Hist_data::HistItem *> *v_totals = new Vector<Hist_data::HistItem *>(ngroups);
      for (int grInd = 0; grInd < ngroups; grInd++)
	{
	  MetricList *mlist;
	  if (ngroups > 1)
	    mlist = dbev->get_compare_mlist (bmlist, grInd);
	  else
	    mlist = bmlist;
	  if (mlist->size () != numMetrics)
	    abort ();

	  Hist_data *data;
	  data = dbev->get_hist_data (mlist, Histable::FUNCTION, 0,
				      Hist_data::ALL);
	  Hist_data::HistItem * totals = data->get_totals ();
	  v_totals->append (totals);
	}

      // store the Hist_data totals in valueTable
      {
	Metric *mitem;
	int index;
	Vec_loop (Metric*, bmlist->get_items (), index, mitem)
	{
	  Vector<void*> * columnData = dbeGetTableDataOneColumn (dbev,
					  v_totals, mitem->get_vtype (), index);
	  valueTable->append (columnData);
	}
      }

      // 7207285: hack for hwc profiling cycles conversion:
      {
	Metric *mitem;
	int index;
	Vec_loop (Metric*, bmlist->get_items (), index, mitem)
	{
	  if (mitem->is_time_val ()
	      && mitem->get_vtype () == VT_ULLONG)
	    {
	      Vector<long long> *cycleValues = (Vector<long long> *)valueTable->fetch (index);
	      Vector<double> *timeValues = new Vector<double>(ngroups);
	      assert (cycleValues->size () == ngroups);
	      for (int grInd = 0; grInd < ngroups; grInd++)
		{
		  long long cycles = cycleValues->fetch (grInd);
		  int expId;
		  if (dbeSession->expGroups->size () > 0)
		    {
		      ExpGroup *gr = dbeSession->expGroups->fetch (grInd);
		      Experiment *exp = gr->exps->fetch (0);
		      expId = exp->getExpIdx ();
		    }
		  else
		    expId = -1;
		  int clock = dbeSession->get_clock (expId);
		  double time;
		  if (clock)
		    time = cycles / (1.e+6 * clock);
		  else
		    time = cycles; //weird
		  timeValues->store (grInd, time);
		}
	      delete cycleValues;
	      valueTable->store (index, timeValues);
	    }
	}
      }

      // Scan metrics for best measure of CPU time
      int bestCpuTimeIndx = -1;
      {
	Metric *mitem;
	int index;
	Vec_loop (Metric*, bmlist->get_items (), index, mitem)
	{
	  BaseMetric::Type type = mitem->get_type ();
	  if (type == BaseMetric::CP_KERNEL_CPU)
	    {
	      bestCpuTimeIndx = index;
	      break; // CP_KERNEL_CPU trumps other measures
	    }
	  if (type == BaseMetric::CP_TOTAL_CPU)
	    {
	      // clock profiling CPU time
	      bestCpuTimeIndx = index;
	      // keep looking in case CP_KERNEL_CPU also exists
	      continue;
	    }

	  bool isTime = ((mitem->get_value_styles () & VAL_TIMEVAL) != 0);
	  bool isHwcCycles = (type == BaseMetric::HWCNTR
			      && (dbe_strcmp (mitem->get_aux (), "cycles") == 0)
			      && isTime);
	  if (isHwcCycles)
	    if (bestCpuTimeIndx < 0)
	      bestCpuTimeIndx = index;
	}
	if (bestCpuTimeIndx >= 0)
	  {
	    Vector<double> *timeValues = (Vector<double> *)valueTable->fetch (bestCpuTimeIndx);
	    if (timeValues->type () == VEC_DOUBLE)
	      for (int grInd = 0; grInd < ngroups; grInd++)
		{
		  double time = timeValues->fetch (grInd);
		  groupCpuTime->append (time);
		}
	  }
      }

      // Scan metrics for Total Thread time
      {
	Metric *mitem;
	int index;
	Vec_loop (Metric*, bmlist->get_items (), index, mitem)
	{
	  BaseMetric::Type type = mitem->get_type ();
	  if (type == BaseMetric::CP_TOTAL)
	    {
	      Vector<double> *timeValues = (Vector<double> *)valueTable->fetch (index);
	      if (timeValues->type () != VEC_DOUBLE)
		continue; // weird
	      for (int grInd = 0; grInd < ngroups; grInd++)
		{
		  double time = timeValues->fetch (grInd);
		  groupTotalTime->append (time);
		}
	      break;
	    }
	}
      }

      // highlight metrics based on cpu time
#define CPUSEC_PERCENT_THRESHOLD            10.0
#define HWC_OVERFLOWS_PER_CPUSEC_THRESHOLD  15
      {
	Metric *mitem;
	int index;
	Vec_loop (Metric*, bmlist->get_items (), index, mitem)
	{
	  BaseMetric::Type type = mitem->get_type ();
	  Vector<bool> * columnHilites = (Vector<bool> *)highlightTable->fetch (index);

	  // always highlight the following
	  if (index == bestCpuTimeIndx)
	    {
	      for (int grInd = 0; grInd < ngroups; grInd++)
		columnHilites->store (grInd, true);
	      continue;
	    }

	  // skip certain types
	  bool typeIsCycles = (type == BaseMetric::HWCNTR
		       && dbe_strcmp (mitem->get_aux (), NTXT ("cycles")) == 0);
	  bool typeIsInsts = (type == BaseMetric::HWCNTR
			&& dbe_strcmp (mitem->get_aux (), NTXT ("insts")) == 0);
	  if (type == BaseMetric::CP_TOTAL
	      || type == BaseMetric::CP_TOTAL_CPU
	      || type == BaseMetric::CP_LMS_USER
	      || type == BaseMetric::CP_LMS_SYSTEM
	      || type == BaseMetric::CP_LMS_TRAP
	      || type == BaseMetric::CP_LMS_USER_LOCK
	      || type == BaseMetric::CP_LMS_SLEEP
	      || type == BaseMetric::CP_KERNEL_CPU
	      || type == BaseMetric::OMP_WORK
	      || typeIsCycles
	      || typeIsInsts
	      // || type == BaseMetric::CP_TOTAL_WAIT
	      )
	    continue; // types we never highlight

	  // for time values, compare against CPUSEC_PERCENT_THRESHOLD
	  bool isTime = ((mitem->get_value_styles () & VAL_TIMEVAL) != 0);
	  if (isTime)
	    {
	      if (groupCpuTime->size () == 0)
		continue; // no time to use as reference
	      Vector<double> *timeValues = (Vector<double> *)valueTable->fetch (index);
	      if (timeValues->type () != VEC_DOUBLE)
		continue; // weird
	      for (int grInd = 0; grInd < ngroups; grInd++)
		{
		  double thistime = timeValues->fetch (grInd);
		  double usertime = groupCpuTime->fetch (grInd);
		  if (thistime / (CPUSEC_PERCENT_THRESHOLD / 100) > usertime)
		    columnHilites->store (grInd, true);
		}
	      continue;
	    }

	  // for HWC event counts, look at rate of events
	  if (type == BaseMetric::HWCNTR)
	    {
	      Hwcentry *hwctr = mitem->get_hw_ctr ();
	      if (!hwctr)
		continue; // weird
	      if (!hwctr->metric)
		continue; // raw counter
	      if (groupCpuTime->size () == 0)
		continue; // no time to use as reference
	      if (mitem->get_base_metric ()->get_dependent_bm ())
		continue; // has a derived time metric, only flag time version
	      Vector<long long> *llValues = (Vector<long long> *)valueTable->fetch (index);
	      if (llValues->type () != VEC_LLONG)
		continue; // weird
	      int overflowVal = hwctr->val; //overflow count
	      if (!overflowVal)
		continue; // weird
	      if (overflowVal > (4000000))
		// cut off events that are very frequent like loads/stores
		// 4Ghz * (0.01 seconds/event) / (4000000 events/overflow) = 10 cycles
		continue;
	      // for HWCs we could base it on the overflow rate
	      for (int grInd = 0; grInd < ngroups; grInd++)
		{
		  double thisVal = llValues->fetch (grInd);
		  thisVal /= overflowVal;
		  double usertime = groupCpuTime->fetch (grInd);
		  if (thisVal > usertime * HWC_OVERFLOWS_PER_CPUSEC_THRESHOLD)
		    columnHilites->store (grInd, true);
		}
	      continue;
	    }

	  // check for non-zero counts of the following
	  if (type == BaseMetric::DEADLOCKS ||
	      type == BaseMetric::RACCESS ||
	      type == BaseMetric::HEAP_ALLOC_BYTES ||
	      type == BaseMetric::HEAP_LEAK_BYTES)
	    {
	      Vector<long long> *llValues = (Vector<long long> *)valueTable->fetch (index);
	      if (llValues->type () != VEC_LLONG)
		continue; // weird
	      for (int grInd = 0; grInd < ngroups; grInd++)
		{
		  long long thisVal = llValues->fetch (grInd);
		  if (thisVal)
		    columnHilites->store (grInd, true);
		}
	      continue;
	    }
	  // continue adding cases as needed
	}
      }
    }

  if (numNonMetrics > 0)
    {
      int index;
      char *mcmd;
      Vec_loop (char *, non_metric_cmds, index, mcmd)
      {
	if (dbe_strcmp (mcmd, NTXT ("YXXX_TOTAL_TIME_PLUS_THREADS")) == 0
	    && groupCpuTime->size () == ngroups)
	  {
	    Vector<char *> *columnData = new Vector<char *>(ngroups);
	    for (int grInd = 0; grInd < ngroups; grInd++)
	      {
		double totaltime = groupTotalTime->fetch (grInd);
		columnData->append (dbe_sprintf (NTXT ("%0.3f %s"), totaltime, GTXT ("Seconds")));
	      }
	    valueTable->append (columnData);
	  }
	else if (dbe_strcmp (mcmd, L1_DURATION) == 0)
	  {
	    Vector<double> *columnData = new Vector<double>(ngroups);
	    for (int grInd = 0; grInd < ngroups; grInd++)
	      {
		hrtime_t duration = dbeCalcGroupDuration (grInd);
		double seconds = duration * 1.e-9;
		columnData->append (seconds);
	      }
	    valueTable->append (columnData);
	  }
	else if (dbe_strcmp (mcmd, L1_GCDURATION) == 0)
	  {
	    Vector<double> *columnData = new Vector<double>(ngroups);
	    for (int grInd = 0; grInd < ngroups; grInd++)
	      {
		hrtime_t duration = dbeCalcGroupGCDuration (grInd);
		double seconds = duration * 1.e-9;
		columnData->append (seconds);
	      }
	    valueTable->append (columnData);
	  }
	else
	  {
	    Vector<char *> *columnData = new Vector<char *>(ngroups);
	    char * valueString = NTXT ("<unknown>");
	    for (int grInd = 0; grInd < ngroups; grInd++)
	      columnData->append (dbe_strdup (valueString));
	    valueTable->append (columnData);
	  }
      }
    }
  return rc;
}

Vector<char*> *
dbeGetOverviewText (int dbevindex)
{
  DbeView *dbev = dbeSession->getView (dbevindex);
  Vector<char*> *info = new Vector<char*>;
  char *field;
  int ngroups = dbeSession->expGroups->size (); // Rows (one per compare group)
  if (ngroups == 0 || !dbev->comparingExperiments ())
    ngroups = 1;
  for (int grInd = 0; grInd < ngroups; grInd++)
    {
      int thisGroupSize = 1;
      Experiment *exp;
      if (dbeSession->expGroups->size () > 0)
	{
	  ExpGroup *gr = dbeSession->expGroups->fetch (grInd);
	  exp = gr->exps->fetch (0);
	  thisGroupSize = gr->exps->size ();
	}
      else
	{
	  if (dbeSession->nexps () == 0)
	    return info;
	  exp = dbeSession->get_exp (0);
	}
      char * expHeader;
      if (ngroups == 1)
	expHeader = dbe_strdup (GTXT ("Experiment      :"));
      else if (grInd == 0)
	expHeader = dbe_strdup (GTXT ("Base Group      : "));
      else if (ngroups == 2)
	expHeader = dbe_strdup (GTXT ("Compare Group   : "));
      else
	expHeader = dbe_sprintf (GTXT ("Compare Group %d : "), grInd);
      if (thisGroupSize == 1)
	info->append (dbe_sprintf ("%s%s", expHeader, exp->get_expt_name ()));
      else
	info->append (dbe_sprintf ("%s%s (plus %d more)",
			  expHeader, exp->get_expt_name (), thisGroupSize - 1));
      free (expHeader);
      field = exp->uarglist;
      if (field && field[0])
	info->append (dbe_sprintf (GTXT ("  Target        : '%s'"), field));
      field = exp->hostname;
      if (field && field[0])
	info->append (dbe_sprintf (GTXT ("  Host          : %s (%s, %s)"),
				   field,
				   exp->architecture ? exp->architecture
				   : GTXT ("<CPU architecture not recorded>"),
				   exp->os_version ? exp->os_version
				   : GTXT ("<OS version not recorded>")));
      time_t start_sec = (time_t) exp->start_sec;
      char *p = ctime (&start_sec);
      hrtime_t tot_time = dbeCalcGroupDuration (grInd);
      double seconds = tot_time * 1.e-9;
      info->append (dbe_sprintf (
		GTXT ("  Start Time    : %s  Duration      : %0.3f Seconds"),
		p, seconds));
      // Number of descendants/processes would be nice
      info->append (dbe_strdup (NTXT ("")));
    }
  return info;
}

//--------------------------------------------------------------------------
// Set Sort by index
//
void
dbeSetSort (int dbevindex, int sort_index, MetricType mtype, bool reverse)
{
  DbeView *dbev;

  dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  dbev->setSort (sort_index, mtype, reverse);
  return;
}

//
// Get annotation setting
//
Vector<int> *
dbeGetAnoValue (int dbevindex)
{
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  Vector<int> *set = new Vector<int>(9);
  set->store (0, dbev->get_src_compcom ());
  set->store (1, dbev->get_dis_compcom ());
  set->store (2, dbev->get_thresh_src ());
  set->store (3, dbev->get_thresh_src ());
  set->store (4, dbev->get_src_visible ());
  set->store (5, (int) dbev->get_srcmetric_visible ());
  set->store (6, (int) dbev->get_hex_visible ());
  set->store (7, (int) dbev->get_cmpline_visible ());
  set->store (8, (int) dbev->get_func_scope ());
  return set;
}

//
// Set annotation setting
//
void
dbeSetAnoValue (int dbevindex, Vector<int> *set)
{
  DbeView *dbev;
  dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  if (set->size () != 10)
    return;
  dbev->set_src_compcom (set->fetch (0));
  dbev->set_dis_compcom (set->fetch (1));
  dbev->set_thresh_src (set->fetch (2));
  dbev->set_thresh_dis (set->fetch (3));
  dbev->set_src_visible (set->fetch (4));
  dbev->set_srcmetric_visible ((bool)set->fetch (5));
  dbev->set_hex_visible ((bool)set->fetch (6));
  dbev->set_cmpline_visible ((bool)set->fetch (7));
  dbev->set_func_scope (set->fetch (8));
  dbev->set_funcline_visible ((bool)set->fetch (9));
  return;
}

//
// Get name formats
//
int
dbeGetNameFormat (int dbevindex)
{
  DbeView *dbev;
  dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  Histable::NameFormat fmt = dbev->get_name_format ();
  return Histable::fname_fmt (fmt);
}

bool
dbeGetSoName (int dbevindex)
{
  DbeView *dbev;
  dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  Histable::NameFormat fmt = dbev->get_name_format ();
  return Histable::soname_fmt (fmt);
}

//
// Set name formats
//
void
dbeSetNameFormat (int dbevindex, int nformat, bool soname)
{
  DbeView *dbev;
  dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  dbev->set_name_format (nformat, soname);
}

//
// Get View mode
//
int
dbeGetViewMode (int dbevindex)
{
  DbeView *dbev;
  dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  return (int) dbev->get_view_mode ();
}

// Set View mode
void
dbeSetViewMode (int dbevindex, int nmode)
{
  DbeView *dbev;
  dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  dbev->set_view_mode ((VMode) nmode);
  return;
}

// Get timeline setting
//
Vector<void*> *
dbeGetTLValue (int dbevindex)
{
  DbeView *dbev;
  dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  Vector<char *> *strings = new Vector<char *>();
  char *tldata_cmd = dbev->get_tldata ();
  strings->store (0, tldata_cmd);

  Vector<int> *ints = new Vector<int>(3);
  int val;
  val = dbev->get_tlmode ();
  ints->store (0, val);
  val = dbev->get_stack_align ();
  ints->store (1, val);
  val = dbev->get_stack_depth ();
  ints->store (2, val);

  Vector<void*> *objs = new Vector<void*>(2);
  objs->store (0, strings);
  objs->store (1, ints);
  return objs;
}

//
// Set timeline setting
//
void
dbeSetTLValue (int dbevindex, const char *tldata_cmd,
	       int entitiy_prop_id, int stackalign, int stackdepth)
{
  DbeView *dbev;
  dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  dbev->set_tldata (tldata_cmd);
  dbev->set_tlmode (entitiy_prop_id);
  dbev->set_stack_align (stackalign);
  dbev->set_stack_depth (stackdepth);
  return;
}

//
// Get founder experiments and their descendants
//
Vector<void*> *
dbeGetExpFounderDescendants ()
{
  int size = dbeSession->nexps ();
  if (size == 0)
    return NULL;
  Vector<void*> *table = new Vector<void*>(2);
  Vector<int> *founderExpIds = new Vector<int>();
  Vector<Vector<int> *> *subExpIds = new Vector<Vector<int>*>();
  for (int index = 0; index < size; index++)
    {
      Experiment *exp = dbeSession->get_exp (index);
      if (exp->founder_exp == NULL)
	{
	  founderExpIds->append (exp->getExpIdx ());
	  Vector<int> *subExps = new Vector<int>();
	  for (int i = 0; i < exp->children_exps->size (); i++)
	    {
	      Experiment * subExp = exp->children_exps->fetch (i);
	      subExps->append (subExp->getExpIdx ());
	    }
	  subExpIds->append (subExps);
	}
    }
  table->store (0, founderExpIds);
  table->store (1, subExpIds);
  return table;
}

//
// Get experiment selection
//
Vector<void*> *
dbeGetExpSelection (int dbevindex)
{
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  int size = dbeSession->nexps ();
  if (size == 0)
    return NULL;
  Vector<void*> *table = new Vector<void*>(3);
  Vector<char*> *names = new Vector<char*>(size);
  Vector<bool> *enable = new Vector<bool>(size);
  Vector<int> *userExpIds = new Vector<int>(size);

  // Get experiment names
  for (int index = 0; index < size; index++)
    {
      Experiment *exp = dbeSession->get_exp (index);
      char *buf = dbeGetName (dbevindex, index);
      names->store (index, buf);
      bool val;
      val = dbev->get_exp_enable (index);
      enable->store (index, val);
      userExpIds->store (index, exp->getUserExpId ());
    }
  table->store (0, names);
  table->store (1, enable);
  table->store (2, userExpIds);
  return table;
}

int
dbeValidateFilterExpression (char *str_expr)
{
  if (str_expr == NULL)
    return 0;
  Expression *expr = dbeSession->ql_parse (str_expr);
  if (expr == NULL)
    return 0;
  delete expr;
  return 1;
}

Vector<void*> *
dbeGetFilterKeywords (int /* dbevindex */)
{
  Vector <char*> *kwCategory = new Vector<char *>();
  Vector <char*> *kwCategoryI18N = new Vector<char *>();
  Vector <char*> *kwDataType = new Vector<char *>();
  Vector <char*> *kwKeyword = new Vector<char *>();
  Vector <char*> *kwFormula = new Vector<char *>();
  Vector <char*> *kwDescription = new Vector<char *>();
  Vector <void*> *kwEnumDescs = new Vector<void *>();

  Vector<void*> *res = new Vector<void*>(7);
  res->append (kwCategory);
  res->append (kwCategoryI18N);
  res->append (kwDataType);
  res->append (kwKeyword);
  res->append (kwFormula);
  res->append (kwDescription);
  res->append (kwEnumDescs);

  char *vtypeNames[] = VTYPE_TYPE_NAMES;
  // section header for global definitions
  kwCategory->append (dbe_strdup (NTXT ("FK_SECTION")));
  kwCategoryI18N->append (dbe_strdup (GTXT ("Global Definitions")));
  kwDataType->append (NULL);
  kwKeyword->append (NULL);
  kwFormula->append (NULL);
  kwDescription->append (NULL);
  kwEnumDescs->append (NULL);
  dbeSession->get_filter_keywords (res);
  MemorySpace::get_filter_keywords (res);

  // loop thru all founder experiments
  int nexp = dbeSession->nexps ();
  for (int ii = 0; ii < nexp; ++ii)
    {
      Experiment* fexp = dbeSession->get_exp (ii);
      if (fexp->founder_exp != NULL)
	continue; // is a child; should be covered when we get to founder

      // section header for each founder
      // section header for founder experiment
      kwCategory->append (dbe_strdup (NTXT ("FK_SECTION")));
      kwCategoryI18N->append (dbe_sprintf (NTXT ("%s [EXPGRID==%d]"),
					   fexp->get_expt_name (),
					   fexp->groupId));
      kwDataType->append (NULL);
      kwKeyword->append (NULL);
      kwFormula->append (NULL);
      kwDescription->append (NULL);
      kwEnumDescs->append (NULL);

      int nchildren = fexp->children_exps->size ();
      Experiment *exp;
      // category header: Experiments
      {
	char *propUName = dbeSession->getPropUName (PROP_EXPID);

	// store list of subexperiments in kwEnumDescs
	Vector <char*> *enumDescs = new Vector<char *>();
	int jj = 0;
	exp = fexp;
	while (1)
	  {
	    char * expBasename = get_basename (exp->get_expt_name ());
	    char * targetName = exp->utargname ? exp->utargname
		    : (char *) GTXT ("(unknown)");
	    enumDescs->append (dbe_sprintf (NTXT ("(%d) -> %s [%s, PID %d]"),
					    exp->getUserExpId (), expBasename,
					    targetName, exp->getPID ()));
	    if (jj >= nchildren)
	      break;
	    exp = fexp->children_exps->fetch (jj);
	    jj++;
	  }
	kwCategory->append (dbe_strdup (NTXT ("FK_EXPLIST")));
	kwCategoryI18N->append (dbe_strdup (GTXT ("Experiments")));
	kwDataType->append (dbe_strdup (vtypeNames[TYPE_INT32]));
	kwKeyword->append (dbe_strdup (NTXT ("EXPID")));
	kwFormula->append (NULL);
	kwDescription->append (propUName);
	kwEnumDescs->append (enumDescs);
      }

      // select representative experiment
      if (nchildren == 0)
	exp = fexp; // founder
      else
	exp = fexp->children_exps->fetch (0); // first child
      int expIdx = exp->getExpIdx ();
      Vector<void*> *data = dbeGetDataDescriptorsV2 (expIdx);
      if (data == NULL)
	continue;
      Vector<int> *dataId = (Vector<int>*)data->fetch (0);
      Vector<char*> *dataName = (Vector<char*>*)data->fetch (1);
      Vector<char*> *dataUName = (Vector<char*>*)data->fetch (2);
      if (dataId == NULL || dataName == NULL)
	{
	  destroy (data);
	  continue;
	}
      // loop thru data descriptors
      int ndata = dataId->size ();
      for (int j = 0; j < ndata; ++j)
	{
	  // category: data name (e.g. Clock Profiling)
	  char * catName = dataName->fetch (j);
	  char * dUname = dataUName ? dataUName->fetch (j) : catName;
	  char * catUname = dUname ? dUname : catName;

	  Vector<void*> *props = dbeGetDataPropertiesV2 (expIdx, dataId->fetch (j));
	  if (props == NULL)
	    continue;
	  Vector<char*> *propUName = (Vector<char*>*)props->fetch (1);
	  Vector<int> *propTypeId = (Vector<int> *)props->fetch (2);
	  Vector<char*> *propType = (Vector<char*>*)props->fetch (3);
	  Vector<char*> *propName = (Vector<char*>*)props->fetch (5);
	  Vector<Vector<char*>*> *propStateNames =
		  (Vector<Vector<char*>*> *)props->fetch (6);
	  Vector<Vector<char*>*> *propStateUNames =
		  (Vector<Vector<char*>*> *)props->fetch (7);
	  if (propName == NULL || propUName == NULL || propType == NULL
	      || propName->size () <= 0)
	    {
	      destroy (props);
	      continue;
	    }
	  int nprop = propName->size ();
	  for (int k = 0; k < nprop; ++k)
	    {
	      if (propTypeId->fetch (k) == TYPE_OBJ)
		continue;
	      if (dbe_strcmp (propName->fetch (k), NTXT ("FRINFO")) == 0)
		continue;

	      // store list of states in kwEnumDescs
	      Vector<char*> *enumDescs = new Vector<char *>();
	      Vector<char*>* stateNames = propStateNames->fetch (k);
	      Vector<char*>* stateUNames = propStateUNames->fetch (k);
	      int nStates = stateNames ? stateNames->size () : 0;
	      for (int kk = 0; kk < nStates; ++kk)
		{
		  const char *stateName = stateNames->fetch (kk);
		  if (stateName == NULL || strlen (stateName) == 0)
		    continue;
		  const char *stateUName = stateUNames->fetch (kk);
		  if (stateUName == NULL || strlen (stateUName) == 0)
		    stateUName = stateName;
		  enumDescs->append (dbe_sprintf (NTXT ("(%d) -> %s"), kk, stateUName));
		}
	      kwCategory->append (dbe_strdup (catName));
	      kwCategoryI18N->append (dbe_strdup (catUname));
	      kwDataType->append (dbe_strdup (propType->fetch (k)));
	      kwKeyword->append (dbe_strdup (propName->fetch (k)));
	      kwFormula->append (NULL);
	      kwDescription->append (dbe_strdup (propUName->fetch (k)));
	      kwEnumDescs->append (enumDescs);
	    }
	  destroy (props);
	}
      destroy (data);
    }
  return (res);
}

// GetFilters -- returns the list of filters for the indexed experiment
//	returns false if there's a problem; true otherwise
//
Vector<void*> *
dbeGetFilters (int dbevindex, int nexp)
{
  FilterNumeric *filt;
  int index;
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  Vector<FilterNumeric *>*filters = dbev->get_all_filters (nexp);
  if (filters == NULL)
    return NULL;

  // return an array of filter data for that experiment
  Vector <int> *findex = new Vector<int>(); // index of the filters
  Vector <char*> *shortname = new Vector<char *>();
  // short name of filter
  Vector <char*> *i18n_name = new Vector<char *>();
  // External I18N'd name of filter
  Vector <char*> *pattern = new Vector<char *>();
  // current setting string
  Vector <char*> *status = new Vector<char *>();
  // current status of filter (%, range, etc.)

  Vec_loop (FilterNumeric *, filters, index, filt)
  {
    findex->append (index);
    shortname->append (dbe_strdup (filt->get_cmd ()));
    i18n_name->append (dbe_strdup (filt->get_name ()));
    pattern->append (dbe_strdup (filt->get_pattern ()));
    status->append (dbe_strdup (filt->get_status ()));
  }
  Vector<void*> *res = new Vector<void*>(5);
  res->store (0, findex);
  res->store (1, shortname);
  res->store (2, i18n_name);
  res->store (3, pattern);
  res->store (4, status);
  return (res);
}

// Set a filter string for a view
//	Returns NULL if OK, error message if not

char *
dbeSetFilterStr (int dbevindex, char *filter_str)
{
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  dbev->clear_error_msg ();
  dbev->clear_warning_msg ();
  char *ret = dbev->set_filter (filter_str);
  return ret;
}

// Get the current filter setting for the view
char *
dbeGetFilterStr (int dbevindex)
{
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  char *ret = dbev->get_filter ();
  return ret;
}

// Update a filters for a single experiment
// Returns true if any filter->set_pattern() returns true,
//	implying rereading the data is needed (i.e., a filter changed)
//
bool
dbeUpdateFilters (int dbevindex, Vector<bool> *selected, Vector<char *> *pattern_str)
{
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  dbev->clear_error_msg ();
  dbev->clear_warning_msg ();

  // Get index of first selected experiment
  int size = selected->size ();
  int nselexp = -1;
  for (int index = 0; index < size; index++)
    {
      if (selected->fetch (index) == true)
	{
	  nselexp = index;
	  break;
	}
    }
  if (nselexp == -1) // No experiment selected
    return false;

  bool ret = false;
  for (int j = 0; j < size; j++)
    {
      if (selected->fetch (j) == false)
	continue;
      bool error;
      if (dbev->set_pattern (j, pattern_str, &error))
	ret = true;
    }
  dbev->update_advanced_filter ();
  return ret;
}

char *
dbeComposeFilterClause (int dbevindex, int type, int subtype, Vector<int> *selections)
{
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  // ask the cached data to generate the string
  Hist_data *data;
  switch (type)
    {
    case DSP_FUNCTION:
      data = dbev->func_data;
      break;
    case DSP_DLAYOUT:
      data = dbev->dlay_data;
      break;
    case DSP_DATAOBJ:
      data = dbev->dobj_data;
      break;
    case DSP_MEMOBJ:
    case DSP_INDXOBJ:
      data = dbev->get_indxobj_data (subtype);
      break;
    case DSP_LINE:
      data = dbev->line_data;
      break;
    case DSP_PC:
      data = dbev->pc_data;
      break;
    case DSP_SOURCE:
      data = dbev->src_data;
      break;
    case DSP_DISASM:
      data = dbev->dis_data;
      break;
    case DSP_IOACTIVITY:
      data = dbev->iofile_data;
      break;
    case DSP_IOVFD:
      data = dbev->iovfd_data;
      break;
    case DSP_IOCALLSTACK:
      data = dbev->iocs_data;
      break;
    case DSP_HEAPCALLSTACK:
      data = dbev->heapcs_data;
      break;
    default:
      return NULL;
    }
  if (data == NULL)
    return NULL;

  // Get array of object indices, and compose filter string
  Vector<uint64_t> *obj_ids = data->get_object_indices (selections);
  if (obj_ids == NULL || obj_ids->size () == 0)
    return NULL;

  uint64_t sel;
  int index;
  int found = 0;
  char buf[128];
  StringBuilder sb;
  sb.append ('(');
  switch (type)
    {
    case DSP_LINE:
    case DSP_PC:
    case DSP_SOURCE:
    case DSP_DISASM:
    case DSP_FUNCTION:
      sb.append (NTXT ("LEAF IN "));
      break;
    case DSP_MEMOBJ:
    case DSP_INDXOBJ:
      sb.append (dbeSession->getIndexSpaceName (subtype));
      sb.append (NTXT (" IN "));
      break;
    }
  Vec_loop (uint64_t, obj_ids, index, sel)
  {
    if (found == 0)
      {
	found = 1;
	sb.append ('(');
      }
    else
      sb.append (NTXT (", "));
    snprintf (buf, sizeof (buf), NTXT ("%llu"), (long long) sel);
    sb.append (buf);
  }
  if (found == 1)
    sb.append (')');

  switch (type)
    {
    case DSP_DLAYOUT:
    case DSP_DATAOBJ:
      sb.append (NTXT (" SOME IN DOBJ"));
      break;
    }
  sb.append (')');
  return sb.toString ();
}

//
// Get load object states
//
Vector<void *> *
dbeGetLoadObjectList (int dbevindex)
{
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  Vector<LoadObject*> *lobjs = dbeSession->get_text_segments ();
  int size = lobjs->size ();

  // Initialize Java boolean array
  Vector<char *> *names = new Vector<char *>(size);
  Vector<int> *states = new Vector<int>(size);
  Vector<int> *indices = new Vector<int>(size);
  Vector<char *> *paths = new Vector<char *>(size);
  Vector<int> *isJava = new Vector<int>(size);

  // Get load object states
  int index;
  LoadObject *lo;
  char *lo_name;

  // lobjectsNoJava is a trimmed list of indices provided to front-end skipping the Java
  // classes. lobjectsNoJava preserves the mapping of the index into the complete lobjs
  // vector. What front-end sees as lobj[i] is really lobj[lobjectsNoJava[i]];

  // This list is constructed every time GetLoadObjectList() or GetLoadObjectState() is
  // called. Possibility of further optimization by making it more persistent.
  // Only consumer of this list is dbeSetLoadObjectState
  int new_index = 0;
  if (dbev->lobjectsNoJava == NULL)
    dbev->lobjectsNoJava = new Vector<int>(1);
  else
    dbev->lobjectsNoJava->reset ();

  Vec_loop (LoadObject*, lobjs, index, lo)
  {
    // Set 0, 1, or 2 for show/hide/api
    enum LibExpand expand = dbev->get_lo_expand (lo->seg_idx);

    lo_name = lo->get_name ();
    if (lo_name != NULL)
      {
	size_t len = strlen (lo_name);
	if (len > 7 && streq (lo_name + len - 7, NTXT (".class>")))
	  isJava->store (new_index, 1);
	else
	  isJava->store (new_index, 0);
      }
    else
      isJava->store (new_index, 0);
    dbev->lobjectsNoJava->append (index);

    names->store (new_index, dbe_sprintf (NTXT ("%s"), lo_name));
    states->store (new_index, (int) expand);
    indices->store (new_index, (int) lo->seg_idx);
    paths->store (new_index, dbe_sprintf (NTXT ("%s"), lo->get_pathname ()));
    new_index++;
  }
  Vector<void*> *res = new Vector<void*>(5);
  res->store (0, names);
  res->store (1, states);
  res->store (2, indices);
  res->store (3, paths);
  res->store (4, isJava);
  delete lobjs;
  return res;
}

Vector<int> *
dbeGetLoadObjectState (int dbevindex)
{
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  Vector<LoadObject*> *lobjs = dbeSession->get_text_segments ();
  int size = lobjs->size ();

  // Initialize Java boolean array
  Vector<int> *states = new Vector<int>(size);
  char *lo_name;

  // lobjectsNoJava is a trimmed list of indices provided to front-end skipping the Java
  // classes. lobjectsNoJava preserves the mapping of the index into the complete lobjs
  // vector. What front-end sees as lobj[i] is really lobj[lobjectsNoJava[i]];

  // This list is constructed every time GetLoadObjectList() or GetLoadObjectState() is
  // called. Possibility of further optimization by making it more persistent.
  // Only consumer of this list is dbeSetLoadObjectState
  int new_index = 0;
  if (dbev->lobjectsNoJava == NULL)
    dbev->lobjectsNoJava = new Vector<int>(1);
  else
    dbev->lobjectsNoJava->reset ();

  // Get load object states
  int index;
  LoadObject *lo;

  Vec_loop (LoadObject*, lobjs, index, lo)
  {
    // Set 0, 1, or 2 for show/hide/api
    lo_name = lo->get_name ();
    if (lo_name != NULL)
      {
	size_t len = strlen (lo_name);
	if (len > 7 && streq (lo_name + len - 7, NTXT (".class>")))
	  continue;
      }
    else
      dbev->lobjectsNoJava->append (index);

    enum LibExpand expand = dbev->get_lo_expand (lo->seg_idx);
    states->store (new_index, (int) expand);
    new_index++;
  }
  delete lobjs;
  return states;
}

// Set load object states
void
dbeSetLoadObjectState (int dbevindex, Vector<int> *selected)
{
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  Vector<LoadObject*> *lobjs = dbeSession->get_text_segments ();

  int index;
  bool changed = false;

  LoadObject *lo;
  int new_index = 0;
  dbev->setShowAll ();
  Vec_loop (LoadObject*, lobjs, index, lo)
  {
    if (dbev->lobjectsNoJava != NULL)
      {
	// This loadobject is a java class and was skipped
	if (dbev->lobjectsNoJava->fetch (new_index) != index)
	  continue;
      }
    // Get array of settings
    enum LibExpand expand = (enum LibExpand) selected->fetch (new_index);
    if (expand == LIBEX_HIDE)
      {
	dbev->resetShowAll ();
	dbeSession->set_lib_visibility_used ();
      }
    changed = changed | dbev->set_libexpand (lo->get_pathname (), expand);
    new_index++;
  }
  delete lobjs;
  if (changed == true)
    {
      dbev->setShowHideChanged ();
      dbev->update_lo_expands ();
    }

  return;
}

// Reset load object states
void
dbeSetLoadObjectDefaults (int dbevindex)
{
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  dbev->set_libdefaults ();
}

// Get  Machine model
Vector<char*>*
dbeGetCPUVerMachineModel (int dbevindex)
{
  Vector<char*>* table = new Vector<char*>();
  DbeView *dbev = dbeSession->getView (dbevindex);
  char * mach_model = dbev->get_settings ()->get_machinemodel ();
  if (mach_model != NULL)
    {
      table->append (mach_model);
      return table;
    }
  int grsize = dbeSession->expGroups->size ();
  for (int j = 0; j < grsize; j++)
    {
      ExpGroup *gr = dbeSession->expGroups->fetch (j);
      Vector<Experiment*> *exps = gr->exps;
      for (int i = 0, sz = exps->size (); i < sz; i++)
	{
	  Experiment *exp = exps->fetch (i);
	  char *model = exp->machinemodel;
	  if (model != NULL)
	    table->append (dbe_strdup (model));
	}
    }
  return table;
}

// automatically load machine model if applicable
void
dbeDetectLoadMachineModel (int dbevindex)
{
  if (dbeSession->is_datamode_available ())
    {
      char *model = dbeGetMachineModel ();
      if (model == NULL)
	{
	  Vector<char*>* models = dbeGetCPUVerMachineModel (dbevindex);
	  char * machineModel = NTXT ("generic");
	  if (models->size () > 0)
	    {
	      machineModel = models->get (0);
	      for (int i = 1; i < models->size (); i++)
		{
		  if (strncmp (models->get (i), machineModel, strlen (machineModel)) == 0)
		    {
		      machineModel = NTXT ("generic");
		      break;
		    }
		}
	      dbeLoadMachineModel (machineModel);
	    }
	  delete models;
	}
    }
}

// Managing Memory Objects
char *
dbeDefineMemObj (char *name, char *index_expr, char *machinemodel,
		 char *sdesc, char *ldesc)
{
  return MemorySpace::mobj_define (name, index_expr, machinemodel, sdesc, ldesc);
}

char *
dbeDeleteMemObj (char *name)
{
  return MemorySpace::mobj_delete (name);
}

Vector<void*> *
dbeGetMemObjects (int /*dbevindex*/)
{
  Vector<void*> *res = MemorySpace::getMemObjects ();
  return res;
}

// Managing machine model
char *
dbeLoadMachineModel (char *name)
{
  return dbeSession->load_mach_model (name);
}

char *
dbeGetMachineModel ()
{
  return dbeSession->get_mach_model ();
}

Vector <char *> *
dbeListMachineModels ()
{
  return dbeSession->list_mach_models ();
}

// Managing Index Objects
char *
dbeDefineIndxObj (char *name, char *index_expr, char *sdesc, char *ldesc)
{
  return dbeSession->indxobj_define (name, NULL, index_expr, sdesc, ldesc);
}

Vector<void*> *
dbeGetIndxObjDescriptions (int /*dbevindex*/)
{
  Vector<void*> *res = dbeSession->getIndxObjDescriptions ();
  return res;
}

Vector<void*> *
dbeGetCustomIndxObjects (int /*dbevindex*/)
{
  Vector<void*> *res = dbeSession->getCustomIndxObjects ();
  return res;
}

void
dbeSetSelObj (int dbevindex, Obj sel_obj_or_ind, int type, int subtype)
{
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  Histable *sel_obj;
  Hist_data *data;
  int sel_ind = (int) sel_obj_or_ind;

  switch (type)
    {
    case DSP_FUNCTION:
      data = dbev->func_data;
      break;
    case DSP_LINE:
      data = dbev->line_data;
      break;
    case DSP_PC:
      data = dbev->pc_data;
      break;
    case DSP_CALLER:
      data = dbev->callers;
      break;
    case DSP_CALLEE:
      data = dbev->callees;
      break;
    case DSP_SOURCE:
      data = dbev->src_data;
      break;
    case DSP_DISASM:
      data = dbev->dis_data;
      break;
    case DSP_DLAYOUT:
      data = dbev->dlay_data;
      if (data == NULL)
	{
	  dbev->sel_binctx = NULL;
	  return;
	}
      if (sel_ind >= 0 && sel_ind < dbev->dlay_data->size ())
	dbev->sel_dobj = dbev->dlay_data->fetch (sel_ind)->obj;
      return;
    case DSP_DATAOBJ:
      data = dbev->dobj_data;
      if (data == NULL)
	{
	  dbev->sel_binctx = NULL;
	  return;
	}
      if (sel_ind >= 0 && sel_ind < dbev->dobj_data->size ())
	dbev->sel_dobj = dbev->dobj_data->fetch (sel_ind)->obj;
      return;
    case DSP_MEMOBJ:
    case DSP_INDXOBJ:
      dbev->set_indxobj_sel (subtype, sel_ind);
      sel_obj = dbev->get_indxobj_sel (subtype);
      if (sel_obj && sel_obj->get_type () == Histable::INDEXOBJ)
	dbev->set_sel_obj (((IndexObject*) sel_obj)->get_obj ());
      return;
    case DSP_SOURCE_V2:
    case DSP_DISASM_V2:
    case DSP_TIMELINE:
    case DSP_LEAKLIST:
    case DSP_RACES:
    case DSP_DEADLOCKS:
    case DSP_DUALSOURCE:
    case DSP_SOURCE_DISASM:
    case DSP_IOACTIVITY:
    case DSP_IOVFD:
    case DSP_IOCALLSTACK:
    case DSP_HEAPCALLSTACK:
    case DSP_MINICALLER:
      dbev->set_sel_obj ((Histable *) sel_obj_or_ind);
      return;
    default:
      // abort();
      return;
    }
  if (type != DSP_SOURCE && type != DSP_DISASM && type != DSP_SOURCE_V2
      && type != DSP_DISASM_V2)
    dbev->sel_binctx = NULL;

  if (data == NULL || data->get_status () != Hist_data::SUCCESS
      || sel_ind >= data->size ())
    return;

  if (sel_ind >= 0 && sel_ind < data->size ())
    dbev->set_sel_obj (data->fetch (sel_ind)->obj);
}

void
dbeSetSelObjV2 (int dbevindex, uint64_t id)
{
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  dbev->set_sel_obj (dbeSession->findObjectById (id));
}

Obj
dbeGetSelObj (int dbevindex, int type, int subtype)
{
  DbeView *dbev = dbeSession->getView (dbevindex);
  Histable *sel_obj = NULL;
  switch (type)
    {
    case DSP_FUNCTION:
      sel_obj = dbev->get_sel_obj (Histable::FUNCTION);
      break;
    case DSP_LINE:
    case DSP_SOURCE:
    case DSP_SOURCE_V2:
      sel_obj = dbev->get_sel_obj (Histable::LINE);
      break;
    case DSP_PC:
    case DSP_DISASM:
    case DSP_DISASM_V2:
      sel_obj = dbev->get_sel_obj (Histable::INSTR);
      break;
    case DSP_SRC_FILE:
      sel_obj = dbev->get_sel_obj (Histable::SOURCEFILE);
      break;
    case DSP_DATAOBJ:
    case DSP_DLAYOUT:
      if (dbev->sel_dobj)
	sel_obj = dbev->sel_dobj->convertto (Histable::DOBJECT);
      break;
    case DSP_MEMOBJ:
    case DSP_INDXOBJ:
      sel_obj = dbev->get_indxobj_sel (subtype);
      break;
    default:
      abort ();
    }
  Dprintf (DEBUG_DBE, NTXT ("### dbeGetSelObj: Dbe.cc:%d %s (%d) returns %s\n"),
	   __LINE__, dsp_type_to_string (type), type, sel_obj ? sel_obj->dump () : "NULL");
  return (Obj) sel_obj;
}

Obj
dbeConvertSelObj (Obj obj, int type)
{
  Histable *sel_obj = (Histable *) obj;
  Dprintf (DEBUG_DBE, NTXT ("### dbeConvertSelObj: Dbe.cc:%d %s (%d) sel_obj=%s\n"),
	   __LINE__, dsp_type_to_string (type), type, sel_obj ? sel_obj->dump ()
	  : "NULL");
  if (sel_obj == NULL)
    return (Obj) NULL;
  switch (type)
    {
    case DSP_FUNCTION:
      return (Obj) sel_obj->convertto (Histable::FUNCTION);
    case DSP_LINE:
      return (Obj) sel_obj->convertto (Histable::LINE);
    case DSP_SOURCE:
    case DSP_SOURCE_V2:
      {
	SourceFile* srcCtx = NULL;
	if (sel_obj->get_type () == Histable::INSTR)
	  {
	    DbeInstr* dbei = (DbeInstr *) sel_obj;
	    srcCtx = (SourceFile*) dbei->convertto (Histable::SOURCEFILE);
	  }
	else if (sel_obj->get_type () == Histable::LINE)
	  {
	    DbeLine * dbel = (DbeLine *) sel_obj;
	    srcCtx = dbel->sourceFile;
	  }
	sel_obj = sel_obj->convertto (Histable::LINE, srcCtx);
	Dprintf (DEBUG_DBE, NTXT ("### dbeConvertSelObj: Dbe.cc:%d %s (%d) returns %s\n"),
		 __LINE__, dsp_type_to_string (type), type, sel_obj ? sel_obj->dump () : "NULL");
	if (sel_obj && sel_obj->get_type () == Histable::LINE)
	  {
	    DbeLine * dbel = (DbeLine *) sel_obj;
	    return (Obj) dbel->dbeline_base;
	  }
	return (Obj) sel_obj->convertto (Histable::LINE, srcCtx);
      }
    case DSP_PC:
    case DSP_DISASM:
    case DSP_DISASM_V2:
      return (Obj) sel_obj->convertto (Histable::INSTR);
    case DSP_SRC_FILE:
      return (Obj) sel_obj->convertto (Histable::SOURCEFILE);
    default:
      abort ();
    }
  return (Obj) NULL;
}

uint64_t
dbeGetSelObjV2 (int dbevindex, char *typeStr)
{
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  Histable *obj = NULL;
  if (typeStr != NULL)
    {
      if (streq (typeStr, NTXT ("FUNCTION")))
	obj = dbev->get_sel_obj (Histable::FUNCTION);
      else if (streq (typeStr, NTXT ("INSTRUCTION")))
	obj = dbev->get_sel_obj (Histable::INSTR);
      else if (streq (typeStr, NTXT ("SOURCELINE")))
	obj = dbev->get_sel_obj (Histable::LINE);
      else if (streq (typeStr, NTXT ("SOURCEFILE")))
	obj = dbev->get_sel_obj (Histable::SOURCEFILE);
    }
  Dprintf (DEBUG_DBE, NTXT ("### dbeGetSelObjV2: Dbe.cc:%d %s returns %s\n"),
	   __LINE__, STR (typeStr), obj ? obj->dump () : "NULL");
  return obj != NULL ? obj->id : (uint64_t) - 1;
}

Vector<uint64_t> *
dbeGetSelObjsIO (int dbevindex, Vector<uint64_t> *ids, int type)
{
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  Vector<uint64_t> *res = NULL;
  Vector<uint64_t> *result = new Vector<uint64_t>();
  for (int i = 0; i < ids->size (); i++)
    {
      res = dbeGetSelObjIO (dbevindex, ids->fetch (i), type);
      if (res != NULL)
	{
	  result->addAll (res);
	  delete res;
	}
    }
  return result;
}

Vector<uint64_t> *
dbeGetSelObjIO (int dbevindex, uint64_t id, int type)
{
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  Histable *obj = NULL;
  Vector<uint64_t> *res = NULL;
  int size = 0;
  switch (type)
    {
    case DSP_IOACTIVITY:
      obj = dbev->get_sel_obj_io (id, Histable::IOACTFILE);
      size = obj != NULL ? ((FileData*) obj)->getVirtualFds ()->size () : 0;
      if (size)
	{
	  res = new Vector<uint64_t>();
	  Vector<int64_t> *vfds = ((FileData*) obj)->getVirtualFds ();
	  for (int i = 0; i < size; i++)
	    res->append (vfds->fetch (i));
	}
      break;
    case DSP_IOVFD:
      obj = dbev->get_sel_obj_io (id, Histable::IOACTVFD);
      if (obj)
	{
	  res = new Vector<uint64_t>();
	  res->append (obj->id);
	}
      break;
    case DSP_IOCALLSTACK:
      obj = dbev->get_sel_obj_io (id, Histable::IOCALLSTACK);
      if (obj)
	{
	  Vector<Obj> *instrs = dbeGetStackPCs (dbevindex, obj->id);
	  if (instrs == NULL)
	    return NULL;
	  int stsize = instrs->size ();
	  res = new Vector<uint64_t>(stsize);
	  for (int i = 0; i < stsize; i++)
	    {
	      Histable *objFunc = (DbeInstr*) (instrs->fetch (i));
	      if (objFunc->get_type () != Histable::LINE)
		{
		  objFunc = objFunc->convertto (Histable::FUNCTION);
		  res->insert (0, objFunc->id);
		}
	    }
	  delete instrs;
	}
      break;
    default:
      break;
    }
  return res;
}

uint64_t
dbeGetSelObjHeapTimestamp (int dbevindex, uint64_t id)
{
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  Histable *obj = NULL;
  uint64_t res = 0;
  Vector<uint64_t> *peakStackIds;
  Vector<hrtime_t> *peakTimestamps;

  // Find and return the timestamp for the peak
  bool foundPeakId = false;
  if (id > 0)
    {
      obj = dbev->get_sel_obj_heap (0);
      if (obj != NULL)
	{
	  peakStackIds = ((HeapData*) obj)->getPeakStackIds ();
	  peakTimestamps = ((HeapData*) obj)->getPeakTimestamps ();
	  for (int i = 0; i < peakStackIds->size (); i++)
	    {
	      if (id == peakStackIds->fetch (i))
		{
		  res = peakTimestamps->fetch (i);
		  foundPeakId = true;
		  break;
		}
	    }
	}
    }

  // Return the first timestamp for the peak
  // if the callstack id is zero or it
  // doesn't match with the peak stack id
  if (id == 0 || !foundPeakId)
    {
      obj = dbev->get_sel_obj_heap (0);
      res = obj != NULL ? ((HeapData*) obj)->getPeakTimestamps ()->fetch (0) : 0;
    }
  return res;
}

int
dbeGetSelObjHeapUserExpId (int dbevindex, uint64_t id)
{
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  Histable *obj = NULL;
  int res = 0;
  obj = dbev->get_sel_obj_heap (id);
  res = obj != NULL ? ((HeapData*) obj)->getUserExpId () : 0;
  return res;
}

//
// Get index of selected function/object
//
int
dbeGetSelIndex (int dbevindex, Obj sel_obj, int type, int subtype)
{
  Hist_data *data;
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  switch (type)
    {
    case DSP_FUNCTION:
      data = dbev->func_data;
      break;
    case DSP_LINE:
      data = dbev->line_data;
      break;
    case DSP_PC:
      data = dbev->pc_data;
      break;
    case DSP_SOURCE:
    case DSP_SOURCE_V2:
      data = dbev->src_data;
      break;
    case DSP_DISASM:
    case DSP_DISASM_V2:
      data = dbev->dis_data;
      break;
    case DSP_DLAYOUT:
      data = dbev->dlay_data;
      break;
    case DSP_DATAOBJ:
      data = dbev->dobj_data;
      break;
    case DSP_MEMOBJ:
    case DSP_INDXOBJ:
      data = dbev->get_indxobj_data (subtype);
      break;
    default:
      data = NULL;
      break;
    }
  if (data == NULL || data->get_status () != Hist_data::SUCCESS)
    return -1;

  Histable *chk_obj = (Histable *) sel_obj;
  Vector<Hist_data::HistItem*> *histItems = data->get_hist_items ();
  if (histItems == NULL || chk_obj == NULL)
    return -1;
  for (int i = 0, sz = histItems->size (); i < sz; i++)
    {
      if (histItems->get (i)->obj == chk_obj)
	return i;
      if (histItems->get (i)->obj == NULL)
	continue;
      if (histItems->get (i)->obj->get_type () == Histable::LINE
	  && chk_obj->get_type () == Histable::LINE)
	{
	  if (((DbeLine*) histItems->get (i)->obj)->convertto (Histable::FUNCTION)
	      == ((DbeLine*) chk_obj)->convertto (Histable::FUNCTION)
	      && ((DbeLine*) histItems->get (i)->obj)->lineno
	      == ((DbeLine*) chk_obj)->lineno)
	    return i;
	}
      else if (histItems->get (i)->obj->get_type () == Histable::INSTR
	 && chk_obj->get_type () == Histable::INSTR)
	if (((DbeInstr*) histItems->get (i)->obj)->convertto (Histable::FUNCTION)
	    == ((DbeInstr*) chk_obj)->convertto (Histable::FUNCTION)
	    && ((DbeInstr*) histItems->get (i)->obj)->addr
	    == ((DbeInstr*) chk_obj)->addr)
	  return i;
    }

  Histable *chk_obj1 = NULL;
  switch (type)
    {
    case DSP_FUNCTION:
      chk_obj1 = chk_obj->convertto (Histable::FUNCTION);
      break;
    case DSP_LINE:
    case DSP_SOURCE:
    case DSP_SOURCE_V2:
      chk_obj1 = chk_obj->convertto (Histable::LINE);
      break;
    case DSP_PC:
    case DSP_DISASM:
    case DSP_DISASM_V2:
      chk_obj1 = chk_obj->convertto (Histable::INSTR);
      break;
    }
  if (chk_obj1 && chk_obj != chk_obj1)
    for (int i = 0, sz = histItems->size (); i < sz; i++)
      if (histItems->get (i)->obj == chk_obj1)
	return i;

  if (type == DSP_LINE)
    {
      for (int i = 0, sz = histItems->size (); i < sz; i++)
	if (histItems->get (i)->obj != NULL
	    && chk_obj->convertto (Histable::FUNCTION)
	    == histItems->get (i)->obj->convertto (Histable::FUNCTION))
	  return i;
    }
  else if (type == DSP_PC)
    {
      for (int i = 0, sz = histItems->size (); i < sz; i++)
	if (histItems->get (i)->obj != NULL
	    && (histItems->get (i)->obj)->convertto (Histable::FUNCTION)
	    == (chk_obj)->convertto (Histable::FUNCTION)
	    && ((DbeLine*) histItems->get (i)->obj->convertto (Histable::LINE))->lineno
	    == ((DbeLine*) chk_obj->convertto (Histable::LINE))->lineno)
	  return i;
      for (int i = 0, sz = histItems->size (); i < sz; i++)
	if (histItems->get (i)->obj != NULL
	    && (histItems->get (i)->obj)->convertto (Histable::FUNCTION)
	    == (chk_obj)->convertto (Histable::FUNCTION))
	  return i;
    }

  // If we clicked on an mfunction line in the called-by call mini in user mode for omp
  // we might not find that function in func data
  if (dbev->isOmpDisMode () && type == DSP_FUNCTION)
    {
      int p = dbeGetSelIndex (dbevindex, sel_obj, DSP_DISASM, subtype);
      if (p != -1)
	return p;
    }
  return -1;
}

// Print data
//
char *
dbePrintData (int dbevindex, int type, int subtype, char *printer,
	      char *fname, FILE *outfile)
{
  Histable *current_obj;
  Function *func;
  Module *module;
  MetricList *mlist_orig;
  bool header;
  Print_params params;
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();

  // Set print parameters
  if (printer != NULL)
    {
      params.dest = DEST_PRINTER;
      params.name = printer;
    }
  else if (outfile != NULL)
    {
      params.dest = DEST_OPEN_FILE;
      params.openfile = outfile;
      params.name = NULL;
    }
  else
    {
      params.dest = DEST_FILE;
      params.name = fname;
      if (*(params.name) == '\0')
	{
	  free (params.name);
	  return dbe_strdup (GTXT ("Please enter the name of the file to which to print"));
	}
    }
  params.ncopies = 1;
  if (outfile != NULL)
    header = false;
  else
    header = !(type == DSP_SOURCE || type == DSP_SOURCE_V2 || type == DSP_DISASM_V2);

  params.header = header;

  // figure out what kind of metrics to use
  if (type == DSP_SELF || type == DSP_CALLER || type == DSP_CALLEE
      || type == DSP_CALLTREE)
    mlist_orig = dbev->get_metric_list (MET_CALL);
  else if (type == DSP_DATAOBJ || type == DSP_DLAYOUT || type == DSP_MEMOBJ)
    mlist_orig = dbev->get_metric_list (MET_DATA);
  else if (type == DSP_INDXOBJ)
    mlist_orig = dbev->get_metric_list (MET_INDX);
  else if (type == DSP_IOACTIVITY || type == DSP_IOVFD
	   || type == DSP_IOCALLSTACK)
    mlist_orig = dbev->get_metric_list (MET_IO);
  else if (type == DSP_HEAPCALLSTACK)
    mlist_orig = dbev->get_metric_list (MET_HEAP);
  else
    mlist_orig = dbev->get_metric_list (MET_NORMAL);

  // make a compacted version of the input list
  // the list will either be moved to the generated data,
  //   or freed below if it wasn't needed
  MetricList *mlist = new MetricList (mlist_orig);
  Hist_data *data = NULL;
  er_print_common_display *cd = NULL;
  int ix;
  // Set data
  switch (type)
    {
    case DSP_FUNCTION:
    case DSP_LINE:
    case DSP_PC:
    case DSP_MEMOBJ:
    case DSP_INDXOBJ:
    case DSP_DATAOBJ:
      data = dbev->get_hist_data (mlist,
				  ((type == DSP_FUNCTION) ? Histable::FUNCTION :
				   (type == DSP_LINE) ? Histable::LINE :
				   (type == DSP_PC) ? Histable::INSTR :
				   (type == DSP_INDXOBJ) ? Histable::INDEXOBJ :
				   (type == DSP_MEMOBJ) ? Histable::MEMOBJ
				   : Histable::DOBJECT),
				  subtype, Hist_data::ALL);
      if (data->get_status () != Hist_data::SUCCESS)
	return DbeView::status_str (DbeView::DBEVIEW_NO_DATA); // no strdup()

      cd = new er_print_histogram (dbev, data, mlist, MODE_LIST,
				   dbev->get_limit (),
				   mlist->get_sort_name (), NULL, true, true);
      break;
    case DSP_DLAYOUT:
      {
	data = dbev->get_hist_data (mlist, Histable::DOBJECT, 0, Hist_data::LAYOUT);
	if (data->get_status () != Hist_data::SUCCESS)
	  return DbeView::status_str (DbeView::DBEVIEW_NO_DATA); // no strdup()
	cd = new er_print_histogram (dbev, data, mlist, MODE_ANNOTATED,
				     dbev->get_thresh_dis (),
				     mlist->get_sort_name (), NULL, true, true);
	break;
      }

      // source and disassembly
    case DSP_SOURCE:
    case DSP_DISASM:
    case DSP_SOURCE_V2:
    case DSP_DISASM_V2:
      if (dbev->sel_obj == NULL)
	return NULL;
      current_obj = dbev->sel_obj->convertto (Histable::FUNCTION);
      if (current_obj->get_type () != Histable::FUNCTION)
	return dbe_strdup (GTXT ("Not a real function; no source or disassembly available."));
      func = (Function*) current_obj->convertto (Histable::FUNCTION);
      if (func->flags & FUNC_FLAG_SIMULATED)
	return dbe_strdup (GTXT ("Not a real function; no source or disassembly available."));
      if (func->get_name () == NULL)
	return dbe_strdup (GTXT ("Source location not recorded in experiment"));
      module = func->module;
      if (module == NULL || module->get_name () == NULL)
	return dbe_strdup (GTXT ("Object name not recorded in experiment"));
      ix = module->loadobject->seg_idx;
      if (dbev->get_lo_expand (ix) == LIBEX_HIDE)
	return dbe_strdup (GTXT ("No source or disassembly available for hidden object"));
      cd = new er_print_histogram (dbev, dbev->func_data, mlist, MODE_ANNOTATED,
				   type == DSP_DISASM || type == DSP_DISASM_V2,
				   mlist->get_sort_name (),
				   func, false, false);
      break;

      // callers-callees
    case DSP_SELF:
    case DSP_CALLER:
    case DSP_CALLEE:
      if (dbev->sel_obj == NULL)
	return NULL;
      current_obj = dbev->sel_obj->convertto (Histable::FUNCTION);
      cd = new er_print_histogram (dbev, dbev->func_data, mlist, MODE_GPROF, 1,
				   mlist->get_sort_name (), current_obj,
				   false, false);
      break;

      // statistics; this won't use the metric list copied above, so delete it
    case DSP_STATIS:
      cd = new er_print_experiment (dbev, 0, dbeSession->nexps () - 1,
				    true, true, true, true, false);
      delete mlist;
      break;
    case DSP_EXP:
      cd = new er_print_experiment (dbev, 0, dbeSession->nexps () - 1,
				    true, true, false, false, false);
      delete mlist;
      break;
    case DSP_LEAKLIST:
      cd = new er_print_leaklist (dbev, true, true, dbev->get_limit ());
      delete mlist;
      break;
    case DSP_HEAPCALLSTACK:
      cd = new er_print_heapactivity (dbev, Histable::HEAPCALLSTACK, false,
				      dbev->get_limit ());
      delete mlist;
      break;
    case DSP_IOACTIVITY:
      cd = new er_print_ioactivity (dbev, Histable::IOACTFILE, false,
				    dbev->get_limit ());
      delete mlist;
      break;
    case DSP_IOVFD:
      cd = new er_print_ioactivity (dbev, Histable::IOACTVFD, false,
				    dbev->get_limit ());
      delete mlist;
      break;

      // the io call stack
    case DSP_IOCALLSTACK:
      cd = new er_print_ioactivity (dbev, Histable::IOCALLSTACK, false,
				    dbev->get_limit ());
      delete mlist;
      break;

      // some unknown panel -- return an error string
    default:
      delete mlist;
      return dbe_strdup (GTXT ("Print not available"));
    }

  // Start printing
  char *buf = NULL;

  // first open the file/device/whatever
  if (cd->open (&params) == 0)
    {
      // now call the actual print routine
      cd->data_dump ();
      if (params.dest == DEST_PRINTER)
	{
	  if (streq ((char *) params.name, NTXT ("-")))
	    {
	      // Special case - return report to the GUI
	      int maxbytes = 2 * 1024 * 1024; // IPC large buffer limit
	      char *report = cd->get_output (maxbytes);
	      delete data;
	      delete cd;
	      return report; // TEMPORARY
	    }
	}
      if (cd->print_output () == false)
	buf = dbe_sprintf (NTXT ("%s: %s"),
			   GTXT ("Unable to submit print request to"),
			   params.name);
    }
  else
    // if unable to set up the print, return an error
    buf = dbe_sprintf (NTXT ("%s: %s"),
		       GTXT ("Unable to open file"),
		       params.name);

  // dbe_free((void *) params.name); XXX when should this happen?
  if (data)
    if (data->isViewOwned () == false)
      delete data;
  delete cd;
  return buf;
}

// Set limit for print data
//
char *
dbeSetPrintLimit (int dbevindex, int limit)
{
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  return (dbev->set_limit (limit));
}

// get limit for print data
int
dbeGetPrintLimit (int dbevindex)
{
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  int limit = dbev->get_limit ();
  return limit;
}

// set printmode for data
char *
dbeSetPrintMode (int dbevindex, char * pmode)
{
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  char *r = dbev->set_printmode (pmode);
  return r;
}

// get printmode for data
int
dbeGetPrintMode (int dbevindex)
{
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  return (dbev->get_printmode ());
}

// get printmode for data
char *
dbeGetPrintModeString (int dbevindex)
{
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  return ( dbev->get_printmode_str ());
}

// get print delimiter for csv data
char
dbeGetPrintDelim (int dbevindex)
{
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  return (dbev->get_printdelimiter ());
}

// Set Source/Object/Load-Object file names
static void
set_file_names (Function *func, char *names[3])
{
  Module *module = func->module;
  LoadObject *loadobject = module->loadobject;
  if (loadobject == NULL)
    loadobject = dbeSession->get_Unknown_LoadObject ();
  free (names[0]);
  free (names[1]);
  free (names[2]);
  SourceFile *sf = func->getDefSrc ();
  char *src_name = sf->dbeFile->get_location_info ();
  DbeFile *df = module->dbeFile;
  if (df == NULL || (df->filetype & DbeFile::F_JAVACLASS) == 0)
    df = module->loadobject->dbeFile;
  char *lo_name = df->get_location_info ();
  char *dot_o_name = lo_name;
  if (module->dot_o_file)
    dot_o_name = module->dot_o_file->dbeFile->get_location_info ();
  names[0] = dbe_sprintf (NTXT ("%s: %s"), GTXT ("Source File"), src_name);
  names[1] = dbe_sprintf (NTXT ("%s: %s"), GTXT ("Object File"), dot_o_name);
  names[2] = dbe_sprintf (NTXT ("%s: %s"), GTXT ("Load Object"), lo_name);
}

// dbeSetFuncData
//	Master function to generate all Tab data for the analyzer
//	Returns the index of the selected item in the specified list
//
// After calling it to set up, the Analyzer calls dbeGetFuncList
//	to format the generated data and return the table
//	Most of the data is destined for a JTable
//
int
dbeSetFuncData (int dbevindex, Obj sel_obj, int type, int subtype)
{
  MetricList *_mlist;
  Histable *org_obj;
  Hist_data *data = NULL;
  int index, sel_index;
  Function *func;
  char *name;
  int ix;

  DbeView *dbev = dbeSession->getView (dbevindex);
  sel_index = -1;
  dbev->resetOmpDisMode ();
  dbev->error_msg = dbev->warning_msg = NULL;

  // get metric list, make a compact duplicate
  _mlist = dbev->get_metric_list (MET_NORMAL);
  MetricList *mlist = new MetricList (_mlist);

  // Remove old function/obj list data & Get new function/obj list data
  org_obj = (Histable *) sel_obj;

  // Figure out which "function" data is being asked for, i.e.,
  //	which of the analyzer displays is asking for data
  switch (type)
    {
      // the various tables: functions, lines, PCs, DataObjects, IndexObjects
    case DSP_FUNCTION:
    case DSP_LINE:
    case DSP_PC:
    case DSP_DATAOBJ:
    case DSP_MEMOBJ:
    case DSP_INDXOBJ:
      switch (type)
	{
	case DSP_FUNCTION:
	  if (dbev->func_data)
	    delete dbev->func_data;
	  dbev->func_data = data = dbev->get_hist_data (mlist,
				   Histable::FUNCTION, subtype, Hist_data::ALL);
	  break;
	case DSP_LINE:
	  if (dbev->line_data)
	    delete dbev->line_data;
	  dbev->line_data = data = dbev->get_hist_data (mlist,
				       Histable::LINE, subtype, Hist_data::ALL);
	  break;
	case DSP_PC:
	  if (dbev->pc_data)
	    delete dbev->pc_data;
	  dbev->pc_data = data = dbev->get_hist_data (mlist,
				      Histable::INSTR, subtype, Hist_data::ALL);
	  break;
	case DSP_DATAOBJ:
	  if (dbev->dobj_data)
	    delete dbev->dobj_data;
	  mlist = dbev->get_metric_list (MET_DATA);
	  dbev->dobj_data = data = dbev->get_hist_data (mlist,
				    Histable::DOBJECT, subtype, Hist_data::ALL);
	  break;
	case DSP_MEMOBJ:
	  mlist = dbev->get_metric_list (MET_DATA);
	  data = dbev->get_hist_data (mlist, Histable::MEMOBJ, subtype,
				      Hist_data::ALL);
	  dbev->indx_data->store (subtype, data);
	  break;
	case DSP_INDXOBJ:
	  mlist = dbev->get_metric_list (MET_INDX);
	  data = dbev->get_hist_data (mlist, Histable::INDEXOBJ, subtype,
				      Hist_data::ALL);
	  dbev->indx_data->store (subtype, data);
	  break;
	default:
	  break;
	}

      // Set the selection of row item
      if (data->get_status () == Hist_data::SUCCESS)
	{
	  // otherwise, look for it
	  sel_index = -1;
	  if (org_obj)
	    {
	      Hist_data::HistItem *hi;
	      Vec_loop (Hist_data::HistItem*, data->get_hist_items (), index, hi)
	      {
		if (hi->obj == org_obj)
		  {
		    sel_index = index;
		    break;
		  }
	      }
	      if (sel_index == -1 && (type == DSP_LINE || type == DSP_PC))
		{
		  Vec_loop (Hist_data::HistItem*, data->get_hist_items (), index, hi)
		  {
		    name = hi->obj->get_name ();
		    if (strcmp (name, NTXT ("<Total>")) &&
			strcmp (name, GTXT ("<Unknown>")))
		      {
			int done = 0;
			switch (type)
			  {
			  case DSP_LINE:
			    if (org_obj->convertto (Histable::FUNCTION)
				     == hi->obj->convertto (Histable::FUNCTION))
			      {
				sel_index = index;
				done = 1;
			      }
			    break;
			  case DSP_PC:
			    if (hi->obj->convertto (Histable::FUNCTION)
				== org_obj->convertto (Histable::FUNCTION)
				&& ((DbeLine*) hi->obj->convertto (Histable::LINE))->lineno
				== ((DbeLine*) org_obj->convertto (Histable::LINE))->lineno)
			      {
				sel_index = index;
				done = 1;
			      }
			    break;
			  }
			if (done)
			  break;
		      }
		  }
		}
	      if (sel_index == -1 && type == DSP_PC)
		{
		  Vec_loop (Hist_data::HistItem*, data->get_hist_items (), index, hi)
		  {
		    name = hi->obj->get_name ();
		    if (strcmp (name, NTXT ("<Total>")) &&
			strcmp (name, GTXT ("<Unknown>")))
		      {
			int done = 0;
			if (hi->obj->convertto (Histable::FUNCTION) ==
			    org_obj->convertto (Histable::FUNCTION))
			  {
			    sel_index = index;
			    done = 1;
			  }
			if (done)
			  break;
		      }
		  }
		}
	    }
	  if (sel_index == -1)
	    {
	      Hist_data::HistItem *hi;
	      Vec_loop (Hist_data::HistItem*, data->get_hist_items (), index, hi)
	      {
		name = hi->obj->get_name ();
		if (strcmp (name, NTXT ("<Total>")) &&
		    strcmp (name, GTXT ("<Unknown>")))
		  {
		    sel_index = index;
		    break;
		  }
	      }
	    }
	}
      else
	dbev->error_msg = DbeView::status_str (DbeView::DBEVIEW_NO_DATA);
      return sel_index;
      // the end of the code for the regular tables

      // Data Layout
    case DSP_DLAYOUT:
      if (dbev->dlay_data)
	delete dbev->dlay_data;
      dbev->marks->reset ();
      mlist = dbev->get_metric_list (MET_DATA);

      // initial dobj list ...
      data = dbev->get_hist_data (mlist, Histable::DOBJECT, subtype,
				  Hist_data::LAYOUT);
      // .. provides metric data for layout
      dbev->dlay_data = data = dbev->get_data_space ()->get_layout_data (data,
					  dbev->marks, dbev->get_thresh_dis ());
      if (data->get_status () != Hist_data::SUCCESS)
	dbev->error_msg = DbeView::status_str (DbeView::DBEVIEW_NO_DATA);
      return sel_index;

      // Source or disassembly
    case DSP_SOURCE_V2:
    case DSP_DISASM_V2:
    case DSP_SOURCE:
    case DSP_DISASM:
      {
	if (org_obj == NULL)
	  {
	    dbev->error_msg = DbeView::status_str (DbeView::DBEVIEW_NO_SEL_OBJ);
	    return sel_index;
	  }
	if (org_obj->get_type () != Histable::FUNCTION)
	  {
	    dbev->error_msg = dbe_strdup (
	     GTXT ("Not a real function; no source or disassembly available."));
	    return sel_index;
	  }
	func = (Function *) org_obj;
	if (func->flags & FUNC_FLAG_SIMULATED)
	  {
	    dbev->error_msg = dbe_strdup (
	     GTXT ("Not a real function; no source or disassembly available."));
	    return sel_index;
	  }
	if (func->get_name () == NULL)
	  {
	    dbev->error_msg = dbe_strdup (
			   GTXT ("Source location not recorded in experiment"));
	    return sel_index;
	  }
	Module *module = func->module;
	if ((module == NULL) || (module->get_name () == NULL))
	  {
	    dbev->error_msg = dbe_strdup (
			       GTXT ("Object name not recorded in experiment"));
	    return sel_index;
	  }
	ix = module->loadobject->seg_idx;
	if (dbev->get_lo_expand (ix) == LIBEX_HIDE)
	  {
	    dbev->error_msg = dbe_strdup (
		 GTXT ("No source or disassembly available for hidden object"));
	    return sel_index;
	  }

	if ((type == DSP_DISASM || type == DSP_DISASM_V2)
	     && dbev->get_view_mode () == VMODE_USER
	    && dbeSession->is_omp_available ())
	  dbev->setOmpDisMode ();

	dbev->marks->reset ();
	SourceFile *srcContext = NULL;
	switch (dbev->sel_obj->get_type ())
	  {
	  case Histable::FUNCTION:
	    {
	      Function *f = (Function *) dbev->sel_obj;
	      srcContext = f->getDefSrc ();
	      dbev->sel_binctx = f->module;
	      break;
	    }
	  case Histable::LINE:
	    {
	      DbeLine *dl = (DbeLine *) dbev->sel_obj;
	      srcContext = dl->sourceFile;
	      Function *f = dl->func;
	      if (f)
		dbev->sel_binctx = f;
	      break;
	    }
	  case Histable::INSTR:
	    {
	      Function *f = (Function *) dbev->sel_obj->convertto (Histable::FUNCTION);
	      if (f)
		{
		  dbev->sel_binctx = f;
		  srcContext = f->getDefSrc ();
		}
	      break;
	    }
	  default:
	    break;
	  }
	mlist = dbev->get_metric_list (MET_SRCDIS);

	// for source and disassembly the name needs to be invisible,
	//	but that's handled in the module code
	if (type == DSP_SOURCE)
	  {
	    if (dbev->src_data)
	      delete dbev->src_data;

	    // func_data computation needed for get_totals
	    if (dbev->func_data == NULL)
	      dbev->func_data = data = dbev->get_hist_data (mlist,
				   Histable::FUNCTION, subtype, Hist_data::ALL);
	    dbev->marks2dsrc->reset ();
	    dbev->marks2dsrc_inc->reset ();
	    data = dbev->src_data = module->get_data (dbev, mlist,
			  Histable::LINE, dbev->func_data->get_totals ()->value,
			  srcContext, func, dbev->marks,
			  dbev->get_thresh_src (), dbev->get_src_compcom (),
			  dbev->get_src_visible (), dbev->get_hex_visible (),
			  false, false, dbev->marks2dsrc, dbev->marks2dsrc_inc);
	    set_file_names (func, dbev->names_src);
	    if (srcContext)
	      {
		free (dbev->names_src[0]);
		dbev->names_src[0] = dbe_sprintf (GTXT ("Source File: %s"),
				     srcContext->dbeFile->get_location_info ());
	      }
	    Obj obj = (Obj) func->convertto (Histable::LINE, srcContext);
	    sel_index = dbeGetSelIndex (dbevindex, obj, type, subtype);
	  }
	else
	  { /* type == DSP_DISASM */
	    if (dbev->dis_data)
	      delete dbev->dis_data;

	    // func_data computation needed for get_totals
	    if (dbev->func_data == NULL)
	      dbev->func_data = data = dbev->get_hist_data (mlist,
				  Histable::FUNCTION, subtype, Hist_data::ALL);
	    dbev->marks2ddis->reset ();
	    dbev->marks2ddis_inc->reset ();
	    data = dbev->dis_data = module->get_data (dbev, mlist,
			 Histable::INSTR, dbev->func_data->get_totals ()->value,
			 srcContext, func, dbev->marks, dbev->get_thresh_dis (),
			 dbev->get_dis_compcom (), dbev->get_src_visible (),
			 dbev->get_hex_visible (), dbev->get_func_scope (),
			 false, dbev->marks2ddis, dbev->marks2ddis_inc);
	    set_file_names (func, dbev->names_dis);
	    if (srcContext)
	      {
		free (dbev->names_dis[0]);
		dbev->names_dis[0] = dbe_sprintf (GTXT ("Source File: %s"),
				    srcContext->dbeFile->get_location_info ());
	      }
	    Obj obj = (Obj) func->convertto (Histable::INSTR);
	    sel_index = dbeGetSelIndex (dbevindex, obj, type, subtype);
	  }
	return sel_index;
      }

      // the three cases for caller-callee
    case DSP_SELF:
    case DSP_CALLER:
    case DSP_CALLEE:
      if (org_obj == NULL)
	{
	  dbev->error_msg = DbeView::status_str (DbeView::DBEVIEW_NO_SEL_OBJ);
	  return sel_index;
	}

      // Caller data
      if (dbev->callers)
	delete dbev->callers;
      mlist = dbev->get_metric_list (MET_CALL);
      dbev->callers = dbev->get_hist_data (mlist, Histable::FUNCTION, subtype,
					   Hist_data::CALLERS, org_obj);
      if (dbev->callers->get_status () != Hist_data::SUCCESS)
	{
	  dbev->error_msg = DbeView::status_str (DbeView::DBEVIEW_NO_DATA);
	  return sel_index;
	}

      // Callee data
      if (dbev->callees)
	delete dbev->callees;
      dbev->callees = dbev->get_hist_data (mlist, Histable::FUNCTION, subtype,
					   Hist_data::CALLEES, org_obj);
      if (dbev->callees->get_status () != Hist_data::SUCCESS)
	{
	  dbev->error_msg = DbeView::status_str (DbeView::DBEVIEW_NO_DATA);
	  return sel_index;
	}

      // Center Function item
      if (dbev->fitem_data)
	delete dbev->fitem_data;
      dbev->fitem_data = dbev->get_hist_data (mlist, Histable::FUNCTION, subtype,
					      Hist_data::SELF, org_obj);
      if (dbev->fitem_data->get_status () != Hist_data::SUCCESS)
	{
	  dbev->error_msg = DbeView::status_str (DbeView::DBEVIEW_NO_DATA);
	  return sel_index;
	}
      return sel_index;
    default:
      abort ();
    }
  return sel_index;
}

Vector<void*>*
dbeGetTotals (int dbevindex, int dsptype, int subtype)
{
  DbeView *dbev = dbeSession->getView (dbevindex);
  MetricList *mlist = dbev->get_metric_list (dsptype, subtype);
  Hist_data *data = dbev->get_hist_data (mlist, Histable::FUNCTION, 0,
					 Hist_data::ALL);
  Hist_data::HistItem *totals = data->get_totals ();
  Vector<void*> *tbl = new Vector<void*>(mlist->size ());
  for (long i = 0, sz = mlist->size (); i < sz; i++)
    {
      Metric *m = mlist->get (i);
      switch (m->get_vtype ())
	{
	case VT_DOUBLE:
	  {
	    Vector<double> *lst = new Vector<double>(1);
	    lst->append (totals->value[i].d);
	    tbl->append (lst);
	    break;
	  }
	case VT_INT:
	  {
	    Vector<int> *lst = new Vector<int>(1);
	    lst->append (totals->value[i].i);
	    tbl->append (lst);
	    break;
	  }
	case VT_LLONG:
	case VT_ULLONG:
	case VT_ADDRESS:
	  {
	    Vector<long long> *lst = new Vector<long long>(1);
	    lst->append (totals->value[i].ll);
	    tbl->append (lst);
	    break;
	  }
	case VT_LABEL:
	  {
	    Vector<char *> *lst = new Vector<char *>(1);
	    Histable::NameFormat nfmt = dbev->get_name_format ();
	    lst->append (dbe_strdup (totals->obj->get_name (nfmt)));
	    tbl->append (lst);
	    break;
	  }
	default:
	  abort ();
	}
    }
  Vector<void*> *res = new Vector<void*>(2);
  res->append (dbeGetMetricList (mlist));
  res->append (tbl);
  return res;
}

Vector<void*>*
dbeGetHotMarks (int dbevindex, int type)
{
  Vector<void*>* table = new Vector<void*>(2);
  Vector<int>* table0 = new Vector<int> ();
  Vector<int>* table1 = new Vector<int> ();
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    return NULL;

  switch (type)
    {
    case DSP_SOURCE:
    case DSP_SOURCE_V2:
      for (int i = 0; i < dbev->marks2dsrc->size (); i++)
	{
	  table0->append (dbev->marks2dsrc->fetch (i).index1);
	  table1->append (dbev->marks2dsrc->fetch (i).index2);
	}
      break;
    case DSP_DISASM:
    case DSP_DISASM_V2:
      for (int i = 0; i < dbev->marks2ddis->size (); i++)
	{
	  table0->append (dbev->marks2ddis->fetch (i).index1);
	  table1->append (dbev->marks2ddis->fetch (i).index2);
	}
      break;
    default:
      break;
    }
  table->store (0, table0);
  table->store (1, table1);
  return table;
}

Vector<void*>*
dbeGetHotMarksInc (int dbevindex, int type)
{
  Vector<void*>* table = new Vector<void*>(2);
  Vector<int>* table0 = new Vector<int> ();
  Vector<int>* table1 = new Vector<int> ();
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    return NULL;

  switch (type)
    {
    case DSP_SOURCE:
    case DSP_SOURCE_V2:
      for (int i = 0; i < dbev->marks2dsrc_inc->size (); i++)
	{
	  table0->append (dbev->marks2dsrc_inc->fetch (i).index1);
	  table1->append (dbev->marks2dsrc_inc->fetch (i).index2);
	}
      break;
    case DSP_DISASM:
    case DSP_DISASM_V2:
      for (int i = 0; i < dbev->marks2ddis_inc->size (); i++)
	{
	  table0->append (dbev->marks2ddis_inc->fetch (i).index1);
	  table1->append (dbev->marks2ddis_inc->fetch (i).index2);
	}
      break;
    default:
      break;
    }
  table->store (0, table0);
  table->store (1, table1);
  return table;
}

Vector<void*>*
dbeGetSummaryHotMarks (int dbevindex, Vector<Obj> *sel_objs, int type)
{
  Vector<void*>* table = new Vector<void*>(2);
  Vector<int>* table0 = new Vector<int> ();
  Vector<int>* table1 = new Vector<int> ();
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    return NULL;
  if (sel_objs == NULL || sel_objs->size () == 0)
    return NULL;

  Hist_data *data;
  Vector<int_pair_t> *marks2d;
  Vector<int_pair_t>* marks2d_inc;
  switch (type)
    {
    case DSP_SOURCE:
    case DSP_SOURCE_V2:
      data = dbev->src_data;
      marks2d = dbev->marks2dsrc;
      marks2d_inc = dbev->marks2dsrc_inc;
      break;
    case DSP_DISASM:
    case DSP_DISASM_V2:
      data = dbev->dis_data;
      marks2d = dbev->marks2ddis;
      marks2d_inc = dbev->marks2ddis_inc;
      break;
    default:
      data = NULL;
      marks2d = NULL;
      marks2d_inc = NULL;
      break;
    }
  if (data == NULL || data->get_status () != Hist_data::SUCCESS
      || marks2d_inc == NULL || marks2d == NULL)
    return NULL;

  MetricList *orig_mlist = data->get_metric_list ();
  MetricList *prop_mlist = new MetricList (dbev->get_metric_ref (MET_NORMAL));
  if (prop_mlist && dbev->comparingExperiments ())
    prop_mlist = dbev->get_compare_mlist (prop_mlist, 0);
  Metric *mitem;
  int index, index2;
  index2 = 0;
  Vec_loop (Metric*, prop_mlist->get_items (), index, mitem)
  {
    if (mitem->get_subtype () == Metric::STATIC)
      continue;

    for (int i = 0; i < marks2d_inc->size (); i++)
      {
	int found = 0;
	for (int j = 0; j < sel_objs->size (); j++)
	  {
	    int sel_index = (int) sel_objs->fetch (j);
	    int marked_index = marks2d_inc->fetch (i).index1;
	    if (sel_index == marked_index)
	      {
		found = 1;
		break;
	      }
	  }
	if (!found)
	  continue;
	int mindex = marks2d_inc->fetch (i).index2;
	Metric *orig_metric = orig_mlist->get_items ()->fetch (mindex);
	if (orig_metric->get_id () == mitem->get_id ()
	    && mitem->get_subtype () == Metric::INCLUSIVE)
	  {
	    table0->append (index2);
	    table1->append (1);
	  }
      }

    for (int i = 0; i < marks2d->size (); i++)
      {
	int found = 0;
	for (int j = 0; j < sel_objs->size (); j++)
	  {
	    int sel_index = (int) sel_objs->fetch (j);
	    int marked_index = marks2d->fetch (i).index1;
	    if (sel_index == marked_index)
	      {
		found = 1;
		break;
	      }
	  }
	if (!found)
	  continue;
	int mindex = marks2d->fetch (i).index2;
	Metric *orig_metric = orig_mlist->get_items ()->fetch (mindex);
	if (orig_metric->get_id () == mitem->get_id ()
	    && mitem->get_subtype () == Metric::EXCLUSIVE)
	  {
	    table0->append (index2);
	    table1->append (0);
	  }
      }
    if (!(mitem->get_subtype () == Metric::EXCLUSIVE
	  || mitem->get_subtype () == Metric::DATASPACE))
      index2++;
  }
  table->store (0, table0);
  table->store (1, table1);
  return table;
}

// Get a vector of function ids of data(begin, begin + length - 1)
// Currently only support source/disassembly view
Vector<uint64_t>*
dbeGetFuncId (int dbevindex, int type, int begin, int length)
{
  Vector<uint64_t>* table = new Vector<uint64_t > ();
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();

  Hist_data *data;
  Function* given_func = NULL;
  switch (type)
    {
    case DSP_SOURCE:
    case DSP_SOURCE_V2:
      data = dbev->src_data;
      break;
    case DSP_DISASM:
    case DSP_DISASM_V2:
      data = dbev->dis_data;
      break;
    default:
      data = NULL;
      abort ();
    }

  if (data == NULL || data->get_status () != Hist_data::SUCCESS)
    return NULL;

  if (begin < 0 || begin + length > data->size ())
    return NULL;

  switch (type)
    {
    case DSP_SOURCE:
    case DSP_SOURCE_V2:
    case DSP_DISASM:
    case DSP_DISASM_V2:
      {
	for (int i = begin; i < begin + length; i++)
	  {
	    given_func = NULL;
	    Histable * sel_obj = data->fetch (i)->obj;
	    if (sel_obj != NULL)
	      given_func = (Function*) (sel_obj)->convertto (Histable::FUNCTION, (Histable*) dbev);
	    if (given_func == NULL)
	      table->append (0);
	    else
	      table->append (given_func->id);
	  }
      }
      break;
    default:
      abort ();
    }
  return table;
}

Vector<void*>*
dbeGetFuncCallerInfo (int dbevindex, int type, Vector<int>* idxs, int groupId)
{
  Vector<void*>* data = new Vector<void*>();
  if (type == DSP_SOURCE_V2 || type == DSP_DISASM_V2)
    {
      Obj sel_func = dbeGetSelObj (dbevindex, DSP_FUNCTION, 0);
      if (sel_func == 0)
	return data;
      Vector<Obj> * cmpObjs = dbeGetComparableObjsV2 (dbevindex, sel_func, type);
      if (cmpObjs == NULL)
	return data;
      DbeView *dbev = dbeSession->getView (dbevindex);
      int mtype = MET_COMMON | COMPARE_BIT | ((groupId + 1) << GROUP_ID_SHIFT);
      MetricList *mlist = dbev->get_metric_list ((MetricType) (mtype & MTYPE_MASK),
						 (mtype & COMPARE_BIT) != 0,
						 mtype >> GROUP_ID_SHIFT);
      Histable *selObj = (Histable *) cmpObjs->fetch (groupId);
      int subtype = 0;
      Hist_data *hist_data = dbev->get_data (mlist, selObj, type, subtype);
      if (hist_data == NULL)
	return data;
    }
  for (int i = 0; i < idxs->size (); i++)
    data->append (dbeGetFuncCallerInfoById (dbevindex, type, idxs->fetch (i)));
  return data;
}

//
// Get Table of Caller info:
// param: idx -- selected AT_FUNC row
// return: callsite_id, callsite_name (function: file: line)
Vector<void*>*
dbeGetFuncCallerInfoById (int dbevindex, int type, int idx)
{
  Vector<void*>* table = new Vector<void*>(3);
  Vector<uint64_t>* table0 = new Vector<uint64_t> ();
  Vector<int>* table1 = new Vector<int> ();
  Vector<char*>* table2 = new Vector<char*>();

  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  Hist_data *data;
  Function* given_func = NULL;
  Vector<Histable*> *instr_info = NULL;
  switch (type)
    {
    case DSP_SOURCE:
    case DSP_SOURCE_V2:
      data = dbev->src_data;
      break;
    case DSP_DISASM:
    case DSP_DISASM_V2:
      data = dbev->dis_data;
      break;
    default:
      data = NULL;
      abort ();
    }
  if (data == NULL || data->get_status () != Hist_data::SUCCESS)
    return NULL;

  if (idx < 0 || idx >= data->size ())
    return NULL;
  switch (type)
    {
    case DSP_SOURCE:
    case DSP_SOURCE_V2:
    case DSP_DISASM:
    case DSP_DISASM_V2:
      {
	Histable * sel_obj = data->fetch (idx)->obj;
	if (sel_obj == NULL)
	  return NULL;
	given_func = (Function*) (sel_obj)->convertto (Histable::FUNCTION, (Histable*) dbev);
	if (given_func == NULL)
	  return NULL;
	PathTree * ptree = dbev->get_path_tree ();
	if (ptree == NULL)
	  return NULL;
	instr_info = ptree->get_clr_instr (given_func);
	DefaultMap<uint64_t, int> * line_seen = new DefaultMap<uint64_t, int>();
	for (int j = 0; j < ((Vector<Histable*>*)instr_info)->size (); j++)
	  {
	    Histable *instr = ((Vector<Histable*>*)instr_info)->fetch (j);
	    Function *cur_func = NULL;
	    if (instr->get_type () == Histable::INSTR)
	      cur_func = ((DbeInstr*) instr)->func;
	    else if (instr->get_type () == Histable::LINE)
	      cur_func = ((DbeLine*) instr)->func;
	    if (cur_func == NULL || (cur_func->flags & FUNC_FLAG_SIMULATED))
		continue; // skip functions like <Total>
	    Histable* line;
	    switch (type)
	      {
	      case DSP_SOURCE:
	      case DSP_SOURCE_V2:
		if (cur_func != NULL)
		  {
		    SourceFile *sourceFile = cur_func->getDefSrc ();
		    if (sourceFile == NULL ||
			(sourceFile->flags & SOURCE_FLAG_UNKNOWN) != 0)
		      continue; // skip functions like <Function: %s, instructions without line numbers>
		  }
		line = instr->convertto (Histable::LINE, NULL);
		break;
	      case DSP_DISASM:
	      case DSP_DISASM_V2:
		line = instr->convertto (Histable::INSTR, NULL);
		break;
	      default:
		abort ();
	      }
	    uint64_t func_id = cur_func->id;
	    uint64_t line_id = instr->id;
	    int is_null = 0;
	    int line_no = -1;
	    switch (type)
	      {
	      case DSP_SOURCE:
	      case DSP_SOURCE_V2:
		is_null = (((DbeLine*) line)->func == NULL) ? 1 : 0;
		if (is_null)
		  ((DbeLine*) line)->func = cur_func;
		line_no = ((DbeLine*) line)->lineno;
		if (line_seen->get (line_id) == 0)
		  {
		    line_seen->put (line_id, 1);
		    table0->append (func_id);
		    table1->append (line_no);
		    Histable::NameFormat nfmt = dbev->get_name_format ();
		    table2->append (dbe_strdup (line->get_name (nfmt)));
		  }
		if (is_null)
		  ((DbeLine*) line)->func = NULL;
		break;
	      case DSP_DISASM:
	      case DSP_DISASM_V2:
		is_null = (((DbeInstr*) line)->func == NULL) ? 1 : 0;
		if (is_null)
		  ((DbeInstr*) line)->func = cur_func;
		line_no = ((DbeInstr*) line)->addr;
		if (line_seen->get (line_id) == 0)
		  {
		    line_seen->put (line_id, 1);
		    table0->append (func_id);
		    table1->append (line_no);
		    Histable::NameFormat nfmt = dbev->get_name_format ();
		    table2->append (dbe_strdup (line->get_name (nfmt)));
		  }
		if (is_null)
		  ((DbeInstr*) line)->func = NULL;
		break;
	      default:
		abort ();
	      }
	 }
	delete line_seen;
	delete instr_info;
      }
      break;
    default:
      abort ();
    }
  table->store (0, table0);
  table->store (1, table1);
  table->store (2, table2);
  return table;
}

Vector<void*>*
dbeGetFuncCalleeInfo (int dbevindex, int type, Vector<int>* idxs, int groupId)
{
  Vector<void*>* data = new Vector<void*>();
  if (type == DSP_SOURCE_V2 || type == DSP_DISASM_V2)
    {
      Obj sel_func = dbeGetSelObj (dbevindex, DSP_FUNCTION, 0);
      if (sel_func == 0)
	return data;
      Vector<Obj> * cmpObjs = dbeGetComparableObjsV2 (dbevindex, sel_func, type);
      if (cmpObjs == NULL)
	return data;
      DbeView *dbev = dbeSession->getView (dbevindex);
      int mtype = MET_COMMON | COMPARE_BIT | ((groupId + 1) << GROUP_ID_SHIFT);
      MetricList *mlist = dbev->get_metric_list ((MetricType) (mtype & MTYPE_MASK),
						 (mtype & COMPARE_BIT) != 0,
						 mtype >> GROUP_ID_SHIFT);
      Histable *selObj = (Histable *) cmpObjs->fetch (groupId);
      int subtype = 0;
      Hist_data *hist_data = dbev->get_data (mlist, selObj, type, subtype);
      if (hist_data == NULL)
	return data;
    }

  for (int i = 0; i < idxs->size (); i++)
    data->append (dbeGetFuncCalleeInfoById (dbevindex, type, idxs->fetch (i)));
  return data;
}

//
// Get Table of Callee info:
// param: idx -- selected AT_FUNC row
// return: callsite_row, callee_id, callee_name
//
Vector<void*>*
dbeGetFuncCalleeInfoById (int dbevindex, int type, int idx)
{
  Vector<void*>* table = new Vector<void*>(3);
  Vector<int>* table0 = new Vector<int>();
  Vector<uint64_t>* table1 = new Vector<uint64_t > ();
  Vector<char*>* table2 = new Vector<char*>();
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  Hist_data *data;
  Function* given_func = NULL;
  Vector<Histable*> *instr_info = NULL;
  Vector<void*> *func_info = NULL;

  switch (type)
    {
    case DSP_SOURCE:
    case DSP_SOURCE_V2:
      data = dbev->src_data;
      break;
    case DSP_DISASM:
    case DSP_DISASM_V2:
      data = dbev->dis_data;
      break;
    default:
      data = NULL;
      abort ();
    }
  if (data == NULL || data->get_status () != Hist_data::SUCCESS)
    return NULL;
  if (idx < 0 || idx >= data->size ())
    return NULL;
  switch (type)
    {
    case DSP_SOURCE:
    case DSP_SOURCE_V2:
    case DSP_DISASM:
    case DSP_DISASM_V2:
      {
	Histable * sel_obj = data->fetch (idx)->obj;
	if (sel_obj == NULL)
	  return NULL;
	given_func = (Function*) (sel_obj)->convertto (Histable::FUNCTION, (Histable*) dbev);
	if (given_func == NULL)
	  return NULL;
	PathTree * ptree = dbev->get_path_tree ();
	if (ptree == NULL)
	  return NULL;
	Vector<Histable*> *instrs = NULL;
	Vector<void*> *callee_instrs = ptree->get_cle_instr (given_func, instrs);
	func_info = new Vector<void*>();
	instr_info = new Vector<Histable*>();
	for (long a = 0, sz_a = callee_instrs ? callee_instrs->size () : 0; a < sz_a; a++)
	  {
	    Vector<Histable*> *temp = ((Vector<Vector<Histable*>*>*)callee_instrs)->get (a);
	    DefaultMap<Function*, int> * func_seen = new DefaultMap<Function*, int>();
	    Histable* instr0 = (Histable*) instrs->fetch (a);
	    for (long b = 0, sz_b = temp ? temp->size () : 0; b < sz_b; b++)
	      {
		Histable *instr = temp->get (b);
		if (instr->get_type () == Histable::INSTR)
		  {
		    Function* func1 = ((DbeInstr *) instr)->func;
		    func_seen->put (func1, 1);
		  }
		else if (instr->get_type () == Histable::LINE)
		  {
		    Function* func1 = ((DbeLine *) instr)->func;
		    func_seen->put (func1, 1);
		  }
	      }
	    Vector<Function*> *funcs = func_seen->keySet ();
	    delete func_seen;
	    if (funcs->size () > 0)
	      {
		instr_info->append (instr0);
		func_info->append (funcs);
	      }
	  }
	delete instrs;
	destroy (callee_instrs);

	DefaultMap<uint64_t, Vector<int>* > * instr_idxs = new DefaultMap<uint64_t, Vector<int>* >();
	DefaultMap<uint64_t, int> * func_idxs = new DefaultMap<uint64_t, int>();
	for (long j = 0, sz_j = instr_info ? instr_info->size () : 0; j < sz_j; j++)
	  {
	    Histable *instr = instr_info->get (j);
	    Function *cur_func = NULL;
	    if (instr->get_type () == Histable::INSTR)
	      cur_func = ((DbeInstr*) instr)->func;
	    else if (instr->get_type () == Histable::LINE)
	      cur_func = ((DbeLine*) instr)->func;
	    if (cur_func != NULL && (cur_func->flags & FUNC_FLAG_SIMULATED))
	      continue; // skip functions like <Total>
	    Histable* line;
	    switch (type)
	      {
	      case DSP_SOURCE:
	      case DSP_SOURCE_V2:
		if (cur_func != NULL)
		  {
		    SourceFile *sourceFile = cur_func->getDefSrc ();
		    if (sourceFile == NULL ||
			(sourceFile->flags & SOURCE_FLAG_UNKNOWN) != 0)
		      // skip functions like <Function: %s, instructions without line numbers>
		      continue;
		  }
		line = instr->convertto (Histable::LINE, NULL);
		if (type == DSP_SOURCE_V2)
		  line = dbev->get_compare_obj (line);
		break;
	      case DSP_DISASM:
	      case DSP_DISASM_V2:
		line = instr;
		if (type == DSP_DISASM_V2)
		  line = dbev->get_compare_obj (line);
		break;
	      default:
		abort ();
	      }
	    if (func_idxs->get (line->id) == 0)
	      {
		func_idxs->put (line->id, 1);
		Vector<int> *temp_idx = new Vector<int>();
		temp_idx->append (j);
		instr_idxs->put (line->id, temp_idx);
	      }
	    else
	      {
		Vector<int> *temp_idx = instr_idxs->get (line->id);
		temp_idx->append (j);
	      }
	  }
	for (long i = 0; i < data->size (); i++)
	  {
	    Histable* line = data->fetch (i)->obj;
	    if (line == NULL)
	      continue;
	    Vector<int> * instr_idx = instr_idxs->get (line->id);
	    if (instr_idx == NULL)
	      continue;
	    for (long j = 0; j < instr_idx->size (); j++)
	      {
		Vector<void*>* callee_funcs_vec = (Vector<void*>*)func_info;
		if (callee_funcs_vec->size () == 0)
		  continue;
		Vector<Function*>* callee_funcs_value = (Vector<Function*>*)callee_funcs_vec->fetch (instr_idx->fetch (j));
		for (int k = 0; callee_funcs_value != NULL && k < callee_funcs_value->size (); k++)
		  {
		    uint64_t funcobj_id = ((Function*) callee_funcs_value->fetch (k))->id;
		    int old_size = table0->size ();
		    if (old_size > 0 && i == table0->fetch (old_size - 1)
			&& funcobj_id == table1->fetch (old_size - 1))
		      continue;
		    table0->append (i);
		    table1->append (funcobj_id);
		    table2->append (dbe_strdup (((Function*) callee_funcs_value->fetch (k))->get_name ()));
		  }
	      }
	  }
	delete instr_idxs;
	delete func_idxs;
	destroy (func_info);
	delete instr_info;
      }
      break;
    default:
      abort ();
    }
  table->store (0, table0);
  table->store (1, table1);
  table->store (2, table2);
  return table;
}

//
// Get Table of Function List data with only total values
//
Vector<void*> *
dbeGetFuncListMini (int dbevindex, int type, int /*subtype*/)
{
  Hist_data *data;
  DbeView *dbev = dbeSession->getView (dbevindex);
  switch (type)
    {
    case DSP_FUNCTION:
      data = dbev->func_data;
      break;
    default:
      data = NULL;
      break;
    }
  if (data == NULL || data->get_status () != Hist_data::SUCCESS)
    return NULL;

  MetricList *mlist = data->get_metric_list ();

  // Get table size: count visible metrics
  int nvisible = 0;
  for (long i = 0, sz = mlist->size (); i < sz; i++)
    {
      Metric *m = mlist->get (i);
      if (m->is_visible () || m->is_tvisible () || m->is_pvisible ())
	nvisible++;
    }
  Vector<void*> *table = new Vector<void*>(nvisible + 1);

  // Fill function list elements
  Hist_data::HistItem *totals = data->get_totals ();
  for (long i = 0, sz = mlist->size (); i < sz; i++)
    {
      Metric *m = mlist->get (i);
      if (!m->is_visible () && !m->is_tvisible () && !m->is_pvisible ())
	continue;
      TValue res;
      TValue *v = data->get_value (&res, i, totals);
      if ((m->get_visbits () & VAL_RATIO) != 0)
	{
	  Vector<double> *col = new Vector<double>(1);
	  double d = (v->tag != VT_LABEL) ? v->to_double () : 100.; // NaN
	  col->append (d);
	  table->append (col);
	  continue;
	}
      switch (m->get_vtype ())
	{
	case VT_INT:
	  {
	    Vector<int> *col = new Vector<int>(1);
	    col->append (v->i);
	    table->append (col);
	    break;
	  }
	case VT_ADDRESS:
	case VT_ULLONG:
	case VT_LLONG:
	  {
	    Vector<long long> *col = new Vector<long long>(1);
	    col->append (v->ll);
	    table->append (col);
	    break;
	  }
	case VT_LABEL:
	  {
	    Vector<char *> *col = new Vector<char *>(1);
	    col->append (dbe_strdup (v->l));
	    table->append (col);
	    break;
	  }
	case VT_DOUBLE:
	default:
	  {
	    Vector<double> *col = new Vector<double>(1);
	    col->append (v->d);
	    table->append (col);
	    break;
	  }
	}
    }
  table->append (NULL);
  return table;
}

// Get Table of Function List data
Vector<void*> *
dbeGetFuncList (int dbevindex, int type, int subtype)
{
  MetricList *mlist;
  Metric *mitem;
  int nitems, nvisible;
  int index, index2, nv;
  char *cell;
  Vector<int> *ji_list;
  Hist_data *data;
  Hist_data::HistItem *item;

  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();

  // fprintf(stderr, NTXT("XXX dbeGetFuncList, FuncListDisp_type = %d\n"), type);
  switch (type)
    {
    case DSP_FUNCTION:
      data = dbev->func_data;
      break;
    case DSP_LINE:
      data = dbev->line_data;
      break;
    case DSP_PC:
      data = dbev->pc_data;
      break;
    case DSP_SOURCE:
    case DSP_SOURCE_V2:
      data = dbev->src_data;
      break;
    case DSP_DISASM:
    case DSP_DISASM_V2:
      data = dbev->dis_data;
      break;
    case DSP_SELF:
      data = dbev->fitem_data;
      break;
    case DSP_CALLER:
      data = dbev->callers;
      break;
    case DSP_CALLEE:
      data = dbev->callees;
      break;
    case DSP_DLAYOUT:
      data = dbev->dlay_data;
      break;
    case DSP_DATAOBJ:
      data = dbev->dobj_data;
      break;
    case DSP_MEMOBJ:
    case DSP_INDXOBJ:
      data = dbev->get_indxobj_data (subtype);
      break;
    default:
      data = NULL;
      break;
    }
  if (data == NULL || data->get_status () != Hist_data::SUCCESS)
    return NULL;
  mlist = data->get_metric_list ();

  // Get table size: count visible metrics
  nitems = data->size ();
  nvisible = 0;
  Vec_loop (Metric*, mlist->get_items (), index, mitem)
  {
    if (mitem->is_visible () || mitem->is_tvisible () || mitem->is_pvisible ())
      nvisible++;
  }

  // Initialize Java String array
  Vector<void*> *table = new Vector<void*>(nvisible + 1);

  // Mark Hi-value metric items for annotated src/dis/layout
  if (type == DSP_SOURCE || type == DSP_DISASM || type == DSP_DLAYOUT
      || type == DSP_SOURCE_V2 || type == DSP_DISASM_V2)
    {
      ji_list = new Vector<int>(nitems);

      if (dbev->marks->size () > 0)
	index = dbev->marks->fetch (0);
      else
	index = -1;
      int mindex = 0;
      for (index2 = 0; index2 < nitems; index2++)
	{
	  item = data->fetch (index2);
	  if (index2 == index)
	    {
	      ji_list->store (index2, -item->type);
	      if (++mindex < dbev->marks->size ())
		index = dbev->marks->fetch (mindex);
	      else
		index = -1;
	    }
	  else
	    ji_list->store (index2, item->type);
	}
      table->store (nvisible, ji_list);
    }
  else
    table->store (nvisible, NULL);

  // Fill function list elements
  nv = 0;

  Vec_loop (Metric*, mlist->get_items (), index, mitem)
  {
    if (!mitem->is_visible () && !mitem->is_tvisible () &&
	!mitem->is_pvisible ())
      continue;

    // Fill values
    switch (mitem->get_vtype ())
      {
      case VT_LABEL:
	{
	  Vector<char*> *jobjects = new Vector<char*>(nitems);
	  char *buf = NULL;
	  size_t bufsz = 0;
	  int lspace = 0;
	  if (type == DSP_SOURCE || type == DSP_DISASM || type == DSP_SOURCE_V2
	      || type == DSP_DISASM_V2)
	    {
	      // if this is source or disassembly, where we'll insert
	      //	a preface into the output line, figure out how wide
	      //	it needs to be
	      // first, scan all the lines, to get the maximum line number
	      bufsz = 1024;
	      buf = (char *) malloc (bufsz);
	      int max_lineno = 0;
	      int hidx;
	      Hist_data::HistItem *hitem;
	      Vec_loop (Hist_data::HistItem*, data, hidx, hitem)
	      {
		if (!hitem->obj)
		  continue;
		if (hitem->obj->get_type () == Histable::LINE &&
		    ((DbeLine*) hitem->obj)->lineno > max_lineno)
		  max_lineno = ((DbeLine*) hitem->obj)->lineno;
		else if (hitem->obj->get_type () == Histable::INSTR
			 && ((DbeInstr*) hitem->obj)->lineno > max_lineno)
		  max_lineno = ((DbeInstr*) hitem->obj)->lineno;
	      }

	      // we have the maximum integer over all linenumbers in the file
	      // 	figure out how many digits are needed
	      lspace = snprintf (buf, bufsz, NTXT ("%d"), max_lineno);
	    }
	  for (index2 = 0; index2 < nitems; index2++)
	    {
	      item = data->fetch (index2);
	      if (type == DSP_DLAYOUT)
		cell = dbe_strdup (((DataObject*) (item->obj))->get_offset_name ());
	      else if (type == DSP_SOURCE || type == DSP_DISASM || type == DSP_SOURCE_V2 || type == DSP_DISASM_V2)
		{
		  // This code is duplicated in output.cc, yet it's
		  // intended for presentation purpose and thus is
		  // potentially different for er_print and analyzer.
		  switch (item->type)
		    {
		    case Module::AT_SRC_ONLY:
		    case Module::AT_SRC:
		      if (item->obj == NULL)
			snprintf (buf, bufsz, NTXT (" %*c. "), lspace, ' ');
		      else
			snprintf (buf, bufsz, NTXT (" %*d. "), lspace, ((DbeLine*) item->obj)->lineno);
		      break;
		    case Module::AT_FUNC:
		    case Module::AT_QUOTE:
		      snprintf (buf, bufsz, NTXT ("%*c"), lspace + 3, ' ');
		      break;
		    case Module::AT_DIS:
		    case Module::AT_DIS_ONLY:
		      if (item->obj == NULL || ((DbeInstr*) item->obj)->lineno == -1)
			snprintf (buf, bufsz, NTXT ("%*c[%*s] "), lspace + 3, ' ', lspace, NTXT ("?"));
		      else
			snprintf (buf, bufsz, NTXT ("%*c[%*d] "), lspace + 3, ' ', lspace,
				  ((DbeInstr*) item->obj)->lineno);
		      break;
		    case Module::AT_COM:
		    case Module::AT_EMPTY:
		      *buf = (char) 0;
		      break;
		    }
		  // get the line's text
		  char *s = item->value[index].l;
		  if (s != NULL)
		    {
		      // copy the string expanding all tabulations
		      // (JTable doesn't render them)
		      char *d = buf + strlen (buf);
		      char c;
		      size_t column = 0;
		      do
			{
			  c = *s++;
			  if (c == '\t')
			    {
			      do
				{
				  *d++ = ' ';
				  column++;
				}
			      while (column & 07);
			    }
			  else
			    {
			      *d++ = c;
			      column++;
			    }
			  if (column + 32 > bufsz)
			    {
			      // Reallocate the buffer
			      size_t curlen = d - buf;
			      bufsz += 1024;
			      char *buf_new = (char *) malloc (bufsz);
			      strncpy (buf_new, buf, curlen);
			      buf_new[curlen] = '\0';
			      free (buf);
			      buf = buf_new;
			      d = buf + curlen;
			    }
			}
		      while (c != (char) 0);
		    }
		  cell = dbe_strdup (buf);
		  free (item->value[index].l);
		  item->value[index].l = NULL; //YXXX missing from dbeGetFuncListV2
		}
	      else
		{
		  // omazur: why don't we have it as metric value
		  Histable::NameFormat nfmt = dbev->get_name_format ();
		  cell = dbe_strdup (item->obj->get_name (nfmt));
		}
	      jobjects->store (index2, cell);
	    }
	  if (type == DSP_SOURCE || type == DSP_DISASM || type == DSP_SOURCE_V2
	      || type == DSP_DISASM_V2)
	    free (buf);
	  table->store (nv++, jobjects);
	  break;
	}
      default:
	table->store (nv++, dbeGetTableDataOneColumn (data, index));
	break;
      }
  }
  return table;
}

Vector<Obj> *
dbeGetComparableObjsV2 (int /* dbevindex */, Obj sel_obj, int type)
{
  long grsize = dbeSession->expGroups->size ();
  Vector<Obj> *res = new Vector<Obj> (grsize + 1);
  for (long j = 0; j < grsize; j++)
    res->append ((Obj) NULL);
  res->append (sel_obj);
  Histable *obj = (Histable *) sel_obj;
  if (obj == NULL)
    return res;
  Function *func = (Function *) obj->convertto (Histable::FUNCTION);
  if (func == NULL)
    return res;
  Vector<Histable *> *cmpObjs = func->get_comparable_objs ();
  if (cmpObjs == NULL || cmpObjs->size () != grsize)
    return res;

  Histable::Type conv_type = (type == DSP_SOURCE || type == DSP_SOURCE_V2) ?
	  Histable::LINE : Histable::INSTR;
  switch (obj->get_type ())
    {
    case Histable::FUNCTION:
      for (long j = 0; j < grsize; j++)
	res->store (j, (Obj) cmpObjs->get (j));
      return res;
    case Histable::INSTR:
    case Histable::LINE:
      {
	SourceFile *srcContext = (SourceFile *) obj->convertto (Histable::SOURCEFILE);
	char *bname = get_basename (srcContext->get_name ());
	for (long j = 0; j < grsize; j++)
	  {
	    Function *func1 = (Function *) cmpObjs->get (j);
	    if (func == func1)
	      {
		if (conv_type == Histable::LINE)
		  res->store (j, (Obj) obj);
		else
		  res->store (j, (Obj) obj->convertto (conv_type, srcContext));
		continue;
	      }
	    if (func1 == NULL)
	      continue;
	    Vector<SourceFile*> *sources = func1->get_sources ();
	    SourceFile *sf = NULL;
	    for (long j1 = 0, sz1 = sources ? sources->size () : 0; j1 < sz1; j1++)
	      {
		SourceFile *sf1 = sources->get (j1);
		if (sf1 == srcContext)
		  { // the same file
		    sf = srcContext;
		    break;
		  }
		else if (sf == NULL)
		  {
		    char *bname1 = get_basename (sf1->get_name ());
		    if (dbe_strcmp (bname, bname1) == 0)
		      sf = sf1;
		  }
	      }
	    res->store (j, (Obj) func1->convertto (conv_type, srcContext));
	  }
	break;
      }
    default:
      break;
    }
  return res;
}

// Get Table of Function List data
Vector<void *> *
dbeGetFuncListV2 (int dbevindex, int mtype, Obj sel_obj, int type, int subtype)
{
  Metric *mitem;
  int nitems, nvisible;
  int index, index2, nv;
  char *cell;
  Hist_data::HistItem *item;
  DbeView *dbev = dbeSession->getView (dbevindex);
  dbev->error_msg = dbev->warning_msg = NULL;
  MetricList *mlist = dbev->get_metric_list ((MetricType) (mtype & MTYPE_MASK),
					     (mtype & COMPARE_BIT) != 0,
					     mtype >> GROUP_ID_SHIFT);
  Histable *selObj = (Histable *) sel_obj;
  int old_compare_mode = dbev->get_compare_mode ();
  if ((mtype & COMPARE_BIT) != 0)
    dbev->reset_compare_mode (CMP_DISABLE);
  Hist_data *data = dbev->get_data (mlist, selObj, type, subtype);
  dbev->reset_compare_mode (old_compare_mode);
  if (data == NULL || data->get_status () != Hist_data::SUCCESS)
    return NULL;
  nitems = data->size ();
  nvisible = mlist->get_items ()->size ();

  // Initialize Java String array
  Vector<void*> *table = new Vector<void*>(nvisible + 3);
  // Mark Hi-value metric items for annotated src/dis/layout
  if (type == DSP_SOURCE || type == DSP_DISASM || type == DSP_DLAYOUT
      || type == DSP_SOURCE_V2 || type == DSP_DISASM_V2)
    {
      Vector<int> *types = new Vector<int>(nitems);
      Vector<Obj> *ids = new Vector<Obj > (nitems);
      if (dbev->marks->size () > 0)
	index = dbev->marks->fetch (0);
      else
	index = -1;
      int mindex = 0;
      for (int i = 0; i < nitems; i++)
	{
	  item = data->fetch (i);
	  ids->store (i, (Obj) item->obj);
	  if (i == index)
	    {
	      types->store (i, -item->type);
	      if (++mindex < dbev->marks->size ())
		index = dbev->marks->fetch (mindex);
	      else
		index = -1;
	    }
	  else
	    types->store (i, item->type);
	}
      table->store (nvisible, types);
      table->store (nvisible + 1, ids);
    }
  else
    {
      table->store (nvisible, NULL);
      table->store (nvisible + 1, NULL);
    }

  // Fill function list elements
  nv = 0;
  Vec_loop (Metric*, mlist->get_items (), index, mitem)
  {
    if (!mitem->is_visible () && !mitem->is_tvisible () &&
	!mitem->is_pvisible ())
      continue;

    // Fill values
    switch (mitem->get_vtype ())
      {
      default:
	table->store (nv++, dbeGetTableDataOneColumn (data, index));
	break;
      case VT_LABEL:
	Vector<char*> *jobjects = new Vector<char*>(nitems);
	char *buf = NULL;
	size_t bufsz = 0;
	int lspace = 0;
	if (type == DSP_SOURCE || type == DSP_DISASM || type == DSP_SOURCE_V2
	    || type == DSP_DISASM_V2)
	  {
	    // if this is source or disassembly, where we'll insert
	    //	a preface into the output line, figure out how wide
	    //	it needs to be
	    // first, scan all the lines, to get the maximum line number
	    bufsz = 1024;
	    buf = (char *) malloc (bufsz);
	    int max_lineno = 0;
	    int hidx;
	    Hist_data::HistItem *hitem;
	    Vec_loop (Hist_data::HistItem*, data, hidx, hitem)
	    {
	      if (!hitem->obj)
		continue;
	      if (hitem->obj->get_type () == Histable::LINE &&
		  ((DbeLine*) hitem->obj)->lineno > max_lineno)
		max_lineno = ((DbeLine*) hitem->obj)->lineno;
	      else if (hitem->obj->get_type () == Histable::INSTR
		       && ((DbeInstr*) hitem->obj)->lineno > max_lineno)
		max_lineno = ((DbeInstr*) hitem->obj)->lineno;
	    }

	    // we have the maximum integer over all linenumbers in the file
	    // 	figure out how many digits are needed
	    lspace = snprintf (buf, bufsz, NTXT ("%d"), max_lineno);
	  }

	for (index2 = 0; index2 < nitems; index2++)
	  {
	    item = data->fetch (index2);
	    if (type == DSP_DLAYOUT)
	      cell = dbe_strdup (((DataObject*) (item->obj))->get_offset_name ());
	    else if (type == DSP_SOURCE || type == DSP_DISASM || type == DSP_SOURCE_V2 || type == DSP_DISASM_V2)
	      {
		// This code is duplicated in output.cc, yet it's
		// intended for presentation purpose and thus is
		// potentially different for er_print and analyzer.
		switch (item->type)
		  {
		  case Module::AT_SRC_ONLY:
		  case Module::AT_SRC:
		    if (item->obj == NULL)
		      snprintf (buf, bufsz, NTXT (" %*c. "), lspace, ' ');
		    else
		      snprintf (buf, bufsz, NTXT (" %*d. "), lspace,
				((DbeLine*) item->obj)->lineno);
		    break;
		  case Module::AT_FUNC:
		  case Module::AT_QUOTE:
		    snprintf (buf, bufsz, NTXT ("%*c"), lspace + 3, ' ');
		    break;
		  case Module::AT_DIS:
		  case Module::AT_DIS_ONLY:
		    if (item->obj == NULL || ((DbeInstr*) item->obj)->lineno == -1)
		      snprintf (buf, bufsz, NTXT ("%*c[%*s] "), lspace + 3, ' ',
				lspace, NTXT ("?"));
		    else
		      snprintf (buf, bufsz, NTXT ("%*c[%*d] "), lspace + 3, ' ',
				lspace,
				((DbeInstr*) item->obj)->lineno);
		    break;
		  case Module::AT_COM:
		  case Module::AT_EMPTY:
		    *buf = (char) 0;
		    break;
		  }
		// get the line's text
		char *s = item->value[index].l;
		if (s != NULL)
		  {
		    // copy the string expanding all tabulations
		    // (JTable doesn't render them)
		    char *d = buf + strlen (buf);
		    char c;
		    size_t column = 0;
		    do
		      {
			c = *s++;
			if (c == '\t')
			  {
			    do
			      {
				*d++ = ' ';
				column++;
			      }
			    while (column & 07);
			  }
			else
			  {
			    *d++ = c;
			    column++;
			  }
			if (column + 32 > bufsz)
			  {
			    // Reallocate the buffer
			    size_t curlen = d - buf;
			    bufsz += 1024;
			    char *buf_new = (char *) malloc (bufsz);
			    strncpy (buf_new, buf, curlen);
			    buf_new[curlen] = '\0';
			    free (buf);
			    buf = buf_new;
			    d = buf + curlen;
			  }
		      }
		    while (c != (char) 0);
		  }
		cell = dbe_strdup (buf);
	      }
	    else
	      {
		Histable::NameFormat nfmt = dbev->get_name_format ();
		cell = dbe_strdup (item->obj->get_name (nfmt));
	      }
	    jobjects->store (index2, cell);
	  }

	if (type == DSP_SOURCE || type == DSP_DISASM || type == DSP_SOURCE_V2
	    || type == DSP_DISASM_V2)
	  free (buf);
	table->store (nv++, jobjects);
	break;
      }
  }
  table->append (dbeGetMetricList (mlist));
  return table;
} // dbeGetFuncListV2

//
// Get Table DataV2
//
Vector<void*> *
dbeGetTableDataV2 (int dbevindex, char *mlistStr, char *modeStr, char *typeStr,
		   char *subtypeStr, Vector<uint64_t> *ids)
{
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();

  // Process metric list specification
  if (mlistStr == NULL)
    return NULL;
  bool met_call = false;
  MetricList *mlist = NULL;
  if (streq (mlistStr, NTXT ("MET_NORMAL")))
    mlist = dbev->get_metric_list (MET_NORMAL);
  else if (streq (mlistStr, NTXT ("MET_CALL")))
    {
      met_call = true;
      mlist = dbev->get_metric_list (MET_CALL);
    }
  else if (streq (mlistStr, NTXT ("MET_CALL_AGR")))
    mlist = dbev->get_metric_list (MET_CALL_AGR);
  else if (streq (mlistStr, NTXT ("MET_DATA")))
    mlist = dbev->get_metric_list (MET_DATA);
  else if (streq (mlistStr, NTXT ("MET_INDX")))
    mlist = dbev->get_metric_list (MET_INDX);
  else if (streq (mlistStr, NTXT ("MET_IO")))
    mlist = dbev->get_metric_list (MET_IO);
  else if (streq (mlistStr, NTXT ("MET_HEAP")))
    mlist = dbev->get_metric_list (MET_HEAP);
  else
    return NULL;

  // Process mode specification
  if (modeStr == NULL)
    return NULL;
  Hist_data::Mode mode = (Hist_data::Mode)0;
  if (streq (modeStr, NTXT ("CALLERS")))
    mode = Hist_data::CALLERS;
  else if (streq (modeStr, NTXT ("CALLEES")))
    mode = Hist_data::CALLEES;
  else if (streq (modeStr, NTXT ("SELF")))
    mode = Hist_data::SELF;
  else if (streq (modeStr, NTXT ("ALL")))
    mode = Hist_data::ALL;
  else
    return NULL;

  // Process type specification
  if (typeStr == NULL)
    return NULL;
  Histable::Type type = Histable::OTHER;
  if (streq (typeStr, NTXT ("FUNCTION")))
    type = Histable::FUNCTION;
  else if (streq (typeStr, NTXT ("INDEXOBJ")))
    type = Histable::INDEXOBJ;
  else if (streq (typeStr, NTXT ("IOACTFILE")))
    type = Histable::IOACTFILE;
  else if (streq (typeStr, NTXT ("IOACTVFD")))
    type = Histable::IOACTVFD;
  else if (streq (typeStr, NTXT ("IOCALLSTACK")))
    type = Histable::IOCALLSTACK;
  else if (streq (typeStr, NTXT ("HEAPCALLSTACK")))
    type = Histable::HEAPCALLSTACK;
  else if (streq (typeStr, NTXT ("LINE")))
    type = Histable::LINE;
  else if (streq (typeStr, NTXT ("INSTR")))
    type = Histable::INSTR;
  else
    // XXX Accepting objects other than above may require a different
    // implementation of the id -> Histable mapping below
    return NULL;

  // Process subtype specification
  int subtype = 0;
  if (subtypeStr != NULL)
    subtype = atoi (subtypeStr);
  Vector<Histable*> *hobjs = NULL;
  if (ids != NULL)
    {
      hobjs = new Vector<Histable*>();
      for (int i = 0; i < ids->size (); ++i)
	{
	  Histable::Type obj_type = type;
	  if ((obj_type == Histable::LINE || obj_type == Histable::INSTR)
	      && subtype == 0)
	    obj_type = Histable::FUNCTION;
	  Histable *hobj = dbeSession->findObjectById (obj_type, subtype, ids->fetch (i));
	  if ((obj_type == Histable::LINE || obj_type == Histable::INSTR)
	      && subtype == 0 && hobj == NULL)
	    return NULL;
	  hobjs->append (hobj);
	}
    }

  PathTree::PtreeComputeOption flag = PathTree::COMPUTEOPT_NONE;
  if (dbev->isOmpDisMode () && type == Histable::FUNCTION
      && mode == Hist_data::CALLEES && met_call)
    flag = PathTree::COMPUTEOPT_OMP_CALLEE;

  Hist_data *data = dbev->get_hist_data (mlist, type, subtype, mode, hobjs, NULL, NULL, flag);
  return dbeGetTableDataV2Data (dbev, data);
}

static Vector<void*> *
dbeGetTableDataV2Data (DbeView * /*dbev*/, Hist_data *data)
{
  if (data == NULL || data->get_status () != Hist_data::SUCCESS)
    return NULL;
  MetricList *mlist;
  mlist = data->get_metric_list ();
  int nitems = data->size ();

  // Initialize Java String array
  Vector<void*> *table = new Vector<void*>(mlist->size () + 1);

  // Fill function list elements
  for (long i = 0, sz = mlist->size (); i < sz; i++)
    {
      Metric *mitem = mlist->get (i);
      if (!mitem->is_visible () && !mitem->is_tvisible () &&
	  !mitem->is_pvisible ())
	continue;
      table->append (dbeGetTableDataOneColumn (data, i));
    }

  // Add an array of Histable IDs
  Vector<uint64_t> *idList = new Vector<uint64_t>(nitems);
  for (int i = 0; i < nitems; ++i)
    {
      Hist_data::HistItem *item = data->fetch (i);
      if (item->obj->get_type () == Histable::LINE
	  || item->obj->get_type () == Histable::INSTR)
	idList->store (i, (uint64_t) (item->obj));
      else
	idList->store (i, item->obj->id);
    }
  table->append (idList);
  return table;
} // dbeGetTableData

//YXXX try to use the following to consolidate similar cut/paste code

static Vector<void*> *
dbeGetTableDataOneColumn (Hist_data *data, int met_ind)
{
  // Allocates a vector and fills it with metric values for one column
  TValue res;
  Metric *m = data->get_metric_list ()->get (met_ind);
  if ((m->get_visbits () & VAL_RATIO) != 0)
    {
      Vector<double> *col = new Vector<double>(data->size ());
      for (long row = 0, sz_row = data->size (); row < sz_row; row++)
	{
	  TValue *v = data->get_value (&res, met_ind, row);
	  double d = (v->tag != VT_LABEL) ? v->to_double () : 100.; // NaN
	  col->append (d);
	}
      return (Vector<void*> *) col;
    }

  switch (m->get_vtype ())
    {
    case VT_DOUBLE:
      {
	Vector<double> *col = new Vector<double>(data->size ());
	for (long row = 0, sz_row = data->size (); row < sz_row; row++)
	  {
	    TValue *v = data->get_value (&res, met_ind, row);
	    col->append (v->d);
	  }
	return (Vector<void*> *) col;
      }
    case VT_INT:
      {
	Vector<int> *col = new Vector<int>(data->size ());
	for (long row = 0, sz_row = data->size (); row < sz_row; row++)
	  {
	    TValue *v = data->get_value (&res, met_ind, row);
	    col->append (v->i);
	  }
	return (Vector<void*> *) col;
      }
    case VT_ULLONG:
    case VT_LLONG:
      {
	Vector<long long> *col = new Vector<long long>(data->size ());
	for (long row = 0, sz_row = data->size (); row < sz_row; row++)
	  {
	    TValue *v = data->get_value (&res, met_ind, row);
	    col->append (v->ll);
	  }
	return (Vector<void*> *) col;
      }
    case VT_ADDRESS:
      {
	Vector<long long> *col = new Vector<long long>(data->size ());
	for (long row = 0, sz_row = data->size (); row < sz_row; row++)
	  {
	    TValue *v = data->get_value (&res, met_ind, row);
	    // set the highest bit to mark this jlong as
	    // a VT_ADDRESS (rather than a regular VT_LLONG)
	    col->append (v->ll | 0x8000000000000000ULL);
	  }
	return (Vector<void*> *) col;
      }
    case VT_LABEL:
      {
	Vector<char *> *col = new Vector<char *>(data->size ());
	for (long row = 0, sz_row = data->size (); row < sz_row; row++)
	  {
	    TValue *v = data->get_value (&res, met_ind, row);
	    col->append (dbe_strdup (v->l));
	  }
	return (Vector<void*> *) col;
      }
    default:
      return NULL;
    }
}

static Vector<void*> *
dbeGetTableDataOneColumn (DbeView *dbev, Vector<Hist_data::HistItem*> *data,
			  ValueTag vtype, int metricColumnNumber)
// Allocates a vector and fills it with metric values for one column
{
  Vector<void*> *column_data = NULL;
  int nitems = data->size (); // number of rows
  int index = metricColumnNumber;
  switch (vtype)
    {
    case VT_DOUBLE:
      {
	Vector<double> *jd_list = new Vector<double>(nitems);
	for (int index2 = 0; index2 < nitems; index2++)
	  {
	    Hist_data::HistItem *item = data->fetch (index2);
	    jd_list->store (index2, item->value[index].d);
	  }
	column_data = (Vector<void*> *)jd_list;
	break;
      }
    case VT_INT:
      {
	Vector<int> *ji_list = new Vector<int>(nitems);
	for (int index2 = 0; index2 < nitems; index2++)
	  {
	    Hist_data::HistItem *item = data->fetch (index2);
	    ji_list->store (index2, item->value[index].i);
	  }
	column_data = (Vector<void*> *)ji_list;
	break;
      }
    case VT_ULLONG:
    case VT_LLONG:
      {
	Vector<long long> *jl_list = new Vector<long long>(nitems);
	for (int index2 = 0; index2 < nitems; index2++)
	  {
	    Hist_data::HistItem *item = data->fetch (index2);
	    jl_list->store (index2, item->value[index].ll);
	  }
	column_data = (Vector<void*> *)jl_list;
	break;
      }
    case VT_ADDRESS:
      {
	Vector<long long> *jl_list = new Vector<long long>(nitems);
	for (int index2 = 0; index2 < nitems; index2++)
	  {
	    Hist_data::HistItem *item = data->fetch (index2);

	    // set the highest bit to mark this jlong as
	    // a VT_ADDRESS (rather than a regular VT_LLONG)
	    uint64_t addr = item->value[index].ll;
	    addr |= 0x8000000000000000ULL;
	    jl_list->store (index2, addr);
	  }
	column_data = (Vector<void*> *)jl_list;
	break;
      }
    case VT_LABEL:
      {
	Vector<char*> *jobjects = new Vector<char*>(nitems);
	for (int index2 = 0; index2 < nitems; index2++)
	  {
	    Hist_data::HistItem *item = data->fetch (index2);

	    // omazur: why don't we have it as metric value
	    Histable::NameFormat nfmt = dbev->get_name_format ();
	    char *str = dbe_strdup (item->obj->get_name (nfmt));
	    jobjects->store (index2, str);
	  }
	column_data = (Vector<void*> *)jobjects;
	break;
      }
    default:
      abort ();
    }
  return column_data;
}

int
dbeGetCallTreeNumLevels (int dbevindex)
{
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  PathTree * ptree = dbev->get_path_tree ();
  if (ptree == NULL)
    return 0;
  return ptree->get_ftree_depth ();
}

Vector<void*>*
dbeGetCallTreeLevel (int dbevindex, char *mcmd, int level)
{
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  PathTree * ptree = dbev->get_path_tree ();
  if (ptree == NULL)
    return NULL;
  if (mcmd == NULL)
    return NULL;
  BaseMetric *bm = dbeSession->find_base_reg_metric (mcmd);
  if (bm == NULL)
    return NULL;
  return ptree->get_ftree_level (bm, level);
}

Vector<void*>*
dbeGetCallTreeLevels (int dbevindex, char *mcmd)
{
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  PathTree * ptree = dbev->get_path_tree ();
  if (ptree == NULL)
    return NULL;
  if (mcmd == NULL)
    return NULL;
  BaseMetric *bm = dbeSession->find_base_reg_metric (mcmd);
  if (bm == NULL)
    return NULL;

  int depth = ptree->get_ftree_depth ();
  Vector<void*> *results = new Vector<void*>(depth);
  for (int ii = 0; ii < depth; ii++)
    results->append (ptree->get_ftree_level (bm, ii));
  return results;
}

Vector<void*>*
dbeGetCallTreeLevelFuncs (int dbevindex, int start_level, int end_level)
{ // (0,-1) -> all levels
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  PathTree * ptree = dbev->get_path_tree ();
  if (ptree == NULL)
    return NULL;

  int depth = ptree->get_ftree_depth ();
  if (start_level < 0)
    start_level = 0;
  if (end_level < 0 || end_level >= depth)
    end_level = depth - 1;

  Histable::NameFormat nfmt = dbev->get_name_format (); //YXXX or fixed format?
  Vector<char*> *funcNames = new Vector<char*>();
  Vector<long long> *funcIds = new Vector<long long>();
  Vector<Obj> *funcObjs = new Vector<Obj>();

  if (start_level == 0 && end_level == depth - 1)
    return dbeGetCallTreeFuncs (dbevindex);
  else
    {
      for (int ii = start_level; ii <= end_level; ii++)
	{
	  Vector<void*> *info = ptree->get_ftree_level (NULL, ii); /*no metric*/
	  if (!info)
	    continue;
	  Vector<long long> *fids = (Vector<long long> *)info->get (2);
	  if (!fids)
	    continue;
	  int index;
	  long long fid;
	  Vec_loop (long long, fids, index, fid)
	  {
	    funcIds->append (fid);
	    Histable *obj = dbeSession->findObjectById (fid);
	    char * fname = obj ? dbe_strdup (obj->get_name (nfmt)) : NULL;
	    funcNames->append (fname);
	    funcObjs->append ((unsigned long) obj); // avoiding sign extension
	  }
	  destroy (info);
	}
    }
  Vector<void*> *results = new Vector<void*>(3);
  results->append (funcIds);
  results->append (funcNames);
  results->append (funcObjs);
  return results;
}

Vector<void*> *
dbeGetCallTreeFuncs (int dbevindex)
{ // does not require ptree->get_ftree_level() to be computed
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  PathTree * ptree = dbev->get_path_tree ();
  if (ptree == NULL)
    return 0;
  Vector<Function*>* funcs = ptree->get_funcs (); // Unique functions in tree
  if (funcs == NULL)
    return NULL;

  long sz = funcs->size ();
  Vector<void*> *results = new Vector<void*>(3);
  Vector<long long> *funcIds = new Vector<long long>(sz);
  Vector<char*> *funcNames = new Vector<char*>(sz);
  Vector<Obj> *funcObjs = new Vector<Obj>(sz);

  int index;
  Function * func;
  Histable::NameFormat nfmt = dbev->get_name_format (); //YXXX or fixed format?
  Vec_loop (Function *, funcs, index, func)
  {
    funcIds->append (func->id); // do we need IDs?
    char *fname = dbe_strdup (func->get_name (nfmt));
    funcNames->append (fname);
    funcObjs->append ((unsigned long) func); // avoiding sign extension
  }
  results->put (0, funcIds);
  results->put (1, funcNames);
  results->put (2, funcObjs);
  destroy (funcs);
  return results;
}

Vector<void*>*
dbeGetCallTreeChildren (int dbevindex, char *mcmd, Vector<int /*NodeIdx*/>*node_idxs)
{
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  if (node_idxs == NULL || node_idxs->size () == 0)
    return NULL;
  long sz = node_idxs->size ();
  PathTree * ptree = dbev->get_path_tree ();
  if (ptree == NULL)
    return NULL;
  if (mcmd == NULL)
    return NULL;
  BaseMetric *bm = dbeSession->find_base_reg_metric (mcmd);
  if (bm == NULL)
    return NULL;

  Vector<void*> *results = new Vector<void*>(sz);
  for (long ii = 0; ii < sz; ii++)
    {
      PathTree::NodeIdx nodeIdx = node_idxs->get (ii); // upcasted from int
      results->append (ptree->get_ftree_node_children (bm, nodeIdx));
    }
  return results;
}

Vector<int> *
dbeGetGroupIds (int /*dbevindex*/)
{
  Vector<ExpGroup*> *groups = dbeSession->expGroups;
  int sz = groups->size ();
  Vector<int> *grIds = new Vector<int>(sz);
  for (int i = 0; i < sz; i++)
    grIds->store (i, groups->fetch (i)->groupId);
  return grIds;
}

//
// Get label for name column
//
Vector<char*> *
dbeGetNames (int dbevindex, int type, Obj sel_obj)
{
  char *s0, *s1, *s2;
  bool need_strdup = true;
  switch (type)
    {
    case DSP_SOURCE_V2:
    case DSP_DISASM_V2:
    case DSP_SOURCE:
    case DSP_DISASM:
      {
	if (sel_obj)
	  {
	    Histable *selObj = (Histable*) sel_obj;
	    Function *func = (Function *) selObj->convertto (Histable::FUNCTION);
	    if (func)
	      {
		char *names[3] = {NULL, NULL, NULL};
		set_file_names (func, names);
		s0 = names[0];
		s1 = names[1];
		s2 = names[2];
		need_strdup = false;
		break;
	      }
	  }
	DbeView *dbev = dbeSession->getView (dbevindex);
	char **names = type == DSP_SOURCE || type == DSP_SOURCE_V2 ? dbev->names_src : dbev->names_dis;
	s0 = names[0];
	s1 = names[1];
	s2 = names[2];
	break;
      }
    case DSP_LINE:
      s0 = GTXT ("Lines");
      s1 = GTXT ("Function, line # in \"sourcefile\"");
      s2 = NTXT ("");
      break;
    case DSP_PC:
      s0 = GTXT ("PCs");
      s1 = GTXT ("Function + offset");
      s2 = NTXT ("");
      break;
    case DSP_DLAYOUT:
      s0 = GTXT ("Name");
      s1 = GTXT ("* +offset .element");
      s2 = NTXT ("");
      break;
    default:
      s0 = GTXT ("Name");
      s1 = s2 = NTXT ("");
      break;
    }
  if (need_strdup)
    {
      s0 = dbe_strdup (s0);
      s1 = dbe_strdup (s1);
      s2 = dbe_strdup (s2);
    }
  Vector<char*> *table = new Vector<char*>(3);
  table->store (0, s0);
  table->store (1, s1);
  table->store (2, s2);
  return table;
}

//
// Get Total/Maximum element of Function List
//
Vector<void*> *
dbeGetTotalMax (int dbevindex, int type, int subtype)
{
  Hist_data *data;
  int index;
  Hist_data::HistItem *total_item, *maximum_item;
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();

  switch (type)
    {
    case DSP_LINE:
      data = dbev->line_data;
      break;
    case DSP_PC:
      data = dbev->pc_data;
      break;
    case DSP_CALLER:
      data = dbev->callers;
      break;
    case DSP_SELF:
    case DSP_CALLEE:
      data = dbev->callees;
      break;
    case DSP_DLAYOUT:
      data = dbev->dlay_data;
      break;
    case DSP_DATAOBJ:
      data = dbev->dobj_data;
      break;
    case DSP_MEMOBJ:
      data = dbev->get_indxobj_data (subtype);
      break;
    case DSP_INDXOBJ:
      data = dbev->get_indxobj_data (subtype);
      break;
    case DSP_FUNCTION: // annotated src/dis use func total/max
    case DSP_SOURCE:
    case DSP_DISASM:
    case DSP_SOURCE_V2:
    case DSP_DISASM_V2:
      data = dbev->func_data;
      break;
    default:
      abort ();
    }
  if (data == NULL || data->get_status () != Hist_data::SUCCESS)
    return NULL;

  // Get list size
  // XXX -- the original list has all items, visible or not;
  // XXX -- the one from Hist_data has only visible items,
  // XXX --    and should be the only ones computed
  // XXX --    Analyzer got confused (yesterday), when we used the shorter list
  // XXX -- Why can we fetch total/max for metrics never
  // XXX --    computed without core dumping?
  MetricList *mlist2 = data->get_metric_list ();
  int size = mlist2->get_items ()->size ();

  // Initialize Java array
  Vector<void*> *total_max = new Vector<void*>(2);
  Vector<double> *total = new Vector<double>(size);
  Vector<double> *maximum = new Vector<double>(size);

  // Fill total/maximum element
  total_item = data->get_totals ();
  maximum_item = data->get_maximums ();

  for (index = 0; index < size; index++)
    {
      total->store (index, total_item->value[index].to_double ());
      maximum->store (index, maximum_item->value[index].to_double ());
    }
  total_max->store (0, total);
  total_max->store (1, maximum);
  return total_max;
}

//
// Get Table of Overview List
Vector<void*> *
dbeGetStatisOverviewList (int dbevindex)
{
  int size;
  Ovw_data **data;
  Ovw_data::Ovw_item labels, *totals;
  int nitems;
  int index, index2;

  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  dbev->error_msg = dbev->warning_msg = NULL;

  size = dbeSession->nexps ();
  totals = new Ovw_data::Ovw_item[size + 1];
  data = new Ovw_data*[size + 1];
  data[0] = new Ovw_data ();

  for (index = 1; index <= size; index++)
    {
      data[index] = dbev->get_ovw_data (index - 1);
      if (data[index] == NULL)
	{
	  Ovw_data::reset_item (&totals[index]); // set contents to zeros
	  continue;
	}
      data[0]->sum (data[index]);
      totals[index] = data[index]->get_totals (); //shallow copy!
    }
  totals[0] = data[0]->get_totals ();

  // Get table size
  labels = data[0]->get_labels ();
  nitems = labels.size + 4;

  // Initialize Java String array
  Vector<void*> *table = new Vector<void*>(size + 4);
  Vector<char*> *jobjects = new Vector<char*>(nitems);

  // Set the label
  jobjects->store (0, dbe_strdup (GTXT ("Start Time (sec.)")));
  jobjects->store (1, dbe_strdup (GTXT ("End Time (sec.)")));
  jobjects->store (2, dbe_strdup (GTXT ("Duration (sec.)")));
  jobjects->store (3, dbe_strdup (GTXT ("Total Thread Time (sec.)")));
  jobjects->store (4, dbe_strdup (GTXT ("Average number of Threads")));

  for (index2 = 5; index2 < nitems; index2++)
    jobjects->store (index2, dbe_strdup (labels.values[index2 - 4].l));
  table->store (0, jobjects);

  // Set the data
  for (index = 0; index <= size; index++)
    {
      Vector<double> *jd_list = new Vector<double>(nitems);
      jd_list->store (0, tstodouble (totals[index].start));
      jd_list->store (1, tstodouble (totals[index].end));
      jd_list->store (2, tstodouble (totals[index].duration));
      jd_list->store (3, tstodouble (totals[index].tlwp));
      jd_list->store (4, totals[index].nlwp);
      for (index2 = 5; index2 < nitems; index2++)
	jd_list->store (index2, tstodouble (totals[index].values[index2 - 4].t));
      table->store (index + 1, jd_list);
    }
  for (index = 0; index <= size; index++)
    delete data[index];
  delete[] data;
  delete[] totals;
  return table;
}

// Get Table of Statistics List
Vector<void*> *
dbeGetStatisList (int dbevindex)
{
  int size;
  Stats_data **data;
  int nitems;
  int index, index2;
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  dbev->error_msg = dbev->warning_msg = NULL;
  if ((size = dbeSession->nexps ()) == 0)
    return NULL;

  // Get statistics data
  data = (Stats_data **) malloc ((size + 1) * sizeof (Stats_data *));
  data[0] = new Stats_data ();
  for (index = 1; index <= size; index++)
    {
      data[index] = dbev->get_stats_data (index - 1);
      if (data[index] == NULL)
	continue;
      data[0]->sum (data[index]);
    }

  // Get table size
  nitems = data[0]->size ();

  // Initialize Java String array
  Vector<void*> *table = new Vector<void*>(size + 2);
  Vector<char*> *jobjects = new Vector<char*>(nitems);

  // Set the label
  for (index2 = 0; index2 < nitems; index2++)
    jobjects->store (index2, dbe_strdup (data[0]->fetch (index2).label));
  table->store (0, jobjects);

  // Set the data
  for (index = 0; index <= size; index++)
    {
      Vector<double> *jd_list = new Vector<double>(nitems);
      for (index2 = 0; index2 < nitems; index2++)
	{
	  double val = 0;
	  if (data[index])
	    val = data[index]->fetch (index2).value.to_double ();
	  jd_list->store (index2, val);
	}
      table->store (index + 1, jd_list);
    }
  if (data)
    {
      for (index = 0; index <= size; index++)
	delete data[index];
      free (data);
    }
  return table;
}


//
// Set summary list
//
static void
setSummary (Vector<Histable*> *objs, Vector<int> *saligns,
	    Vector<char> *mnemonic, Vector<char*> *jlabels, Vector<char*> *jvalues)
{
  char *sname = NULL, *oname = NULL, *lname = NULL, *alias = NULL,
	  *mangle = NULL, *address = NULL, *size = NULL,
	  *name_0 = NULL, *sname_0 = NULL, *oname_0 = NULL, *lname_0 = NULL,
	  *alias_0 = NULL, *mangle_0 = NULL;
  Function *func, *last_func = NULL;
  int one_func = 1;

  // Get the source/object/load-object files & aliases
  long long ll_size = 0;
  for (long i = 0; i < objs->size (); i++)
    {
      Histable *current_obj = objs->fetch (i);
      Histable::Type htype = current_obj->get_type ();
      if (htype == Histable::LOADOBJECT)
	lname = ((LoadObject *) current_obj)->dbeFile->get_location_info ();
      else if ((func = (Function*) current_obj->convertto (Histable::FUNCTION)) != NULL)
	{
	  if (one_func && last_func != NULL && last_func != func)
	    one_func = 0;
	  last_func = func;
	  sname = NULL;
	  DbeLine *dbeline = (DbeLine*) current_obj->convertto (Histable::LINE);
	  if (dbeline)
	    {
	      SourceFile *sf;
	      if (dbeline->lineno == 0 && dbeline->include != NULL)
		sf = dbeline->include;
	      else if (dbeline->sourceFile != NULL)
		sf = dbeline->sourceFile;
	      else
		sf = func->getDefSrc ();
	      if (sf)
		sname = sf->dbeFile->get_location_info ();
	    }
	  char *func_name = func->get_name ();
	  mangle = func->get_mangled_name ();
	  if (mangle && streq (func_name, mangle))
	    mangle = NULL;
	  Module *module = func->module;
	  if (module != NULL)
	    {
	      module->read_stabs ();
	      if (sname == NULL || strlen (sname) == 0)
		{
		  SourceFile *sf = module->getMainSrc ();
		  sname = sf->dbeFile->get_location_info ();
		}
	      DbeFile *df = module->dbeFile;
	      if (df == NULL || (df->filetype & DbeFile::F_JAVACLASS) == 0)
		df = module->loadobject->dbeFile;
	      lname = df->get_location_info ();
	      oname = lname;
	      if (module->dot_o_file)
		oname = module->dot_o_file->dbeFile->get_location_info ();
	    }

	  if (htype == Histable::INSTR && dbeSession->is_datamode_available ())
	    alias = ((DbeInstr*) current_obj)->get_descriptor ();
	}

      char *name = current_obj->get_name ();
      if (i == 0)
	{
	  name_0 = name;
	  lname_0 = lname;
	  sname_0 = sname;
	  oname_0 = oname;
	  mangle_0 = mangle;
	  alias_0 = alias;
	  if (objs->size () == 1)
	    {
	      uint64_t addr = current_obj->get_addr ();
	      address = dbe_sprintf (NTXT ("%lld:0x%08llX"),
				     (long long) ADDRESS_SEG (addr),
				     (long long) ADDRESS_OFF (addr));
	    }
	}
      else
	{
	  if (name_0 != name)
	    name_0 = NULL;
	  if (lname_0 != lname)
	    lname_0 = NULL;
	  if (sname_0 != sname)
	    sname_0 = NULL;
	  if (oname_0 != oname)
	    oname_0 = NULL;
	  if (mangle_0 != mangle)
	    mangle_0 = NULL;
	  if (alias_0 != alias)
	    alias_0 = NULL;
	}
      if (current_obj->get_size () == -1)
	{
	  if (size == NULL)
	    size = dbe_strdup (GTXT ("(Unknown)"));
	}
      else
	ll_size += current_obj->get_size ();
    }
  if (size == NULL)
    size = dbe_sprintf (NTXT ("%lld"), ll_size);
  if (name_0 == NULL)
    {
      if (objs->size () > 1)
	{
	  char *func_name = last_func == NULL ? NULL :
		  (one_func == 0 ? NULL : last_func->get_name ());
	  name_0 = dbe_sprintf (NTXT ("%s%s%s (%lld %s)"),
				func_name == NULL ? "" : func_name,
				func_name == NULL ? "" : ": ",
				GTXT ("Multiple Selection"),
				(long long) objs->size (),
				GTXT ("objects"));
	}
    }
  else
    name_0 = dbe_strdup (name_0);

  // Set the name area
  saligns->store (0, TEXT_LEFT);
  mnemonic->store (0, 'N');
  jlabels->store (0, dbe_strdup (GTXT ("Name")));
  jvalues->store (0, name_0);

  saligns->store (1, TEXT_LEFT);
  mnemonic->store (1, 'P');
  jlabels->store (1, dbe_strdup (GTXT ("PC Address")));
  jvalues->store (1, address);

  saligns->store (2, TEXT_LEFT);
  mnemonic->store (2, 'z');
  jlabels->store (2, dbe_strdup (GTXT ("Size")));
  jvalues->store (2, size);

  saligns->store (3, TEXT_RIGHT);
  mnemonic->store (3, 'r');
  jlabels->store (3, dbe_strdup (GTXT ("Source File")));
  jvalues->store (3, dbe_strdup (sname_0));

  saligns->store (4, TEXT_RIGHT);
  mnemonic->store (4, 'b');
  jlabels->store (4, dbe_strdup (GTXT ("Object File")));
  jvalues->store (4, dbe_strdup (oname_0));

  saligns->store (5, TEXT_LEFT);
  mnemonic->store (5, 'j');
  jlabels->store (5, dbe_strdup (GTXT ("Load Object")));
  jvalues->store (5, dbe_strdup (lname_0));

  saligns->store (6, TEXT_LEFT);
  mnemonic->store (6, 'm');
  jlabels->store (6, dbe_strdup (GTXT ("Mangled Name")));
  jvalues->store (6, dbe_strdup (mangle_0));

  saligns->store (7, TEXT_LEFT);
  mnemonic->store (7, 'A');
  jlabels->store (7, dbe_strdup (GTXT ("Aliases")));
  jvalues->store (7, dbe_strdup (alias_0));
}

// Set memory-object summary list
//
static void
setMemSummary (Vector<Histable*> *objs, Vector<int> *saligns,
	       Vector<char> *mnemonic, Vector<char*> *jlabels,
	       Vector<char*> *jvalues)
{
  saligns->store (0, TEXT_LEFT);
  mnemonic->store (0, 'M');
  jlabels->store (0, dbe_strdup (GTXT ("Memory Object")));
  if (objs->size () == 1)
    {
      Histable *current_obj = objs->fetch (0);
      jvalues->store (0, dbe_strdup (current_obj->get_name ()));
    }
  else
    {
      char *name = dbe_sprintf (NTXT ("%s (%lld %s)"),
				GTXT ("Multiple Selection"),
				(long long) objs->size (), GTXT ("objects"));
      jvalues->store (0, name);
    }
}

// Set index-object summary list
//
static void
setIndxSummary (Vector<Histable*> *objs, Vector<int> *saligns,
		Vector<char> *mnemonic, Vector<char*> *jlabels,
		Vector<char*> *jvalues)
{
  saligns->store (0, TEXT_LEFT);
  mnemonic->store (0, 'I');
  jlabels->store (0, dbe_strdup (GTXT ("Index Object")));

  if (objs->size () == 1)
    {
      Histable *current_obj = objs->fetch (0);
      jvalues->store (0, dbe_strdup (current_obj->get_name ()));
    }
  else
    {
      char *name = dbe_sprintf (NTXT ("%s (%lld %s)"), GTXT ("Multiple Selection"),
				(long long) objs->size (), GTXT ("objects"));
      jvalues->store (0, name);
    }
}

// Set I/O activity summary list
//
static void
setIOActivitySummary (Vector<Histable*> *objs, Vector<int> *saligns,
		      Vector<char> *mnemonic, Vector<char*> *jlabels,
		      Vector<char*> *jvalues)
{
  saligns->store (0, TEXT_LEFT);
  mnemonic->store (0, 'O');
  jlabels->store (0, dbe_strdup (GTXT ("I/O Activity")));
  if (objs->size () == 1)
    {
      Histable *current_obj = objs->fetch (0);
      jvalues->store (0, dbe_strdup (current_obj->get_name ()));
    }
  else
    {
      char *name = dbe_sprintf (NTXT ("%s (%lld %s)"), GTXT ("Multiple Selection"),
				(long long) objs->size (), GTXT ("objects"));
      jvalues->store (0, name);
    }
}

// Set heap activity summary list
//
static void
setHeapActivitySummary (Vector<Histable*> *objs, Vector<int> *saligns,
			Vector<char> *mnemonic, Vector<char*> *jlabels,
			Vector<char*> *jvalues)
{
  saligns->store (0, TEXT_LEFT);
  mnemonic->store (0, 'O');
  jlabels->store (0, dbe_strdup (GTXT ("Heap Activity")));

  if (objs->size () == 1)
    {
      Histable *current_obj = objs->fetch (0);
      jvalues->store (0, dbe_strdup (current_obj->get_name ()));
    }
  else
    {
      char *name = dbe_sprintf (NTXT ("%s (%lld %s)"), GTXT ("Multiple Selection"),
				(long long) objs->size (), GTXT ("objects"));
      jvalues->store (0, name);
    }
}

//
// Set data-object summary list
//
static void
setDataSummary (Vector<Histable*> *objs, Vector<int> *saligns,
		Vector<char> *mnemonic, Vector<char*> *jlabels,
		Vector<char*> *jvalues)
{
  char *name, *type, *member, *elist;
  DataObject *dobj;
  Vector<DataObject *> *delem;
  Histable *scope;
  int index;
  char *size, *offset, *elements, *scopename;

  // Get the data object elements
  member = elist = type = size = offset = elements = scopename = NULL;

  if (objs->size () == 1)
    {
      Histable *current_obj = objs->fetch (0);
      name = dbe_strdup (current_obj->get_name ());
      dobj = (DataObject *) current_obj;
      type = dobj->get_typename ();
      scope = dobj->get_scope ();
      delem = dbeSession->get_dobj_elements (dobj);
      if (type == NULL)
	type = GTXT ("(Synthetic)");
      if (!scope)
	scopename = dbe_strdup (GTXT ("(Global)"));
      else
	{
	  switch (scope->get_type ())
	    {
	    case Histable::FUNCTION:
	      scopename = dbe_sprintf (NTXT ("%s(%s)"),
				       ((Function*) scope)->module->get_name (),
				       scope->get_name ());
	      break;
	    case Histable::LOADOBJECT:
	    case Histable::MODULE:
	    default:
	      scopename = dbe_strdup (scope->get_name ());
	      break;
	    }
	}

      if (dobj->get_offset () != -1)
	{
	  if (dobj->get_parent ())
	    member = dbe_strdup (dobj->get_parent ()->get_name ());
	  offset = dbe_sprintf (NTXT ("%lld"), (long long) dobj->get_offset ());
	}
      size = dbe_sprintf ("%lld", (long long) dobj->get_size ());

      if (delem->size () > 0)
	{
	  elements = dbe_sprintf (NTXT ("%lld"), (long long) delem->size ());
	  StringBuilder sb_tmp, sb;
	  sb.append (GTXT ("Offset Size  Name\n"));
	  for (index = 0; index < delem->size (); index++)
	    {
	      DataObject *ditem = delem->fetch (index);
	      sb_tmp.sprintf (NTXT ("%6lld %5lld  %s\n"),
			      (long long) ditem->get_offset (),
			      (long long) ditem->get_size (), ditem->get_name ());
	      sb.append (&sb_tmp);
	    }
	  if (sb.charAt (sb.length () - 1) == '\n')
	    sb.setLength (sb.length () - 1);
	  elist = sb.toString ();
	}
    }
  else
    name = dbe_sprintf (NTXT ("%s (%lld %s)"), GTXT ("Multiple Selection"),
			(long long) objs->size (), GTXT ("objects"));

  saligns->store (0, TEXT_LEFT);
  mnemonic->store (0, 'D');
  jlabels->store (0, dbe_strdup (GTXT ("Data Object")));
  jvalues->store (0, name);

  saligns->store (1, TEXT_LEFT);
  mnemonic->store (1, 'S');
  jlabels->store (1, dbe_strdup (GTXT ("Scope")));
  jvalues->store (1, scopename);

  saligns->store (2, TEXT_LEFT);
  mnemonic->store (2, 'T');
  jlabels->store (2, dbe_strdup (GTXT ("Type")));
  jvalues->store (2, dbe_strdup (type));

  saligns->store (3, TEXT_LEFT);
  mnemonic->store (3, 'M');
  jlabels->store (3, dbe_strdup (GTXT ("Member of")));
  jvalues->store (3, member);

  saligns->store (4, TEXT_LEFT);
  mnemonic->store (4, 'O');
  jlabels->store (4, dbe_strdup (GTXT ("Offset")));
  jvalues->store (4, offset);

  saligns->store (5, TEXT_LEFT);
  mnemonic->store (5, 'z');
  jlabels->store (5, dbe_strdup (GTXT ("Size")));
  jvalues->store (5, size);

  saligns->store (6, TEXT_LEFT);
  mnemonic->store (6, 'E');
  jlabels->store (6, dbe_strdup (GTXT ("Elements")));
  jvalues->store (6, elements);

  saligns->store (7, TEXT_LEFT);
  mnemonic->store (7, 'L');
  jlabels->store (7, dbe_strdup (GTXT ("List")));
  jvalues->store (7, elist);
}

#define SUMMARY_NAME 8
#define DSUMMARY_NAME 8
#define LSUMMARY_NAME   7
#define IMSUMMARY_NAME   1

Vector<void*> *
dbeGetSummaryV2 (int dbevindex, Vector<Obj> *sel_objs, int type, int subtype)
{
  if (sel_objs == NULL || sel_objs->size () == 0)
    return NULL;
  DbeView *dbev = dbeSession->getView (dbevindex);
  Vector<Histable*>*objs = new Vector<Histable*>(sel_objs->size ());
  for (int i = 0; i < sel_objs->size (); i++)
    {
      Histable *obj = (Histable *) sel_objs->fetch (i);
      if (obj == NULL)
	continue;
      char *nm = obj->get_name ();
      if (streq (nm, NTXT ("<Total>")))
	{
	  // Special case for 'Total'.
	  // Multi selection which includes 'Total' is only 'Total'
	  objs->reset ();
	  objs->append (obj);
	  break;
	}
      objs->append (obj);
    }
  if (objs->size () == 0)
    return NULL;

  // Set name area
  int nname = SUMMARY_NAME;
  Vector<int> *saligns = new Vector<int>(nname);
  Vector<char>*mnemonic = new Vector<char>(nname);
  Vector<char*> *jlabels = new Vector<char*>(nname);
  Vector<char*> *jvalues = new Vector<char*>(nname);
  Vector<void*> *name_objs = new Vector<void*>(4);
  name_objs->store (0, saligns);
  name_objs->store (1, mnemonic);
  name_objs->store (2, jlabels);
  name_objs->store (3, jvalues);
  setSummary (objs, saligns, mnemonic, jlabels, jvalues);

  MetricList *prop_mlist = new MetricList (dbev->get_metric_ref (MET_NORMAL));
  if (prop_mlist && dbev->comparingExperiments ())
    prop_mlist = dbev->get_compare_mlist (prop_mlist, 0);

  int nitems = prop_mlist->get_items ()->size ();

  // Set the metrics area
  jlabels = new Vector<char*>(nitems);
  Vector<double> *clock_list = new Vector<double>(nitems);
  Vector<double> *excl_list = new Vector<double>(nitems);
  Vector<double> *ep_list = new Vector<double>(nitems);
  Vector<double> *incl_list = new Vector<double>(nitems);
  Vector<double> *ip_list = new Vector<double>(nitems);
  Vector<int> *vtype = new Vector<int>(nitems);

  // Initialize Java String array
  Vector<void*> *metric_objs = new Vector<void*>(8);
  metric_objs->store (0, jlabels);
  metric_objs->store (1, clock_list);
  metric_objs->store (2, excl_list);
  metric_objs->store (3, ep_list);
  metric_objs->store (4, incl_list);
  metric_objs->store (5, ip_list);
  metric_objs->store (6, vtype);

  int last_init = -1;
  for (int i = 0; i < objs->size (); i++)
    {
      Histable *obj = objs->fetch (i);
      // Get the data to be displayed
      Hist_data *data = dbev->get_hist_data (prop_mlist, obj->get_type (), subtype,
					     Hist_data::SELF, obj, dbev->sel_binctx, objs);

      if (data->get_status () != Hist_data::SUCCESS)
	{
	  if (type != DSP_DLAYOUT)
	    { // For data_layout, rows with zero metrics are OK
	      delete data;
	      continue;
	    }
	}
      TValue *values = NULL;
      if (data->get_status () == Hist_data::SUCCESS)
	{
	  Hist_data::HistItem *hi = data->fetch (0);
	  if (hi)
	    values = hi->value;
	}
      Hist_data::HistItem *total = data->get_totals ();
      int index2 = 0;
      char *tstr = GTXT (" Time");
      char *estr = GTXT ("Exclusive ");
      size_t len = strlen (estr);

      // get the metric list from the data
      MetricList *mlist = data->get_metric_list ();
      int index;
      Metric *mitem;
      double clock;
      Vec_loop (Metric*, mlist->get_items (), index, mitem)
      {
	if (mitem->get_subtype () == Metric::STATIC)
	  continue;
	if (last_init < index2)
	  {
	    last_init = index2;
	    jlabels->store (index2, NULL);
	    clock_list->store (index2, 0.0);
	    excl_list->store (index2, 0.0);
	    ep_list->store (index2, 0.0);
	    incl_list->store (index2, 0.0);
	    ip_list->store (index2, 0.0);
	    vtype->store (index2, 0);
	  }
	double dvalue = (values != NULL) ? values[index].to_double () : 0.0;
	double dtotal = total->value[index].to_double ();
	if (mitem->is_time_val ())
	  clock = 1.e+6 * dbeSession->get_clock (-1);
	else
	  clock = 0.0;

	clock_list->store (index2, clock);
	if ((mitem->get_subtype () == Metric::EXCLUSIVE) ||
	    (mitem->get_subtype () == Metric::DATASPACE))
	  {
	    if (i == 0)
	      {
		char *sstr = mitem->get_name ();
		if (!strncmp (sstr, estr, len))
		  sstr += len;
		char *buf, *lstr = strstr (sstr, tstr);
		if (lstr)
		  buf = dbe_strndup (sstr, lstr - sstr);
		else
		  buf = dbe_strdup (sstr);
		jlabels->store (index2, buf);
		vtype->store (index2, mitem->get_vtype ());
	      }
	    dvalue += excl_list->fetch (index2);
	    double percent = dtotal == 0.0 ? dtotal : (dvalue / dtotal) * 100;
	    excl_list->store (index2, dvalue);
	    ep_list->store (index2, percent);
	  }
	else
	  {
	    dvalue += incl_list->fetch (index2);
	    if (dvalue > dtotal)
	      dvalue = dtotal; // temporary correction
	    double percent = dtotal == 0.0 ? dtotal : (dvalue / dtotal) * 100;
	    incl_list->store (index2, dvalue);
	    ip_list->store (index2, percent);
	    index2++;
	  }
      }
      delete data;
    }
  delete prop_mlist;
  Vector<void*> *summary = new Vector<void*>(2);
  summary->store (0, name_objs);
  summary->store (1, metric_objs);
  return summary;
}

// Get Summary List
Vector<void*> *
dbeGetSummary (int dbevindex, Vector<Obj> *sel_objs, int type, int subtype)
{
  bool is_data, is_mem, is_indx, is_iodata, is_heapdata;
  Hist_data::HistItem *total;
  MetricList *prop_mlist; // as passed to get_hist_data
  MetricList *mlist; // as stored in the data
  Metric *mitem;
  int i, nname, nitems, index, index2;
  TValue *values;
  double dvalue, clock;
  Hist_data *data;
  Vector<double> *percent_scale;

  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  if (sel_objs == NULL || sel_objs->size () == 0)
    return NULL;

  is_mem = false;
  is_data = false;
  is_indx = false;
  is_iodata = false;
  is_heapdata = false;
  nname = SUMMARY_NAME;
  Vector<Histable*>*objs = new Vector<Histable*>(sel_objs->size ());
  if (type == DSP_TIMELINE)
    objs->append ((Histable *) sel_objs->fetch (0));
  else
    {
      switch (type)
	{
	case DSP_FUNCTION:
	  data = dbev->func_data;
	  break;
	case DSP_LINE:
	  data = dbev->line_data;
	  break;
	case DSP_PC:
	  data = dbev->pc_data;
	  break;
	case DSP_SELF:
	  data = dbev->fitem_data;
	  break;
	case DSP_SOURCE:
	case DSP_SOURCE_V2:
	  data = dbev->src_data;
	  break;
	case DSP_DISASM:
	case DSP_DISASM_V2:
	  data = dbev->dis_data;
	  break;
	case DSP_DLAYOUT:
	  is_data = true;
	  nname = LSUMMARY_NAME;
	  data = dbev->dlay_data;
	  break;
	case DSP_DATAOBJ:
	  is_data = true;
	  nname = DSUMMARY_NAME;
	  data = dbev->dobj_data;
	  break;
	case DSP_MEMOBJ:
	  is_data = true;
	  is_mem = true;
	  nname = IMSUMMARY_NAME;
	  data = dbev->get_indxobj_data (subtype);
	  break;
	case DSP_INDXOBJ:
	  is_indx = true;
	  nname = IMSUMMARY_NAME;
	  data = dbev->get_indxobj_data (subtype);
	  break;
	case DSP_IOACTIVITY:
	  is_iodata = true;
	  nname = IMSUMMARY_NAME;
	  data = dbev->iofile_data;
	  break;
	case DSP_IOVFD:
	  is_iodata = true;
	  nname = IMSUMMARY_NAME;
	  data = dbev->iovfd_data;
	  break;
	case DSP_IOCALLSTACK:
	  is_iodata = true;
	  nname = IMSUMMARY_NAME;
	  data = dbev->iocs_data;
	  break;
	case DSP_HEAPCALLSTACK:
	  is_heapdata = true;
	  nname = IMSUMMARY_NAME;
	  data = dbev->heapcs_data;
	  break;
	default:
	  data = NULL;
	  break;
	}
      if (data == NULL || data->get_status () != Hist_data::SUCCESS)
	return NULL;

      Hist_data::HistItem *current_item;
      for (i = 0; i < sel_objs->size (); i++)
	{
	  int sel_index = (int) sel_objs->fetch (i);
	  if (type != DSP_IOACTIVITY && type != DSP_IOVFD &&
	      type != DSP_IOCALLSTACK && type != DSP_HEAPCALLSTACK)
	    {
	      if (sel_index < 0 || sel_index >= data->size ())
		continue;
	      current_item = data->fetch (sel_index);
	      if (current_item->obj == NULL)
		continue;
	    }
	  else
	    {
	      if (sel_index < 0)
		continue;
	      bool found = false;
	      for (int j = 0; j < data->size (); j++)
		{
		  current_item = data->fetch (j);
		  if ((current_item->obj != NULL) && (current_item->obj->id == sel_index))
		    {
		      found = true;
		      break;
		    }
		}
	      if (!found)
		continue;
	    }
	  char *nm = current_item->obj->get_name ();
	  if (streq (nm, NTXT ("<Total>")))
	    {
	      // Special case for 'Total'.
	      // Multi selection which includes 'Total' is only 'Total'
	      objs->reset ();
	      objs->append (current_item->obj);
	      break;
	    }
	  objs->append (current_item->obj);
	}
    }
  if (objs->size () == 0)
    return NULL;

  // Set name area
  Vector<int> *saligns = new Vector<int>(nname);
  Vector<char>*mnemonic = new Vector<char>(nname);
  Vector<char*> *jlabels = new Vector<char*>(nname);
  Vector<char*> *jvalues = new Vector<char*>(nname);
  Vector<void*> *name_objs = new Vector<void*>(4);
  name_objs->store (0, saligns);
  name_objs->store (1, mnemonic);
  name_objs->store (2, jlabels);
  name_objs->store (3, jvalues);
  if (is_mem)
    setMemSummary (objs, saligns, mnemonic, jlabels, jvalues);
  else if (is_indx)
    setIndxSummary (objs, saligns, mnemonic, jlabels, jvalues);
  else if (is_data)
    setDataSummary (objs, saligns, mnemonic, jlabels, jvalues);
  else if (is_iodata)
    setIOActivitySummary (objs, saligns, mnemonic, jlabels, jvalues);
  else if (is_heapdata)
    setHeapActivitySummary (objs, saligns, mnemonic, jlabels, jvalues);
  else
    setSummary (objs, saligns, mnemonic, jlabels, jvalues);

  // Get the reference metrics
  if (is_data)
    prop_mlist = new MetricList (dbev->get_metric_ref (MET_DATA));
  else if (is_indx)
    prop_mlist = new MetricList (dbev->get_metric_ref (MET_INDX));
  else if (is_iodata)
    prop_mlist = new MetricList (dbev->get_metric_ref (MET_IO));
  else if (is_heapdata)
    prop_mlist = new MetricList (dbev->get_metric_ref (MET_HEAP));
  else
    prop_mlist = new MetricList (dbev->get_metric_ref (MET_NORMAL));

  // XXXX a workaround to avoid aggregated data for compare mode, only show base experiment data
  if (prop_mlist && dbev->comparingExperiments ())
    prop_mlist = dbev->get_compare_mlist (prop_mlist, 0);
  nitems = prop_mlist->get_items ()->size ();

  // Set the metrics area
  jlabels = new Vector<char*>(nitems);
  Vector<double> *clock_list = new Vector<double>(nitems);
  Vector<double> *excl_list = new Vector<double>(nitems);
  Vector<double> *ep_list = new Vector<double>(nitems);
  Vector<double> *incl_list = new Vector<double>(nitems);
  Vector<double> *ip_list = new Vector<double>(nitems);
  Vector<int> *vtype = new Vector<int>(nitems);

  // Initialize Java String array
  Vector<void*> *metric_objs = new Vector<void*>(8);
  metric_objs->store (0, jlabels);
  metric_objs->store (1, clock_list);
  metric_objs->store (2, excl_list);
  metric_objs->store (3, ep_list);
  metric_objs->store (4, incl_list);
  metric_objs->store (5, ip_list);
  metric_objs->store (6, vtype);
  percent_scale = new Vector<double>();
  int last_init = -1;
  for (i = 0; i < objs->size (); i++)
    {
      Histable *current_obj = objs->fetch (i);
      // Get the data to be displayed
      data = dbev->get_hist_data (prop_mlist, current_obj->get_type (), subtype,
				  Hist_data::SELF, current_obj, dbev->sel_binctx, objs);
      if (data->get_status () != Hist_data::SUCCESS)
	{
	  if (type != DSP_DLAYOUT)
	    { // For data_layout, rows with zero metrics are OK
	      delete data;
	      continue;
	    }
	}
      Hist_data::HistItem *hi = data->fetch (0);
      values = hi ? hi->value : NULL;
      total = data->get_totals ();
      index2 = 0;

      // get the metric list from the data
      mlist = data->get_metric_list ();

      // We loop over the metrics in mlist.
      // We construct index2, which tells us
      // the corresponding entry in the metric_objs lists.
      // We need this mapping multiple times.
      // So, if you change the looping in any way here,
      // do so as well in other similar loops.
      // All such loops are marked so:
      // See discussion on "mlist-to-index2 mapping".

      Vec_loop (Metric*, mlist->get_items (), index, mitem)
      {
	if (mitem->get_subtype () == Metric::STATIC)
	  continue;
	if (last_init < index2)
	  {
	    last_init = index2;
	    jlabels->store (index2, NULL);
	    clock_list->store (index2, 0.0);
	    excl_list->store (index2, 0.0);
	    ep_list->store (index2, 0.0);
	    incl_list->store (index2, 0.0);
	    ip_list->store (index2, 0.0);
	    vtype->store (index2, 0);
	  }
	dvalue = (values != NULL) ? values[index].to_double () : 0.0;
	double dtotal = total->value[index].to_double ();
	percent_scale->store (index, dtotal == 0. ? 0. : 100. / dtotal);
	if (mitem->is_time_val ())
	  clock = 1.e+6 * dbeSession->get_clock (-1);
	else
	  clock = 0.0;

	clock_list->store (index2, clock);
	if (mitem->get_subtype () == Metric::EXCLUSIVE ||
	    mitem->get_subtype () == Metric::DATASPACE)
	  {
	    if (i == 0)
	      {
		char *sstr = mitem->get_username ();
		char *buf = dbe_strdup (sstr);
		jlabels->store (index2, buf);
		vtype->store (index2, mitem->get_vtype ());
	      }
	    dvalue += excl_list->fetch (index2);
	    double percent = dvalue * percent_scale->fetch (index);
	    excl_list->store (index2, dvalue);
	    ep_list->store (index2, percent);
	    if (is_data || is_indx || is_iodata || is_heapdata)
	      // move to next row, except if there's inclusive data, too
	      index2++;
	  }
	else
	  {
	    dvalue += incl_list->fetch (index2);
	    if (dvalue > dtotal && mitem->get_type () != BaseMetric::DERIVED)
	      dvalue = dtotal; // temporary correction
	    double percent = dvalue * percent_scale->fetch (index);
	    incl_list->store (index2, dvalue);
	    ip_list->store (index2, percent);
	    index2++;
	  }
      }
      delete data;
    }

  // for multi-selection, we have to recompute the derived metrics
  if (objs->size () > 1 &&
      dbev->get_derived_metrics () != NULL &&
      dbev->get_derived_metrics ()->get_items () != NULL &&
      dbev->get_derived_metrics ()->get_items ()->size () > 0)
    {
      // See discussion on "mlist-to-index2 mapping".
      Vector<Metric*> *mvec = new Vector<Metric*>(nitems);
      index2 = 0;
      Vec_loop (Metric*, prop_mlist->get_items (), index, mitem)
      {
	if (mitem->get_subtype () == Metric::STATIC)
	  continue;
	if (mitem->get_subtype () == Metric::EXCLUSIVE ||
	    mitem->get_subtype () == Metric::DATASPACE)
	  {
	    mvec->store (index2, mitem);
	    if (is_data || is_indx || is_iodata || is_heapdata)
	      index2++;
	  }
	else
	  {
	    assert (strcmp (mvec->fetch (index2)->get_cmd (), mitem->get_cmd ()) == 0);
	    index2++;
	  }
      }
      int *map = dbev->get_derived_metrics ()->construct_map (mvec, BaseMetric::EXCLUSIVE, mvec->fetch (0)->get_expr_spec ());
      if (map != NULL)
	{
	  int nmetrics = mvec->size ();
	  double *evalues = (double *) malloc (nmetrics * sizeof (double));
	  double *ivalues = (double *) malloc (nmetrics * sizeof (double));
	  for (index2 = 0; index2 < nmetrics; index2++)
	    {
	      evalues[index2] = excl_list->fetch (index2);
	      ivalues[index2] = incl_list->fetch (index2);
	    }

	  // evaluate derived metrics
	  dbev->get_derived_metrics ()->eval (map, evalues);
	  dbev->get_derived_metrics ()->eval (map, ivalues);
	  for (index2 = 0; index2 < nmetrics; index2++)
	    {
	      excl_list->store (index2, evalues[index2]);
	      incl_list->store (index2, ivalues[index2]);
	    }

	  // recompute percentages for derived metrics    EUGENE maybe all percentage computations should be moved here
	  // See discussion on "mlist-to-index2 mapping".
	  index2 = 0;
	  Vec_loop (Metric*, prop_mlist->get_items (), index, mitem)
	  {
	    if (mitem->get_subtype () == Metric::STATIC)
	      continue;
	    if (mitem->get_subtype () == Metric::EXCLUSIVE ||
		mitem->get_subtype () == Metric::DATASPACE)
	      {
		if (mitem->get_type () == BaseMetric::DERIVED)
		  ep_list->store (index2, excl_list->fetch (index2) * percent_scale->fetch (index));
		if (is_data || is_indx || is_iodata || is_heapdata)
		  index2++;
	      }
	    else
	      {
		if (mitem->get_type () == BaseMetric::DERIVED)
		  ip_list->store (index2, incl_list->fetch (index2) * percent_scale->fetch (index));
		index2++;
	      }
	  }
	  free (evalues);
	  free (ivalues);
	  free (map);
	}
      delete mvec;
    }
  delete prop_mlist;
  Vector<void*> *summary = new Vector<void*>(2);
  summary->store (0, name_objs);
  summary->store (1, metric_objs);
  delete objs;
  delete percent_scale;
  return summary;
}

char *
dbeGetExpName (int /*dbevindex*/, char *dir_name)
{
  char *ret;
  char *warn;
  if (col_ctr == NULL)
    col_ctr = new Coll_Ctrl (1); // Potential race condition?
  if (dir_name != NULL)
    {
      ret = col_ctr->set_directory (dir_name, &warn);
      // note that the warning and error msgs are written to stderr, not returned to caller
      if (warn != NULL)
	fprintf (stderr, NTXT ("%s"), warn);
      if (ret != NULL)
	fprintf (stderr, NTXT ("%s"), ret);
    }
  return dbe_strdup (col_ctr->get_expt ());
}

// === CollectDialog HWC info ===

Vector<Vector<char*>*> *
dbeGetHwcSets (int /*dbevindex*/, bool forKernel)
{
  Vector<Vector<char*>*> *list = new Vector<Vector<char*>*>(2);
  char * defctrs = hwc_get_default_cntrs2 (forKernel, 1);
  Vector<char*> *i18n = new Vector<char*>(1); // User name
  Vector<char*> *name = new Vector<char*>(1); // Internal name
  if (NULL != defctrs)
    {
      i18n->store (0, strdup (defctrs));
      name->store (0, strdup (NTXT ("default")));
    }
  list->store (0, i18n);
  list->store (1, name);
  return list;
}

static Vector<void*> *
dbeGetHwcs (Hwcentry **hwcs)
{
  int sz;
  for (sz = 0; hwcs && hwcs[sz]; sz++)
    ;
  Vector<void*> *list = new Vector<void*>(9);
  Vector<char*> *i18n = new Vector<char*>(sz);
  Vector<char*> *name = new Vector<char*>(sz);
  Vector<char*> *int_name = new Vector<char*>(sz);
  Vector<char*> *metric = new Vector<char*>(sz);
  Vector<long long> *val = new Vector<long long>(sz);
  Vector<int> *timecvt = new Vector<int>(sz);
  Vector<int> *memop = new Vector<int>(sz);
  Vector<char*> *short_desc = new Vector<char*>(sz);
  Vector<Vector<int>*> *reglist_v = new Vector<Vector<int>*>(sz);
  Vector<bool> *supportsAttrs = new Vector<bool>(sz);
  Vector<bool> *supportsMemspace = new Vector<bool>(sz);

  for (int i = 0; i < sz; i++)
    {
      Hwcentry *ctr = hwcs[i];
      Vector<int> *registers = new Vector<int>(MAX_PICS);
      regno_t *reglist = ctr->reg_list;
      for (int k = 0; !REG_LIST_EOL (reglist[k]) && k < MAX_PICS; k++)
	registers->store (k, reglist[k]);

      i18n->store (i, dbe_strdup (hwc_i18n_metric (ctr)));
      name->store (i, dbe_strdup (ctr->name));
      int_name->store (i, dbe_strdup (ctr->int_name));
      metric->store (i, dbe_strdup (ctr->metric));
      val->store (i, ctr->val); // signed promotion from int
      timecvt->store (i, ctr->timecvt);
      memop->store (i, ctr->memop);
      reglist_v->store (i, registers);
      short_desc->store (i, dbe_strdup (ctr->short_desc));
      supportsAttrs->store (i, true);
      supportsMemspace->store (i, ABST_MEMSPACE_ENABLED (ctr->memop));
    }
  list->store (0, i18n);
  list->store (1, name);
  list->store (2, int_name);
  list->store (3, metric);
  list->store (4, val);
  list->store (5, timecvt);
  list->store (6, memop);
  list->store (7, short_desc);
  list->store (8, reglist_v);
  list->store (9, supportsAttrs);
  list->store (10, supportsMemspace);
  return list;
}

Vector<void *> *
dbeGetHwcsAll (int /*dbevindex*/, bool forKernel)
{
  Vector<void*> *list = new Vector<void*>(2);
  list->store (0, dbeGetHwcs (hwc_get_std_ctrs (forKernel)));
  list->store (1, dbeGetHwcs (hwc_get_raw_ctrs (forKernel)));
  return list;
}

Vector<char*> *
dbeGetHwcHelp (int /*dbevindex*/, bool forKernel)
{
  Vector<char*> *strings = new Vector<char*>(32);
  FILE *f = tmpfile ();
  hwc_usage_f (forKernel, f, "", 0, 0, 1); // writes to f
  fflush (f);
  fseek (f, 0, SEEK_SET);
#define MAX_LINE_LEN 2048
  char buff[MAX_LINE_LEN];
  int ii = 0;
  while (fgets (buff, MAX_LINE_LEN, f))
    strings->store (ii++, dbe_strdup (buff));
  fclose (f);
  return strings;
}

Vector<char*> *
dbeGetHwcAttrList (int /*dbevindex*/, bool forKernel)
{
  char ** attr_list = hwc_get_attrs (forKernel); // Get Attribute list
  int size;
  for (size = 0; attr_list && attr_list[size]; size++)
    ;

  Vector<char*> *name = new Vector<char*>(size);
  for (int i = 0; i < size; i++)
    name->store (i, dbe_strdup (attr_list[i]));
  return name;
}

//Get maximum number of simultaneous counters
int
dbeGetHwcMaxConcurrent (int /*dbevindex*/, bool forKernel)
{
  return hwc_get_max_concurrent (forKernel);
}

// === End CollectDialog HWC info ===


//  Instruction-frequency data
Vector<char*> *
dbeGetIfreqData (int dbevindex)
{
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  if (!dbeSession->is_ifreq_available ())
    return NULL;
  int size = dbeSession->nexps ();
  if (size == 0)
    return NULL;

  // Initialize Java String array
  Vector<char*> *list = new Vector<char*>();
  for (int i = 0; i < size; i++)
    {
      Experiment *exp = dbeSession->get_exp (i);
      if (exp->broken || !dbev->get_exp_enable (i) || !exp->ifreqavail)
	continue;
      // write a header for the experiment
      list->append (dbe_sprintf (GTXT ("Instruction frequency data from experiment %s\n\n"),
				 exp->get_expt_name ()));
      // add its instruction frequency messages
      char *ifreq = pr_mesgs (exp->fetch_ifreq (), NTXT (""), NTXT (""));
      list->append (ifreq);
    }
  return list;
}

//   LeakList related methods
//
Vector<void*> *
dbeGetLeakListInfo (int dbevindex, bool leakflag)
{
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  MetricList *origmlist = dbev->get_metric_list (MET_NORMAL);
  MetricList *nmlist = new MetricList (origmlist);
  if (leakflag)
    nmlist->set_metrics (NTXT ("e.heapleakbytes:e.heapleakcnt:name"), true,
			 dbev->get_derived_metrics ());
  else
    nmlist->set_metrics (NTXT ("e.heapallocbytes:e.heapalloccnt:name"), true,
			 dbev->get_derived_metrics ());
  MetricList *mlist = new MetricList (nmlist);
  delete nmlist;

  CStack_data *lam = dbev->get_cstack_data (mlist);
  if (lam == NULL || lam->size () == 0)
    {
      delete lam;
      delete mlist;
      return NULL;
    }
  Vector<Vector<Obj>*> *evalue = new Vector<Vector<Obj>*>(lam->size ());
  Vector<Vector<Obj>*> *pcstack = new Vector<Vector<Obj>*>(lam->size ());
  Vector<Vector<Obj>*> *offstack = new Vector<Vector<Obj>*>(lam->size ());
  Vector<Vector<Obj>*> *fpcstack = new Vector<Vector<Obj>*>(lam->size ());
  Vector<Vector<Obj>*> *sumval = new Vector<Vector<Obj>*>(lam->size ());

  int index;
  CStack_data::CStack_item *lae;
  Vec_loop (CStack_data::CStack_item*, lam->cstack_items, index, lae)
  {
    Vector<Obj> *jivals = NULL;
    if (lae != NULL)
      {
	jivals = new Vector<Obj>(4);
	jivals->store (0, (Obj) (index + 1));
	jivals->store (1, (Obj) lae->value[1].ll);
	jivals->store (2, (Obj) lae->value[0].ll);
	jivals->store (3, (Obj) (leakflag ? 1 : 2));
      }
    evalue->store (index, jivals);
    int snum = lae->stack->size ();
    Vector<Obj> *jivals1 = new Vector<Obj>(snum);
    Vector<Obj> *jivals2 = new Vector<Obj>(snum);
    Vector<Obj> *jivals3 = new Vector<Obj>(snum);
    if (lae->stack != NULL)
      {
	for (int i = lae->stack->size () - 1; i >= 0; i--)
	  {
	    DbeInstr *instr = lae->stack->fetch (i);
	    jivals1->store (i, (Obj) instr);
	    jivals2->store (i, (Obj) instr->func);
	    jivals3->store (i, (Obj) instr->addr);
	  }
      }
    fpcstack->store (index, jivals1);
    pcstack->store (index, jivals2);
    offstack->store (index, jivals3);
    lae++;
  }
  Vector<Obj> *jivals4 = new Vector<Obj>(3);
  jivals4->store (0, (Obj) lam->size ());
  jivals4->store (1, (Obj) lam->total->value[1].ll);
  jivals4->store (2, (Obj) lam->total->value[0].ll);
  sumval->store (0, jivals4);
  delete lam;
  delete mlist;
  Vector<void*> *earray = new Vector<void*>(5);
  earray->store (0, evalue);
  earray->store (1, pcstack);
  earray->store (2, offstack);
  earray->store (3, fpcstack);
  earray->store (4, sumval);
  return earray;
}

// Map timeline address to function instr
//
Obj
dbeGetObject (int dbevindex, Obj sel_func, Obj sel_pc)
{
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
   abort ();
  if (sel_pc)
    return sel_pc;
  return sel_func;
}

char *
dbeGetName (int /*dbevindex*/, int exp_id)
// This function's name is not descriptive enough - it returns a string
//   containing the full experiment name with path, process name, and PID.
// There are various dbe functions that provide experiment name and experiment
// details, and they should probably be consolidated/refactored. (TBR)
// For another example of similar output formatting, see dbeGetExpName().
{
  int id = (exp_id < 0) ? 0 : exp_id;
  Experiment *exp = dbeSession->get_exp (id);
  if (exp == NULL)
    return NULL;
  char *buf =
	  dbe_sprintf (NTXT ("%s [%s, PID %d]"),
		       exp->get_expt_name (),
		       exp->utargname != NULL ? exp->utargname : GTXT ("(unknown)"),
		       exp->getPID ());
  return buf;
}

Vector<char*> *
dbeGetExpVerboseName (Vector<int> *exp_ids)
{
  int len = exp_ids->size ();
  Vector<char*> *list = new Vector<char*>(len);
  for (int i = 0; i < len; i++)
    {
      char * verboseName = dbeGetName (0, exp_ids->fetch (i)); // no strdup()
      list->store (i, verboseName);
    }
  return list;
}

long long
dbeGetStartTime (int /*dbevindex*/, int exp_id)
{
  int id = (exp_id < 0) ? 0 : exp_id;
  Experiment *exp = dbeSession->get_exp (id);
  return exp ? exp->getStartTime () : (long long) 0;
}

long long
dbeGetRelativeStartTime (int /*dbevindex*/, int exp_id)
{
  int id = (exp_id < 0) ? 0 : exp_id;
  Experiment *exp = dbeSession->get_exp (id);
  return exp ? exp->getRelativeStartTime () : (long long) 0;
}

long long
dbeGetEndTime (int /*dbevindex*/, int exp_id)
{
  int id = (exp_id < 0) ? 0 : exp_id;
  Experiment *exp = dbeSession->get_exp (id);

  // Experiment::getEndTime was initially implemented as
  // returning exp->last_event. To preserve the semantics
  // new Experiment::getLastEvent() is used here.
  return exp ? exp->getLastEvent () : (long long) 0;
}

int
dbeGetClock (int /*dbevindex*/, int exp_id)
{
  return dbeSession->get_clock (exp_id);
}

long long
dbeGetWallStartSec (int /*dbevindex*/, int exp_id)
{
  int id = (exp_id < 0) ? 0 : exp_id;
  Experiment *exp = dbeSession->get_exp (id);
  return exp ? exp->getWallStartSec () : 0ll;
}

char *
dbeGetHostname (int /*dbevindex*/, int exp_id)
{
  int id = (exp_id < 0) ? 0 : exp_id;
  Experiment *exp = dbeSession->get_exp (id);
  return exp ? dbe_strdup (exp->hostname) : NULL;
}

static DataView *
getTimelinePackets (int dbevindex, int exp_id, int data_id, int entity_prop_id)
{
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  const int sortprop_count = 3;
  const int sortprops[sortprop_count] = {
    PROP_HWCTAG, // aux
    entity_prop_id,
    PROP_TSTAMP
  };
  DataView *packets = dbev->get_filtered_events (exp_id, data_id,
						 sortprops, sortprop_count);
  return packets;
}

static long
getIdxByVals (DataView * packets, int aux, int entity_prop_val,
	      uint64_t time, DataView::Relation rel)
{
  const int sortprop_count = 3;
  Datum tval[sortprop_count];
  tval[0].setUINT32 (aux);
  tval[1].setUINT32 (entity_prop_val); //CPUID, LWPID, THRID are downsized to 32
  tval[2].setUINT64 (time);
  long idx = packets->getIdxByVals (tval, rel);
  return idx;
}

static bool
isValidIdx (DataView * packets, int entity_prop_id,
	    int aux, int entity_prop_val, long idx)
{
  if (idx < 0 || idx >= packets->getSize ())
    return false;
  int pkt_aux = packets->getIntValue (PROP_HWCTAG, idx);
  if (pkt_aux != aux)
    return false;
  if (entity_prop_id == PROP_EXPID)
    return true; // not a packet property; we know the packet is in this experiment
  if (entity_prop_id == PROP_NONE)
    return true; // not a packet property; we know the packet is in this experiment
  int pkt_ent = packets->getIntValue (entity_prop_id, idx);
  if (pkt_ent != entity_prop_val)
    return false;
  return true;
}

static bool
hasInvisbleTLEvents (Experiment *exp, VMode view_mode)
{
  if (exp->has_java && view_mode == VMODE_USER)
    return true;
  return false;
}

static bool
isVisibleTLEvent (Experiment *exp, VMode view_mode, DataView* packets, long idx)
{
  if (hasInvisbleTLEvents (exp, view_mode))
    {
      JThread *jthread = (JThread*) packets->getObjValue (PROP_JTHREAD, idx);
      if (jthread == JTHREAD_NONE || (jthread != NULL && jthread->is_system ()))
	return false;
    }
  return true;
}

static long
getTLVisibleIdxByStepping (Experiment *exp, VMode view_mode, int entity_prop_id,
			   DataView * packets, int aux, int entity_prop_val,
			   long idx, long move_count, int direction)
{
  assert (move_count >= 0);
  assert (direction == 1 || direction == -1 || direction == 0);
  if (direction == 0 /* precise hit required */)
    move_count = 0;
  do
    {
      if (!isValidIdx (packets, entity_prop_id, aux, entity_prop_val, idx))
	return -1;
      if (isVisibleTLEvent (exp, view_mode, packets, idx))
	{
	  if (move_count <= 0)
	    break;
	  move_count--;
	}
      if (direction == 0)
	return -1;
      idx += direction;
    }
  while (1);
  return idx;
}

static long
getTLVisibleIdxByVals (Experiment *exp, VMode view_mode, int entity_prop_id,
		       DataView * packets,
		       int aux, int entity_prop_val, uint64_t time, DataView::Relation rel)
{
  long idx = getIdxByVals (packets, aux, entity_prop_val, time, rel);
  if (!hasInvisbleTLEvents (exp, view_mode))
    return idx;
  if (idx < 0)
    return idx;
  if (rel == DataView::REL_EQ)
    return -1; // would require bi-directional search... not supported for now
  int direction = (rel == DataView::REL_LT || rel == DataView::REL_LTEQ) ? -1 : 1;
  idx = getTLVisibleIdxByStepping (exp, view_mode, entity_prop_id, packets,
				   aux, entity_prop_val,
				   idx, 0 /* first match */, direction);
  return idx;
}

// In thread mode, the entity name for non Java thread should be the 1st func
// from the current thread's stack. See #4961315
static char*
getThreadRootFuncName (int, int, int, int, VMode)
{
  return NULL; // until we figure out what we want to show... YXXX
}

Vector<void*> *
dbeGetEntityProps (int dbevindex) //YXXX TBD, should this be exp-specific?
{
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  Vector<int> *prop_id = new Vector<int>();
  Vector<char*> *prop_name = new Vector<char*>();
  Vector<char*> *prop_uname = new Vector<char*>();
  Vector<char*> *prop_cname = new Vector<char*>(); //must match TLModeCmd vals!

  prop_id->append (PROP_NONE);
  prop_name->append (dbe_strdup (GTXT ("NONE")));
  prop_uname->append (dbe_strdup (GTXT ("Unknown")));
  prop_cname->append (dbe_strdup (NTXT ("unknown")));

  prop_id->append (PROP_LWPID);
  prop_name->append (dbe_strdup (GTXT ("LWPID")));
  prop_uname->append (dbe_strdup (GTXT ("LWP")));
  prop_cname->append (dbe_strdup (NTXT ("lwp")));

  prop_id->append (PROP_THRID);
  prop_name->append (dbe_strdup (GTXT ("THRID")));
  prop_uname->append (dbe_strdup (GTXT ("Thread")));
  prop_cname->append (dbe_strdup (NTXT ("thread")));

  prop_id->append (PROP_CPUID);
  prop_name->append (dbe_strdup (GTXT ("CPUID")));
  prop_uname->append (dbe_strdup (GTXT ("CPU")));
  prop_cname->append (dbe_strdup (NTXT ("cpu")));

  prop_id->append (PROP_EXPID);
  prop_name->append (dbe_strdup (GTXT ("EXPID")));
  prop_uname->append (dbe_strdup (GTXT ("Process"))); // placeholder...
  // ...until we finalize how to expose user-level Experiments, descendents
  prop_cname->append (dbe_strdup (NTXT ("experiment")));
  Vector<void*> *darray = new Vector<void*>();
  darray->store (0, prop_id);
  darray->store (1, prop_name);
  darray->store (2, prop_uname);
  darray->store (3, prop_cname);
  return darray;
}

Vector<void*> *
dbeGetEntities (int dbevindex, int exp_id, int entity_prop_id)
{
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  Experiment *exp = dbeSession->get_exp (exp_id);
  if (exp == NULL)
    return NULL;

  // Recognize and skip faketime experiments
  if (exp->timelineavail == false)
    return NULL;
  Vector<Histable*> *tagObjs = exp->getTagObjs ((Prop_type) entity_prop_id);
  int total_nelem;
  if (tagObjs)
    total_nelem = (int) tagObjs->size ();
  else
    total_nelem = 0;
  const VMode view_mode = dbev->get_view_mode ();
  bool show_java_threadnames = (entity_prop_id == PROP_THRID &&
				view_mode != VMODE_MACHINE);
  // allocate the structures for the return
  Vector<int> *entity_prop_vals = new Vector<int>();
  Vector<char*> *jthr_names = new Vector<char*>();
  Vector<char*> *jthr_g_names = new Vector<char*>();
  Vector<char*> *jthr_p_names = new Vector<char*>();

  // now walk the tagObjs from the experiment, and check for filtering
  for (int tagObjsIdx = 0; tagObjsIdx < total_nelem; tagObjsIdx++)
    {
      int entity_prop_val = (int) ((Other *) tagObjs->fetch (tagObjsIdx))->tag;
      entity_prop_vals->append (entity_prop_val);
      char *jname, *jgname, *jpname;
      JThread *jthread = NULL;
      bool has_java_threadnames = false;
      if (show_java_threadnames)
	{
	  jthread = exp->get_jthread (entity_prop_val);
	  has_java_threadnames = (jthread != JTHREAD_DEFAULT
				  && jthread != JTHREAD_NONE);
	}
      if (!has_java_threadnames)
	{
	  jname = jgname = jpname = NULL;
	  if (entity_prop_id == PROP_THRID || entity_prop_id == PROP_LWPID)
	    // if non Java thread, set thread name to the 1st func
	    // from the current thread's stack. see #4961315
	    jname = getThreadRootFuncName (dbevindex, exp_id, entity_prop_id,
					   entity_prop_val, view_mode);
	}
      else
	{
	  jname = dbe_strdup (jthread->name);
	  jgname = dbe_strdup (jthread->group_name);
	  jpname = dbe_strdup (jthread->parent_name);
	}
      jthr_names->append (jname);
      jthr_g_names->append (jgname);
      jthr_p_names->append (jpname);
    }
  Vector<char*> *entity_prop_name_v = new Vector<char*>();
  char* entity_prop_name = dbeSession->getPropName (entity_prop_id);
  entity_prop_name_v->append (entity_prop_name);
  Vector<void*> *darray = new Vector<void*>(5);
  darray->store (0, entity_prop_vals);
  darray->store (1, jthr_names);
  darray->store (2, jthr_g_names);
  darray->store (3, jthr_p_names);
  darray->store (4, entity_prop_name_v); // vector only has 1 element
  return darray;
}

// TBR: dbeGetEntities() can be set to private now that we have dbeGetEntitiesV2()
Vector<void*> *
dbeGetEntitiesV2 (int dbevindex, Vector<int> *exp_ids, int entity_prop_id)
{
  int sz = exp_ids->size ();
  Vector<void*> *res = new Vector<void*>(sz);
  for (int ii = 0; ii < sz; ii++)
    {
      int expIdx = exp_ids->fetch (ii);
      Vector<void*>* ents = dbeGetEntities (dbevindex, expIdx, entity_prop_id);
      res->store (ii, ents);
    }
  return res;
}

//YXXX old-tl packets still used for details
static Vector<void*> *
getTLDetailValues (int dbevindex, Experiment * exp, int data_id,
		   VMode view_mode, DataView *packets, long idx)
{
  Vector<long long> *value = new Vector<long long>(15);
  long i = idx;
  if (data_id == DATA_SAMPLE || data_id == DATA_GCEVENT)
    {
      //YXXX DATA_SAMPLE not handled but could be.
    }
  Obj stack = (unsigned long) getStack (view_mode, packets, i);
  Vector<Obj> *funcs = stack ? dbeGetStackFunctions (dbevindex, stack) : NULL;
  Function *func = (Function*)
	  getStackPC (0, view_mode, packets, i)->convertto (Histable::FUNCTION);
  // Fill common data
  value->store (0, packets->getIntValue (PROP_LWPID, i));
  value->store (1, packets->getIntValue (PROP_THRID, i));
  value->store (2, packets->getIntValue (PROP_CPUID, i));
  value->store (3, packets->getLongValue (PROP_TSTAMP, i));
  value->store (4, (unsigned long) stack);
  value->store (5, (unsigned long) func);

  // Fill specific data
  switch (data_id)
    {
    case DATA_CLOCK:
      value->store (6, packets->getIntValue (PROP_MSTATE, i));
      {
	hrtime_t interval = exp->get_params ()->ptimer_usec * 1000LL // nanoseconds
		* packets->getLongValue (PROP_NTICK, i);
	value->store (7, interval);
      }
      value->store (8, packets->getIntValue (PROP_OMPSTATE, i));
      value->store (9, packets->getLongValue (PROP_EVT_TIME, i)); // visual duration
      break;
    case DATA_SYNCH:
      value->store (6, packets->getLongValue (PROP_EVT_TIME, i));
      value->store (7, packets->getLongValue (PROP_SOBJ, i));
      break;
    case DATA_HWC:
      value->store (6, packets->getLongValue (PROP_HWCINT, i));
      value->store (7, packets->getLongValue (PROP_VADDR, i)); // data vaddr
      value->store (8, packets->getLongValue (PROP_PADDR, i)); // data paddr
      value->store (9, packets->getLongValue (PROP_VIRTPC, i)); // pc paddr
      value->store (10, packets->getLongValue (PROP_PHYSPC, i)); // pc vaddr
      break;
    case DATA_RACE:
      value->store (6, packets->getIntValue (PROP_RTYPE, i));
      value->store (7, packets->getIntValue (PROP_RID, i));
      value->store (8, packets->getLongValue (PROP_RVADDR, i));
      break;
    case DATA_DLCK:
      value->store (6, packets->getIntValue (PROP_DTYPE, i));
      value->store (7, packets->getIntValue (PROP_DLTYPE, i));
      value->store (8, packets->getIntValue (PROP_DID, i));
      value->store (9, packets->getLongValue (PROP_DVADDR, i));
      break;
    case DATA_HEAP:
    case DATA_HEAPSZ:
      value->store (6, packets->getIntValue (PROP_HTYPE, i));
      value->store (7, packets->getLongValue (PROP_HSIZE, i));
      value->store (8, packets->getLongValue (PROP_HVADDR, i));
      value->store (9, packets->getLongValue (PROP_HOVADDR, i));
      value->store (10, packets->getLongValue (PROP_HLEAKED, i));
      value->store (11, packets->getLongValue (PROP_HFREED, i));
      value->store (12, packets->getLongValue (PROP_HCUR_ALLOCS, i)); // signed int64_t
      value->store (13, packets->getLongValue (PROP_HCUR_LEAKS, i));
      break;
    case DATA_IOTRACE:
      value->store (6, packets->getIntValue (PROP_IOTYPE, i));
      value->store (7, packets->getIntValue (PROP_IOFD, i));
      value->store (8, packets->getLongValue (PROP_IONBYTE, i));
      value->store (9, packets->getLongValue (PROP_EVT_TIME, i));
      value->store (10, packets->getIntValue (PROP_IOVFD, i));
      break;
    }
  Vector<void*> *result = new Vector<void*>(5);
  result->store (0, value);
  result->store (1, funcs); // Histable::Function*
  result->store (2, funcs ? dbeGetFuncNames (dbevindex, funcs) : 0); // formatted func names
  result->store (3, stack ? dbeGetStackPCs (dbevindex, stack) : 0); // Histable::DbeInstr*
  result->store (4, stack ? dbeGetStackNames (dbevindex, stack) : 0); // formatted pc names
  return result;
}

Vector<void*> *
dbeGetTLDetails (int dbevindex, int exp_id, int data_id,
		 int entity_prop_id, Obj event_id)
{
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  Experiment *exp = dbeSession->get_exp (exp_id < 0 ? 0 : exp_id);
  if (exp == NULL)
    return NULL;
  DataView *packets =
	  getTimelinePackets (dbevindex, exp_id, data_id, entity_prop_id);
  if (!packets)
    return NULL;

  VMode view_mode = dbev->get_view_mode ();
  long idx = (long) event_id;
  Vector<void*> *values = getTLDetailValues (dbevindex, exp, data_id, view_mode, packets, idx);
  return values;
}

Vector<Obj> *
dbeGetStackFunctions (int dbevindex, Obj stack)
{
  Vector<Obj> *instrs = dbeGetStackPCs (dbevindex, stack);
  if (instrs == NULL)
    return NULL;
  int stsize = instrs->size ();
  Vector<Obj> *jivals = new Vector<Obj>(stsize);
  for (int i = 0; i < stsize; i++)
    {
      Histable *obj = (Histable*) instrs->fetch (i);
      // if ( obj->get_type() != Histable::LINE ) {//YXXX what is this?
      // Remove the above check: why not do this conversion for lines -
      // otherwise filtering in timeline by function stack in omp user mode is broken
      obj = obj->convertto (Histable::FUNCTION);
      jivals->store (i, (Obj) obj);
    }
  delete instrs;
  return jivals;
}

Vector<void*> *
dbeGetStacksFunctions (int dbevindex, Vector<Obj> *stacks)
{
  long sz = stacks->size ();
  Vector<void*> *res = new Vector<void*>(sz);
  for (int ii = 0; ii < sz; ii++)
    {
      Obj stack = stacks->fetch (ii);
      Vector<Obj> *jivals = dbeGetStackFunctions (dbevindex, stack);
      res->store (ii, jivals);
    }
  return res;
}

Vector<Obj> *
dbeGetStackPCs (int dbevindex, Obj stack)
{
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  if (stack == 0)
    return NULL;

  bool show_all = dbev->isShowAll ();
  Vector<Histable*> *instrs = CallStack::getStackPCs ((void *) stack, !show_all);
  int stsize = instrs->size ();
  int istart = 0;
  bool showAll = dbev->isShowAll ();
  for (int i = 0; i < stsize - 1; i++)
    {
      Function *func = (Function*) instrs->fetch (i)->convertto (Histable::FUNCTION);
      int ix = func->module->loadobject->seg_idx;
      if (showAll && dbev->get_lo_expand (ix) == LIBEX_API)
	// truncate stack here:  LIBRARY_VISIBILITY if we are using API only but no hide
	istart = i;
    }
  stsize = stsize - istart;
  Vector<Obj> *jlvals = new Vector<Obj>(stsize);
  for (int i = 0; i < stsize; i++)
    {
      Histable *instr = instrs->fetch (i + istart);
      jlvals->store (i, (Obj) instr);
    }
  delete instrs;
  return jlvals;
}

Vector<char*> *
dbeGetStackNames (int dbevindex, Obj stack)
{
  DbeView *dbev = dbeSession->getView (dbevindex);
  Vector<Obj> *instrs = dbeGetStackPCs (dbevindex, stack);
  if (instrs == NULL)
    return NULL;
  int stsize = instrs->size ();
  Vector<char*> *list = new Vector<char*>(stsize);
  bool showAll = dbev->isShowAll ();
  for (int i = 0; i < stsize; i++)
    {
      Histable* instr = (Histable*) instrs->fetch (i);
      if (!showAll)
	{
	  // LIBRARY_VISIBILITY
	  Function *func = (Function*) instr->convertto (Histable::FUNCTION);
	  LoadObject *lo = ((Function*) func)->module->loadobject;
	  if (dbev->get_lo_expand (lo->seg_idx) == LIBEX_HIDE)
	    {
	      list->store (i, dbe_strdup (lo->get_name ()));
	      continue;
	    }
	}
      list->store (i, dbe_strdup (instr->get_name (dbev->get_name_format ())));
    }
  delete instrs;
  return list;
}

Vector<void*> *
dbeGetSamples (int dbevindex, int exp_id, int64_t lo_idx, int64_t hi_idx)
{
  DataView * packets =
	  getTimelinePackets (dbevindex, exp_id, DATA_SAMPLE, PROP_EXPID);
  if (packets == NULL || packets->getSize () == 0)
    return NULL;
  long lo;
  if (lo_idx < 0)
    lo = 0;
  else
    lo = (long) lo_idx;

  long long max = packets->getSize () - 1;
  long hi;
  if (hi_idx < 0 || hi_idx > max)
    hi = (long) max;
  else
    hi = (long) hi_idx;

  Vector<Vector<long long>*> *sarray = new Vector<Vector<long long>*>;
  Vector<long long>* starts = new Vector<long long>;
  Vector<long long>* ends = new Vector<long long>;
  Vector<long long>* rtimes = new Vector<long long>;
  Vector<char*> *startNames = new Vector<char*>;
  Vector<char*> *endNames = new Vector<char*>;
  Vector<int> *sampId = new Vector<int>;

  for (long index = lo; index <= hi; index++)
    {
      Sample *sample = (Sample*) packets->getObjValue (PROP_SMPLOBJ, index);
      PrUsage *prusage = sample->get_usage ();
      if (prusage == NULL)
	prusage = new PrUsage;
      Vector<long long> *states = prusage->getMstateValues ();
      sarray->append (states);
      starts->append (sample->get_start_time ());
      ends->append (sample->get_end_time ());
      rtimes->append (prusage->pr_rtime);
      startNames->append (dbe_strdup (sample->get_start_label ()));
      endNames->append (dbe_strdup (sample->get_end_label ()));
      sampId->append (sample->get_number ());
    }
  Vector<void *> *res = new Vector<void*>(6);
  res->store (0, sarray);
  res->store (1, starts);
  res->store (2, ends);
  res->store (3, rtimes);
  res->store (4, startNames);
  res->store (5, endNames);
  res->store (6, sampId);
  return res;
}

Vector<void*> *
dbeGetGCEvents (int dbevindex, int exp_id, int64_t lo_idx, int64_t hi_idx)
{
  DataView *packets =
	  getTimelinePackets (dbevindex, exp_id, DATA_GCEVENT, PROP_EXPID);
  if (packets == NULL || packets->getSize () == 0)
    return NULL;

  long lo;
  if (lo_idx < 0)
    lo = 0;
  else
    lo = (long) lo_idx;
  long long max = packets->getSize () - 1;
  long hi;
  if (hi_idx < 0 || hi_idx > max)
    hi = (long) max;
  else
    hi = (long) hi_idx;

  Vector<long long>* starts = new Vector<long long>;
  Vector<long long>* ends = new Vector<long long>;
  Vector<int> *eventId = new Vector<int>;
  for (long index = lo; index <= hi; index++)
    {
      GCEvent *gcevent = (GCEvent*) packets->getObjValue (PROP_GCEVENTOBJ, index);
      if (gcevent)
	{
	  starts->append (gcevent->start);
	  ends->append (gcevent->end);
	  eventId->append (gcevent->id);
	}
    }
  Vector<void *> *res = new Vector<void*>(3);
  res->store (0, starts);
  res->store (1, ends);
  res->store (2, eventId);
  return res;
}

Vector<Vector<char*>*>*
dbeGetIOStatistics (int dbevindex)
{
  DbeView *dbev = dbeSession->getView (dbevindex);
  Hist_data *hist_data;
  Hist_data::HistItem *hi;
  FileData *fDataTotal;

  hist_data = dbev->iofile_data;
  if (hist_data == NULL)
    return NULL;
  hi = hist_data->fetch (0);
  fDataTotal = (FileData*) hi->obj;

  Vector<char*> *writeStat = new Vector<char*>;
  Vector<char*> *readStat = new Vector<char*>;
  Vector<char*> *otherStat = new Vector<char*>;
  Vector<char*> *errorStat = new Vector<char*>;

  writeStat->append (dbe_strdup (GTXT ("Write Statistics")));
  readStat->append (dbe_strdup (GTXT ("Read Statistics")));
  otherStat->append (dbe_strdup (GTXT ("Other I/O Statistics")));
  errorStat->append (dbe_strdup (GTXT ("I/O Error Statistics")));

  StringBuilder sb;
  if (fDataTotal->getWriteCnt () > 0)
    {
      if (fDataTotal->getW0KB1KBCnt () > 0)
	{
	  sb.sprintf (GTXT ("0KB - 1KB"));
	  writeStat->append (sb.toString ());
	  sb.sprintf (NTXT ("%d"), fDataTotal->getW0KB1KBCnt ());
	  writeStat->append (sb.toString ());
	}
      if (fDataTotal->getW1KB8KBCnt () > 0)
	{
	  sb.sprintf (GTXT ("1KB - 8KB"));
	  writeStat->append (sb.toString ());
	  sb.sprintf (NTXT ("%d"), fDataTotal->getW1KB8KBCnt ());
	  writeStat->append (sb.toString ());
	}
      if (fDataTotal->getW8KB32KBCnt () > 0)
	{
	  sb.sprintf (GTXT ("8KB - 32KB"));
	  writeStat->append (sb.toString ());
	  sb.sprintf (NTXT ("%d"), fDataTotal->getW8KB32KBCnt ());
	  writeStat->append (sb.toString ());
	}
      if (fDataTotal->getW32KB128KBCnt () > 0)
	{
	  sb.sprintf (GTXT ("32KB - 128KB"));
	  writeStat->append (sb.toString ());
	  sb.sprintf (NTXT ("%d"), fDataTotal->getW32KB128KBCnt ());
	  writeStat->append (sb.toString ());
	}
      if (fDataTotal->getW128KB256KBCnt () > 0)
	{
	  sb.sprintf (GTXT ("128KB - 256KB"));
	  writeStat->append (sb.toString ());
	  sb.sprintf (NTXT ("%d"), fDataTotal->getW128KB256KBCnt ());
	  writeStat->append (sb.toString ());
	}
      if (fDataTotal->getW256KB512KBCnt () > 0)
	{
	  sb.sprintf (GTXT ("256KB - 512KB"));
	  writeStat->append (sb.toString ());
	  sb.sprintf (NTXT ("%d"), fDataTotal->getW256KB512KBCnt ());
	  writeStat->append (sb.toString ());
	}
      if (fDataTotal->getW512KB1000KBCnt () > 0)
	{
	  sb.sprintf (GTXT ("512KB - 1000KB"));
	  writeStat->append (sb.toString ());
	  sb.sprintf (NTXT ("%d"), fDataTotal->getW512KB1000KBCnt ());
	  writeStat->append (sb.toString ());
	}
      if (fDataTotal->getW1000KB10MBCnt () > 0)
	{
	  sb.sprintf (GTXT ("1000KB - 10MB"));
	  writeStat->append (sb.toString ());
	  sb.sprintf (NTXT ("%d"), fDataTotal->getW1000KB10MBCnt ());
	  writeStat->append (sb.toString ());
	}
      if (fDataTotal->getW10MB100MBCnt () > 0)
	{
	  sb.sprintf (GTXT ("10MB - 100MB"));
	  writeStat->append (sb.toString ());
	  sb.sprintf (NTXT ("%d"), fDataTotal->getW10MB100MBCnt ());
	  writeStat->append (sb.toString ());
	}
      if (fDataTotal->getW100MB1GBCnt () > 0)
	{
	  sb.sprintf (GTXT ("100MB - 1GB"));
	  writeStat->append (sb.toString ());
	  sb.sprintf (NTXT ("%d"), fDataTotal->getW100MB1GBCnt ());
	  writeStat->append (sb.toString ());
	}
      if (fDataTotal->getW1GB10GBCnt () > 0)
	{
	  sb.sprintf (GTXT ("1GB - 10GB"));
	  writeStat->append (sb.toString ());
	  sb.sprintf (NTXT ("%d"), fDataTotal->getW1GB10GBCnt ());
	  writeStat->append (sb.toString ());
	}
      if (fDataTotal->getW10GB100GBCnt () > 0)
	{
	  sb.sprintf (GTXT ("10GB - 100GB"));
	  writeStat->append (sb.toString ());
	  sb.sprintf (NTXT ("%d"), fDataTotal->getW10GB100GBCnt ());
	  writeStat->append (sb.toString ());
	}
      if (fDataTotal->getW100GB1TBCnt () > 0)
	{
	  sb.sprintf (GTXT ("100GB - 1TB"));
	  writeStat->append (sb.toString ());
	  sb.sprintf (NTXT ("%d"), fDataTotal->getW100GB1TBCnt ());
	  writeStat->append (sb.toString ());
	}
      if (fDataTotal->getW1TB10TBCnt () > 0)
	{
	  sb.sprintf (GTXT ("1TB - 10TB"));
	  writeStat->append (sb.toString ());
	  sb.sprintf (NTXT ("%d"), fDataTotal->getW1TB10TBCnt ());
	  writeStat->append (sb.toString ());
	}

      sb.sprintf (GTXT ("Longest write"));
      writeStat->append (sb.toString ());
      sb.sprintf (NTXT ("%.6f (secs.)"),
		  (double) (fDataTotal->getWSlowestBytes () / (double) NANOSEC));
      writeStat->append (sb.toString ());

      sb.sprintf (GTXT ("Smallest write bytes"));
      writeStat->append (sb.toString ());
      sb.sprintf (NTXT ("%d"), (int) (fDataTotal->getWSmallestBytes ()));
      writeStat->append (sb.toString ());

      sb.sprintf (GTXT ("Largest write bytes"));
      writeStat->append (sb.toString ());
      sb.sprintf (NTXT ("%d"), (int) (fDataTotal->getWLargestBytes ()));
      writeStat->append (sb.toString ());

      sb.sprintf (GTXT ("Total time"));
      writeStat->append (sb.toString ());
      sb.sprintf (NTXT ("%.6f (secs.)"),
		  (double) (fDataTotal->getWriteTime () / (double) NANOSEC));
      writeStat->append (sb.toString ());

      sb.sprintf (GTXT ("Total calls"));
      writeStat->append (sb.toString ());
      sb.sprintf (NTXT ("%d"), (int) (fDataTotal->getWriteCnt ()));
      writeStat->append (sb.toString ());

      sb.sprintf (GTXT ("Total bytes"));
      writeStat->append (sb.toString ());
      sb.sprintf (NTXT ("%lld"), (long long) (fDataTotal->getWriteBytes ()));
      writeStat->append (sb.toString ());
    }

  if (fDataTotal->getReadCnt () > 0)
    {
      if (fDataTotal->getR0KB1KBCnt () > 0)
	{
	  sb.sprintf (GTXT ("0KB - 1KB"));
	  readStat->append (sb.toString ());
	  sb.sprintf (NTXT ("%d"), fDataTotal->getR0KB1KBCnt ());
	  readStat->append (sb.toString ());
	}
      if (fDataTotal->getR1KB8KBCnt () > 0)
	{
	  sb.sprintf (GTXT ("1KB - 8KB"));
	  readStat->append (sb.toString ());
	  sb.sprintf (NTXT ("%d"), fDataTotal->getR1KB8KBCnt ());
	  readStat->append (sb.toString ());
	}
      if (fDataTotal->getR8KB32KBCnt () > 0)
	{
	  sb.sprintf (GTXT ("8KB - 32KB"));
	  readStat->append (sb.toString ());
	  sb.sprintf (NTXT ("%d"), fDataTotal->getR8KB32KBCnt ());
	  readStat->append (sb.toString ());
	}
      if (fDataTotal->getR32KB128KBCnt () > 0)
	{
	  sb.sprintf (GTXT ("32KB - 128KB"));
	  readStat->append (sb.toString ());
	  sb.sprintf (NTXT ("%d"), fDataTotal->getR32KB128KBCnt ());
	  readStat->append (sb.toString ());
	}
      if (fDataTotal->getR128KB256KBCnt () > 0)
	{
	  sb.sprintf (GTXT ("128KB - 256KB"));
	  readStat->append (sb.toString ());
	  sb.sprintf (NTXT ("%d"), fDataTotal->getR128KB256KBCnt ());
	  readStat->append (sb.toString ());
	}
      if (fDataTotal->getR256KB512KBCnt () > 0)
	{
	  sb.sprintf (GTXT ("256KB - 512KB"));
	  readStat->append (sb.toString ());
	  sb.sprintf (NTXT ("%d"), fDataTotal->getR256KB512KBCnt ());
	  readStat->append (sb.toString ());
	}
      if (fDataTotal->getR512KB1000KBCnt () > 0)
	{
	  sb.sprintf (GTXT ("512KB - 1000KB"));
	  readStat->append (sb.toString ());
	  sb.sprintf (NTXT ("%d"), fDataTotal->getR512KB1000KBCnt ());
	  readStat->append (sb.toString ());
	}
      if (fDataTotal->getR1000KB10MBCnt () > 0)
	{
	  sb.sprintf (GTXT ("1000KB - 10MB"));
	  readStat->append (sb.toString ());
	  sb.sprintf (NTXT ("%d"), fDataTotal->getR1000KB10MBCnt ());
	  readStat->append (sb.toString ());
	}
      if (fDataTotal->getR10MB100MBCnt () > 0)
	{
	  sb.sprintf (GTXT ("10MB - 100MB"));
	  readStat->append (sb.toString ());
	  sb.sprintf (NTXT ("%d"), fDataTotal->getR10MB100MBCnt ());
	  readStat->append (sb.toString ());
	}
      if (fDataTotal->getR100MB1GBCnt () > 0)
	{
	  sb.sprintf (GTXT ("100MB - 1GB"));
	  readStat->append (sb.toString ());
	  sb.sprintf (NTXT ("%d"), fDataTotal->getR100MB1GBCnt ());
	  readStat->append (sb.toString ());
	}
      if (fDataTotal->getR1GB10GBCnt () > 0)
	{
	  sb.sprintf (GTXT ("1GB - 10GB"));
	  readStat->append (sb.toString ());
	  sb.sprintf (NTXT ("%d"), fDataTotal->getR1GB10GBCnt ());
	  readStat->append (sb.toString ());
	}
      if (fDataTotal->getR10GB100GBCnt () > 0)
	{
	  sb.sprintf (GTXT ("10GB - 100GB"));
	  readStat->append (sb.toString ());
	  sb.sprintf (NTXT ("%d"), fDataTotal->getR10GB100GBCnt ());
	  readStat->append (sb.toString ());
	}
      if (fDataTotal->getR100GB1TBCnt () > 0)
	{
	  sb.sprintf (GTXT ("100GB - 1TB"));
	  readStat->append (sb.toString ());
	  sb.sprintf (NTXT ("%d"), fDataTotal->getR100GB1TBCnt ());
	  readStat->append (sb.toString ());
	}
      if (fDataTotal->getR1TB10TBCnt () > 0)
	{
	  sb.sprintf (GTXT ("1TB - 10TB"));
	  readStat->append (sb.toString ());
	  sb.sprintf (NTXT ("%d"), fDataTotal->getR1TB10TBCnt ());
	  readStat->append (sb.toString ());
	}

      sb.sprintf (GTXT ("Longest read"));
      readStat->append (sb.toString ());
      sb.sprintf (NTXT ("%.6f (secs.)"),
		  (double) (fDataTotal->getRSlowestBytes () / (double) NANOSEC));
      readStat->append (sb.toString ());

      sb.sprintf (GTXT ("Smallest read bytes"));
      readStat->append (sb.toString ());
      sb.sprintf (NTXT ("%d"), (int) (fDataTotal->getRSmallestBytes ()));
      readStat->append (sb.toString ());

      sb.sprintf (GTXT ("Largest read bytes"));
      readStat->append (sb.toString ());
      sb.sprintf (NTXT ("%d"), (int) (fDataTotal->getRLargestBytes ()));
      readStat->append (sb.toString ());

      sb.sprintf (GTXT ("Total time"));
      readStat->append (sb.toString ());
      sb.sprintf (NTXT ("%.6f (secs.)"),
		  (double) (fDataTotal->getReadTime () / (double) NANOSEC));
      readStat->append (sb.toString ());

      sb.sprintf (GTXT ("Total calls"));
      readStat->append (sb.toString ());
      sb.sprintf (NTXT ("%d"), (int) (fDataTotal->getReadCnt ()));
      readStat->append (sb.toString ());

      sb.sprintf (GTXT ("Total bytes"));
      readStat->append (sb.toString ());
      sb.sprintf (NTXT ("%lld"), (long long) (fDataTotal->getReadBytes ()));
      readStat->append (sb.toString ());
    }

  if (fDataTotal->getOtherCnt () > 0)
    {
      sb.sprintf (GTXT ("Total time"));
      otherStat->append (sb.toString ());
      sb.sprintf (NTXT ("%.6f (secs.)"),
		  (double) (fDataTotal->getOtherTime () / (double) NANOSEC));
      otherStat->append (sb.toString ());

      sb.sprintf (GTXT ("Total calls"));
      otherStat->append (sb.toString ());
      sb.sprintf (NTXT ("%d"), (int) (fDataTotal->getOtherCnt ()));
      otherStat->append (sb.toString ());
    }

  if (fDataTotal->getErrorCnt () > 0)
    {
      sb.sprintf (GTXT ("Total time"));
      errorStat->append (sb.toString ());
      sb.sprintf (NTXT ("%.6f (secs.)"),
		  (double) (fDataTotal->getErrorTime () / (double) NANOSEC));
      errorStat->append (sb.toString ());

      sb.sprintf (GTXT ("Total calls"));
      errorStat->append (sb.toString ());
      sb.sprintf (NTXT ("%d"), (int) (fDataTotal->getErrorCnt ()));
      errorStat->append (sb.toString ());
    }
  Vector<Vector<char*>*>* statisticsData = new Vector<Vector<char*>*>(4);
  statisticsData->store (0, writeStat);
  statisticsData->store (1, readStat);
  statisticsData->store (2, otherStat);
  statisticsData->store (3, errorStat);
  return statisticsData;
}

Vector<Vector<char*>*>*
dbeGetHeapStatistics (int dbevindex)
{
  DbeView *dbev = dbeSession->getView (dbevindex);
  Hist_data *hist_data;
  Hist_data::HistItem *hi;
  HeapData *hDataTotal;
  hist_data = dbev->heapcs_data;
  if (hist_data == NULL)
    return NULL;

  hi = hist_data->fetch (0);
  hDataTotal = (HeapData*) hi->obj;
  Vector<char*> *memoryUsage = new Vector<char*>;
  Vector<char*> *allocStat = new Vector<char*>;
  Vector<char*> *leakStat = new Vector<char*>;

  memoryUsage->append (dbe_strdup (GTXT ("Process With Highest Peak Memory Usage")));
  allocStat->append (dbe_strdup (GTXT ("Memory Allocations Statistics")));
  leakStat->append (dbe_strdup (GTXT ("Memory Leaks Statistics")));
  StringBuilder sb;
  if (hDataTotal->getPeakMemUsage () > 0)
    {
      sb.sprintf (GTXT ("Heap size bytes"));
      memoryUsage->append (sb.toString ());
      sb.sprintf (NTXT ("%lld"), (long long) (hDataTotal->getPeakMemUsage ()));
      memoryUsage->append (sb.toString ());

      sb.sprintf (GTXT ("Experiment Id"));
      memoryUsage->append (sb.toString ());
      sb.sprintf (NTXT ("%d"), (int) (hDataTotal->getUserExpId ()));
      memoryUsage->append (sb.toString ());

      sb.sprintf (GTXT ("Process Id"));
      memoryUsage->append (sb.toString ());
      sb.sprintf (NTXT ("%d"), (int) (hDataTotal->getPid ()));
      memoryUsage->append (sb.toString ());

      Vector<hrtime_t> *pTimestamps;
      pTimestamps = hDataTotal->getPeakTimestamps ();
      if (pTimestamps != NULL)
	{
	  for (int i = 0; i < pTimestamps->size (); i++)
	    {
	      sb.sprintf (GTXT ("Time of peak"));
	      memoryUsage->append (sb.toString ());
	      sb.sprintf (NTXT ("%.3f (secs.)"), (double) (pTimestamps->fetch (i) / (double) NANOSEC));
	      memoryUsage->append (sb.toString ());
	    }
	}
    }

  if (hDataTotal->getAllocCnt () > 0)
    {
      if (hDataTotal->getA0KB1KBCnt () > 0)
	{
	  sb.sprintf (GTXT ("0KB - 1KB"));
	  allocStat->append (sb.toString ());
	  sb.sprintf (NTXT ("%d"), hDataTotal->getA0KB1KBCnt ());
	  allocStat->append (sb.toString ());
	}
      if (hDataTotal->getA1KB8KBCnt () > 0)
	{
	  sb.sprintf (GTXT ("1KB - 8KB"));
	  allocStat->append (sb.toString ());
	  sb.sprintf (NTXT ("%d"), hDataTotal->getA1KB8KBCnt ());
	  allocStat->append (sb.toString ());
	}
      if (hDataTotal->getA8KB32KBCnt () > 0)
	{
	  sb.sprintf (GTXT ("8KB - 32KB"));
	  allocStat->append (sb.toString ());
	  sb.sprintf (NTXT ("%d"), hDataTotal->getA8KB32KBCnt ());
	  allocStat->append (sb.toString ());
	}
      if (hDataTotal->getA32KB128KBCnt () > 0)
	{
	  sb.sprintf (GTXT ("32KB - 128KB"));
	  allocStat->append (sb.toString ());
	  sb.sprintf (NTXT ("%d"), hDataTotal->getA32KB128KBCnt ());
	  allocStat->append (sb.toString ());
	}
      if (hDataTotal->getA128KB256KBCnt () > 0)
	{
	  sb.sprintf (GTXT ("128KB - 256KB"));
	  allocStat->append (sb.toString ());
	  sb.sprintf (NTXT ("%d"), hDataTotal->getA128KB256KBCnt ());
	  allocStat->append (sb.toString ());
	}
      if (hDataTotal->getA256KB512KBCnt () > 0)
	{
	  sb.sprintf (GTXT ("256KB - 512KB"));
	  allocStat->append (sb.toString ());
	  sb.sprintf (NTXT ("%d"), hDataTotal->getA256KB512KBCnt ());
	  allocStat->append (sb.toString ());
	}
      if (hDataTotal->getA512KB1000KBCnt () > 0)
	{
	  sb.sprintf (GTXT ("512KB - 1000KB"));
	  allocStat->append (sb.toString ());
	  sb.sprintf (NTXT ("%d"), hDataTotal->getA512KB1000KBCnt ());
	  allocStat->append (sb.toString ());
	}
      if (hDataTotal->getA1000KB10MBCnt () > 0)
	{
	  sb.sprintf (GTXT ("1000KB - 10MB"));
	  allocStat->append (sb.toString ());
	  sb.sprintf (NTXT ("%d"), hDataTotal->getA1000KB10MBCnt ());
	  allocStat->append (sb.toString ());
	}
      if (hDataTotal->getA10MB100MBCnt () > 0)
	{
	  sb.sprintf (GTXT ("10MB - 100MB"));
	  allocStat->append (sb.toString ());
	  sb.sprintf (NTXT ("%d"), hDataTotal->getA10MB100MBCnt ());
	  allocStat->append (sb.toString ());
	}
      if (hDataTotal->getA100MB1GBCnt () > 0)
	{
	  sb.sprintf (GTXT ("100MB - 1GB"));
	  allocStat->append (sb.toString ());
	  sb.sprintf (NTXT ("%d"), hDataTotal->getA100MB1GBCnt ());
	  allocStat->append (sb.toString ());
	}
      if (hDataTotal->getA1GB10GBCnt () > 0)
	{
	  sb.sprintf (GTXT ("1GB - 10GB"));
	  allocStat->append (sb.toString ());
	  sb.sprintf (NTXT ("%d"), hDataTotal->getA1GB10GBCnt ());
	  allocStat->append (sb.toString ());
	}
      if (hDataTotal->getA10GB100GBCnt () > 0)
	{
	  sb.sprintf (GTXT ("10GB - 100GB"));
	  allocStat->append (sb.toString ());
	  sb.sprintf (NTXT ("%d"), hDataTotal->getA10GB100GBCnt ());
	  allocStat->append (sb.toString ());
	}
      if (hDataTotal->getA100GB1TBCnt () > 0)
	{
	  sb.sprintf (GTXT ("100GB - 1TB"));
	  allocStat->append (sb.toString ());
	  sb.sprintf (NTXT ("%d"), hDataTotal->getA100GB1TBCnt ());
	  allocStat->append (sb.toString ());
	}
      if (hDataTotal->getA1TB10TBCnt () > 0)
	{
	  sb.sprintf (GTXT ("1TB - 10TB"));
	  allocStat->append (sb.toString ());
	  sb.sprintf (NTXT ("%d"), hDataTotal->getA1TB10TBCnt ());
	  allocStat->append (sb.toString ());
	}

      sb.sprintf (GTXT ("Smallest allocation bytes"));
      allocStat->append (sb.toString ());
      sb.sprintf (NTXT ("%d"), (int) (hDataTotal->getASmallestBytes ()));
      allocStat->append (sb.toString ());

      sb.sprintf (GTXT ("Largest allocation bytes"));
      allocStat->append (sb.toString ());
      sb.sprintf (NTXT ("%d"), (int) (hDataTotal->getALargestBytes ()));
      allocStat->append (sb.toString ());

      sb.sprintf (GTXT ("Total allocations"));
      allocStat->append (sb.toString ());
      sb.sprintf (NTXT ("%d"), (int) (hDataTotal->getAllocCnt ()));
      allocStat->append (sb.toString ());

      sb.sprintf (GTXT ("Total bytes"));
      allocStat->append (sb.toString ());
      sb.sprintf (NTXT ("%lld"), (long long) (hDataTotal->getAllocBytes ()));
      allocStat->append (sb.toString ());
    }

  if (hDataTotal->getLeakCnt () > 0)
    {
      if (hDataTotal->getL0KB1KBCnt () > 0)
	{
	  sb.sprintf (GTXT ("0KB - 1KB"));
	  leakStat->append (sb.toString ());
	  sb.sprintf (NTXT ("%d"), hDataTotal->getL0KB1KBCnt ());
	  leakStat->append (sb.toString ());
	}
      if (hDataTotal->getL1KB8KBCnt () > 0)
	{
	  sb.sprintf (GTXT ("1KB - 8KB"));
	  leakStat->append (sb.toString ());
	  sb.sprintf (NTXT ("%d"), hDataTotal->getL1KB8KBCnt ());
	  leakStat->append (sb.toString ());
	}
      if (hDataTotal->getL8KB32KBCnt () > 0)
	{
	  sb.sprintf (GTXT ("8KB - 32KB"));
	  leakStat->append (sb.toString ());
	  sb.sprintf (NTXT ("%d"), hDataTotal->getL8KB32KBCnt ());
	  leakStat->append (sb.toString ());
	}
      if (hDataTotal->getL32KB128KBCnt () > 0)
	{
	  sb.sprintf (GTXT ("32KB - 128KB"));
	  leakStat->append (sb.toString ());
	  sb.sprintf (NTXT ("%d"), hDataTotal->getL32KB128KBCnt ());
	  leakStat->append (sb.toString ());
	}
      if (hDataTotal->getL128KB256KBCnt () > 0)
	{
	  sb.sprintf (GTXT ("128KB - 256KB"));
	  leakStat->append (sb.toString ());
	  sb.sprintf (NTXT ("%d"), hDataTotal->getL128KB256KBCnt ());
	  leakStat->append (sb.toString ());
	}
      if (hDataTotal->getL256KB512KBCnt () > 0)
	{
	  sb.sprintf (GTXT ("256KB - 512KB"));
	  leakStat->append (sb.toString ());
	  sb.sprintf (NTXT ("%d"), hDataTotal->getL256KB512KBCnt ());
	  leakStat->append (sb.toString ());
	}
      if (hDataTotal->getL512KB1000KBCnt () > 0)
	{
	  sb.sprintf (GTXT ("512KB - 1000KB"));
	  leakStat->append (sb.toString ());
	  sb.sprintf (NTXT ("%d"), hDataTotal->getL512KB1000KBCnt ());
	  leakStat->append (sb.toString ());
	}
      if (hDataTotal->getL1000KB10MBCnt () > 0)
	{
	  sb.sprintf (GTXT ("1000KB - 10MB"));
	  leakStat->append (sb.toString ());
	  sb.sprintf (NTXT ("%d"), hDataTotal->getL1000KB10MBCnt ());
	  leakStat->append (sb.toString ());
	}
      if (hDataTotal->getL10MB100MBCnt () > 0)
	{
	  sb.sprintf (GTXT ("10MB - 100MB"));
	  leakStat->append (sb.toString ());
	  sb.sprintf (NTXT ("%d"), hDataTotal->getL10MB100MBCnt ());
	  leakStat->append (sb.toString ());
	}
      if (hDataTotal->getL100MB1GBCnt () > 0)
	{
	  sb.sprintf (GTXT ("100MB - 1GB"));
	  leakStat->append (sb.toString ());
	  sb.sprintf (NTXT ("%d"), hDataTotal->getL100MB1GBCnt ());
	  leakStat->append (sb.toString ());
	}
      if (hDataTotal->getL1GB10GBCnt () > 0)
	{
	  sb.sprintf (GTXT ("1GB - 10GB"));
	  leakStat->append (sb.toString ());
	  sb.sprintf (NTXT ("%d"), hDataTotal->getL1GB10GBCnt ());
	  leakStat->append (sb.toString ());
	}
      if (hDataTotal->getL10GB100GBCnt () > 0)
	{
	  sb.sprintf (GTXT ("10GB - 100GB"));
	  leakStat->append (sb.toString ());
	  sb.sprintf (NTXT ("%d"), hDataTotal->getL10GB100GBCnt ());
	  leakStat->append (sb.toString ());
	}
      if (hDataTotal->getL100GB1TBCnt () > 0)
	{
	  sb.sprintf (GTXT ("100GB - 1TB"));
	  leakStat->append (sb.toString ());
	  sb.sprintf (NTXT ("%d"), hDataTotal->getL100GB1TBCnt ());
	  leakStat->append (sb.toString ());
	}
      if (hDataTotal->getL1TB10TBCnt () > 0)
	{
	  sb.sprintf (GTXT ("1TB - 10TB"));
	  leakStat->append (sb.toString ());
	  sb.sprintf (NTXT ("%d"), hDataTotal->getL1TB10TBCnt ());
	  leakStat->append (sb.toString ());
	}

      sb.sprintf (GTXT ("Smallest leaked bytes"));
      leakStat->append (sb.toString ());
      sb.sprintf (NTXT ("%d"), (int) (hDataTotal->getLSmallestBytes ()));
      leakStat->append (sb.toString ());

      sb.sprintf (GTXT ("Largest leaked bytes"));
      leakStat->append (sb.toString ());
      sb.sprintf (NTXT ("%d"), (int) (hDataTotal->getLLargestBytes ()));
      leakStat->append (sb.toString ());

      sb.sprintf (GTXT ("Total leaked"));
      leakStat->append (sb.toString ());
      sb.sprintf (NTXT ("%d"), (int) (hDataTotal->getLeakCnt ()));
      leakStat->append (sb.toString ());

      sb.sprintf (GTXT ("Total bytes"));
      leakStat->append (sb.toString ());
      sb.sprintf (NTXT ("%lld"), (long long) (hDataTotal->getLeakBytes ()));
      leakStat->append (sb.toString ());
    }
  Vector<Vector<char*>*>* statisticsData = new Vector<Vector<char*>*>(3);
  statisticsData->store (0, memoryUsage);
  statisticsData->store (1, allocStat);
  statisticsData->store (2, leakStat);
  return statisticsData;
}

Vector<char*> *
dbeGetFuncNames (int dbevindex, Vector<Obj> *funcs)
{
  int len = funcs->size ();
  Vector<char*> *list = new Vector<char*>(len);
  for (int i = 0; i < len; i++)
    list->store (i, dbeGetFuncName (dbevindex, funcs->fetch (i))); // no strdup()
  return list;
}

Vector<char*> *
dbeGetObjNamesV2 (int dbevindex, Vector<uint64_t> *ids)
{
  int len = ids->size ();
  Vector<char*> *list = new Vector<char*>(len);
  for (int i = 0; i < len; i++)
    list->store (i, dbeGetObjNameV2 (dbevindex, ids->fetch (i))); // no strdup()
  return list;
}

char *
dbeGetFuncName (int dbevindex, Obj func)
{
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  if (func == 0)
    return NULL;
  char *fname;
  fname = ((Histable *) func)->get_name (dbev->get_name_format ());
  return fname ? dbe_strdup (fname) : NULL;
}

Vector<uint64_t> *
dbeGetFuncIds (int dbevindex, Vector<Obj> *funcs)
{
  int len = funcs->size ();
  Vector<uint64_t> *list = new Vector<uint64_t>(len);
  for (int i = 0; i < len; i++)
    list->store (i, dbeGetFuncId (dbevindex, funcs->fetch (i)));
  return list;
}

uint64_t
dbeGetFuncId (int dbevindex, Obj func)
{
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  if (func == 0)
    return 0;
  uint64_t id = ((Histable *) func)->id;
  return id;
}

char *
dbeGetObjNameV2 (int dbevindex, uint64_t id)
{
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  Histable *obj = dbeSession->findObjectById (id);
  if (obj == NULL)
    return NULL;
  char *fname = obj->get_name (dbev->get_name_format ());
  return fname ? dbe_strdup (fname) : NULL;
}

char *
dbeGetDataspaceTypeDesc (int /*dbevindex*/, Obj stack)
{
  if (stack == 0)
    return NULL;
  Histable *hist = CallStack::getStackPC ((void *) stack, 0);
  DbeInstr *instr;
  Histable::Type type = hist->get_type ();
  if (type != Histable::INSTR)
    return NULL;
  else
    instr = (DbeInstr *) hist;
  char *descriptor = instr->get_descriptor ();
  return descriptor ? dbe_strdup (descriptor) : NULL;
}

Vector<void*> *
dbeGetDataDescriptorsV2 (int exp_id)
{
  Experiment *exp = dbeSession->get_exp (exp_id);
  if (exp == NULL)
    return NULL;
  Vector<int> *dataId = new Vector<int>;
  Vector<char*> *dataName = new Vector<char*>;
  Vector<char*> *dataUName = new Vector<char*>;
  Vector<int> *auxProp = new Vector<int>;
  Vector<DataDescriptor*> *ddscr = exp->getDataDescriptors ();
  for (int i = 0; i < ddscr->size (); i++)
    {
      DataDescriptor *dataDscr = ddscr->fetch (i);
      if (dataDscr->getFlags () & DDFLAG_NOSHOW)
	continue;
      int data_id = dataDscr->getId ();
      int aux_prop_id = (data_id == DATA_HWC) ? PROP_HWCTAG : PROP_NONE;
      dataId->append (data_id);
      dataName->append (strdup (dataDscr->getName ()));
      dataUName->append (strdup (dataDscr->getUName ()));
      auxProp->append (aux_prop_id);
    }
  delete ddscr;
  Vector<void*> *res = new Vector<void*>(3);
  res->store (0, dataId);
  res->store (1, dataName);
  res->store (2, dataUName);
  res->store (3, auxProp);
  return res;
}

Vector<void*> *
dbeGetDataPropertiesV2 (int exp_id, int data_id)
{
  Experiment *exp = dbeSession->get_exp (exp_id);
  if (exp == NULL)
    return NULL;
  DataDescriptor *dataDscr = exp->get_raw_events (data_id);
  if (dataDscr == NULL)
    return NULL;
  Vector<PropDescr*> *props = dataDscr->getProps ();
  Vector<int> *propId = new Vector<int>(props->size ());
  Vector<char*> *propUName = new Vector<char*>(props->size ());
  Vector<int> *propTypeId = new Vector<int>(props->size ());
  Vector<char*> *propTypeName = new Vector<char*>(props->size ());
  Vector<int> *propFlags = new Vector<int>(props->size ());
  Vector<char*> *propName = new Vector<char*>(props->size ());
  Vector<void*> *propStateNames = new Vector<void*>(props->size ());
  Vector<void*> *propStateUNames = new Vector<void*>(props->size ());

  for (int i = 0; i < props->size (); i++)
    {
      PropDescr *prop = props->fetch (i);
      char *pname = prop->name;
      if (pname == NULL)
	pname = NTXT ("");
      char *uname = prop->uname;
      if (uname == NULL)
	uname = pname;
      int vtypeNum = prop->vtype;
      if (vtypeNum < 0 || vtypeNum >= TYPE_LAST)
	vtypeNum = TYPE_NONE;
      const char * vtypeNames[] = VTYPE_TYPE_NAMES;
      const char *vtype = vtypeNames[prop->vtype];
      Vector<char*> *stateNames = NULL;
      Vector<char*> *stateUNames = NULL;
      int nStates = prop->getMaxState ();
      if (nStates > 0)
	{
	  stateNames = new Vector<char*>(nStates);
	  stateUNames = new Vector<char*>(nStates);
	  for (int kk = 0; kk < nStates; kk++)
	    {
	      const char * stateName = prop->getStateName (kk);
	      stateNames->store (kk, dbe_strdup (stateName));
	      const char * Uname = prop->getStateUName (kk);
	      stateUNames->store (kk, dbe_strdup (Uname));
	    }
	}
      propId->store (i, prop->propID);
      propUName->store (i, dbe_strdup (uname));
      propTypeId->store (i, prop->vtype);
      propTypeName->store (i, dbe_strdup (vtype));
      propFlags->store (i, prop->flags);
      propName->store (i, dbe_strdup (pname));
      propStateNames->store (i, stateNames);
      propStateUNames->store (i, stateUNames);
    }
  Vector<void*> *res = new Vector<void*>(7);
  res->store (0, propId);
  res->store (1, propUName);
  res->store (2, propTypeId);
  res->store (3, propTypeName);
  res->store (4, propFlags);
  res->store (5, propName);
  res->store (6, propStateNames);
  res->store (7, propStateUNames);
  return res;
}

Vector<void *> *
dbeGetExperimentTimeInfo (Vector<int> *exp_ids)
{
  int sz = exp_ids->size ();
  Vector<long long> *offset_time = new Vector<long long> (sz);
  Vector<long long> *start_time = new Vector<long long> (sz);
  Vector<long long> *end_time = new Vector<long long> (sz);
  Vector<long long> *start_wall_sec = new Vector<long long> (sz);
  Vector<char* > *hostname = new Vector<char*> (sz);
  Vector<int> *cpu_freq = new Vector<int> (sz);
  for (int ii = 0; ii < sz; ii++)
    {
      int expIdx = exp_ids->fetch (ii);
      { // update end_time by forcing fetch of experiment data
	// workaround until dbeGetEndTime() is more robust
	int id = (expIdx < 0) ? 0 : expIdx;
	Experiment *exp = dbeSession->get_exp (id);
	if (exp)
	  {
	    Vector<DataDescriptor*> *ddscr = exp->getDataDescriptors ();
	    delete ddscr;
	  }
      }
      offset_time->store (ii, dbeGetRelativeStartTime (0, expIdx));
      start_time->store (ii, dbeGetStartTime (0, expIdx));
      end_time->store (ii, dbeGetEndTime (0, expIdx));
      start_wall_sec->store (ii, dbeGetWallStartSec (0, expIdx));
      hostname->store (ii, dbeGetHostname (0, expIdx));
      cpu_freq->store (ii, dbeGetClock (0, expIdx));
    }
  Vector<void*> *res = new Vector<void*>(4);
  res->store (0, offset_time);
  res->store (1, start_time);
  res->store (2, end_time);
  res->store (3, start_wall_sec);
  res->store (4, hostname);
  res->store (5, cpu_freq);
  return res;
}

Vector<void *> *
dbeGetExperimentDataDescriptors (Vector<int> *exp_ids)
{
  int sz = exp_ids->size ();
  Vector<void*> *exp_dscr_info = new Vector<void*> (sz);
  Vector<void*> *exp_dscr_props = new Vector<void*> (sz);

  for (int ii = 0; ii < sz; ii++)
    {
      int expIdx = exp_ids->fetch (ii);
      Vector<void*> *ddscrInfo = dbeGetDataDescriptorsV2 (expIdx);
      Vector<void*> *ddscrProps = new Vector<void*> (); // one entry per ddscrInfo
      if (ddscrInfo)
	{
	  Vector<int> *dataId = (Vector<int>*)ddscrInfo->fetch (0);
	  if (dataId)
	    {
	      // loop thru data descriptors
	      int ndata = dataId->size ();
	      for (int j = 0; j < ndata; ++j)
		{
		  Vector<void*> *props = dbeGetDataPropertiesV2 (expIdx, dataId->fetch (j));
		  ddscrProps->store (j, props);
		}
	    }
	}
      exp_dscr_info->store (ii, ddscrInfo);
      exp_dscr_props->store (ii, ddscrProps);
    }
  Vector<void*> *res = new Vector<void*>(2);
  res->store (0, exp_dscr_info);
  res->store (1, exp_dscr_props);
  return res;
}

static Vector<void *> *
dbeGetTLDataRepVals (VMode view_mode, hrtime_t start_ts, hrtime_t delta,
		     int numDeltas, DataView*packets,
		     Vector<long> *representativeEvents, bool showDuration);

static bool
dbeHasTLData (int dbevindex, int exp_id, int data_id, int entity_prop_id,
	      int entity_prop_value, int aux)
{
  DataView *packets =
	  getTimelinePackets (dbevindex, exp_id, data_id, entity_prop_id);
  if (!packets || packets->getSize () == 0)
    return false;
  long start_ind = getIdxByVals (packets, aux, entity_prop_value,
				 0, DataView::REL_GTEQ); // time >= 0
  if (start_ind < 0)
    return false;

  DbeView *dbev = dbeSession->getView (dbevindex);
  VMode view_mode = dbev->get_view_mode ();
  Experiment *exp = dbeSession->get_exp (exp_id);
  if (!hasInvisbleTLEvents (exp, view_mode))
    return true; // all events are visible, no further checking required
  long end_ind = getIdxByVals (packets, aux, entity_prop_value,
			       MAX_TIME, DataView::REL_LTEQ);
  for (long ii = start_ind; ii <= end_ind; ii++)
    {
      if (!isVisibleTLEvent (exp, view_mode, packets, ii))
	continue;
      return true; // first visible packet => has data
    }
  return false;
}

Vector<bool> *
dbeHasTLData (int dbev_index, Vector<int> *exp_ids, Vector<int> *data_ids,
	      Vector<int> *entity_prop_ids, // LWP,CPU,THR, etc
	      Vector<int> *entity_prop_values, Vector<int> *auxs)
{
  DbeView *dbev = dbeSession->getView (dbev_index);
  if (!dbev->isShowAll () && (dbev->isShowHideChanged ()
			      || dbev->isNewViewMode ()))
    {
      // LIBRARY_VISIBILITY
      dbev->resetAndConstructShowHideStacks ();
      if (dbev->isNewViewMode ())
	dbev->resetNewViewMode ();
      if (dbev->isShowHideChanged ())
	dbev->resetShowHideChanged ();
    }

  int sz = exp_ids->size ();
  Vector<bool> *hasVec = new Vector<bool>(sz);
  for (int ii = 0; ii < sz; ii++)
    {
      bool hasData = dbeHasTLData (dbev_index, exp_ids->fetch (ii),
				   data_ids->fetch (ii),
				   entity_prop_ids->fetch (ii),
				   entity_prop_values->fetch (ii),
				   auxs->fetch (ii));
      hasVec->store (ii, hasData);
    }
  return hasVec;
}

/*
 *   dbeGetTLData implements:
 *   FROM data_id
 *     DURATION >= delta AND ( start_ts <= TSTAMP < start_ts+num*delta OR
 *                             start_ts <= TSTAMP-DURATION < start_ts+num*delta )
 *     OR
 *     FAIR( DURATION < delta AND ( start_ts <= TSTAMP < start_ts+num*delta ) )
 *     WHERE lfilter
 */

Vector<void *> *
dbeGetTLData (
	      int dbevindex,
	      int exp_id,
	      int data_id, // DATA_*
	      int entity_prop_id, // Show PROP_LWPID, PROP_CPUID, PROP_THRID, PROP_EXPID, or N/A
	      int entity_prop_value, // which LWPID, CPUID, THRID, EXPID for this request
	      int aux,
	      hrtime_t param_start_ts,
	      hrtime_t param_delta,
	      int param_numDeltas,
	      bool getRepresentatives, // fetch TL representatives
	      Vector<char *> *chartProps) // calculate sums for these property vals
{
  const hrtime_t start_ts = param_start_ts;
  const hrtime_t delta = param_delta;
  const int numDeltas = param_numDeltas;
  DbeView *dbev = dbeSession->getView (dbevindex);
  if (dbev == NULL)
    abort ();
  Experiment *exp = dbeSession->get_exp (exp_id);
  if (exp == NULL)
    return NULL;
  if (getRepresentatives == false && chartProps == NULL)
    return NULL;
  if (delta <= 0)
    return NULL;

  hrtime_t tmp_ts = start_ts + delta * numDeltas;
  if (tmp_ts < start_ts)
    tmp_ts = MAX_TIME;
  const hrtime_t end_ts = tmp_ts;
  if (exp->get_status () == Experiment::INCOMPLETE &&
      exp->getLastEvent () < end_ts)
    exp->update ();
  DataView *packets =
	  getTimelinePackets (dbevindex, exp_id, data_id, entity_prop_id);
  if (packets == NULL)
    return NULL; // strange, no data view?

  VMode view_mode = dbev->get_view_mode (); // user, expert, machine //YXXX yuck

  // storage for calculating timeline representative events
  Vector<long> *representativeEvents = NULL;
  // list of representative events to be displayed on TL
  Vector<int> *binRepIdx = NULL;
  // for each bin, index    of current "best" representativeEvent
  Vector<void*> *representativeVals = NULL;
  // TL representative packets' values

  // storage for calculating charts
  Vector<int> *propIds = NULL; // [propIdx], which prop to measure
  Vector<void*> *propVals = NULL; // [propIdx][bin], prop vals
  Vector<int> *propNumStates = NULL; // [propIdx], how many states for prop?
  Vector<bool> *propCumulativeChart = NULL; // [propIdx], data represents cumulative totals
  Vector<long long> *propCumulativeRecentBinLastVal = NULL; // [propIdx], most recent value
  Vector<long long> *propCumulativeRecentBinHighVal = NULL; // [propIdx], highest value for propCumulativeRecentBin
  Vector<int> *propCumulativeRecentBin = NULL; // [propIdx], most recent bin

  // determine when to show duration of events
  bool tmp_repsShowDuration = false;
  bool tmp_statesUseDuration = false;
  bool tmp_extendMicrostates = false;
  const hrtime_t ptimerTickDuration = exp->get_params ()->ptimer_usec * 1000LL; // nanoseconds per tick
  const bool hasDuration = packets->getProp (PROP_EVT_TIME) ? true : false;
  if (hasDuration)
    {
      switch (entity_prop_id)
	{
	case PROP_CPUID:
	  tmp_repsShowDuration = false;
	  tmp_statesUseDuration = false;
	  break;
	case PROP_THRID:
	case PROP_LWPID:
	  tmp_repsShowDuration = true;
	  tmp_statesUseDuration = true;
	  tmp_extendMicrostates = (DATA_CLOCK == data_id) && (ptimerTickDuration < param_delta);
	  break;
	case PROP_EXPID:
	case PROP_NONE: // experiment summary row uses this
	default:
	  if (DATA_SAMPLE == data_id)
	    {
	      tmp_repsShowDuration = true;
	      tmp_statesUseDuration = true;
	    }
	  else if (DATA_GCEVENT == data_id)
	    {
	      tmp_repsShowDuration = true;
	      tmp_statesUseDuration = true;
	    }
	  else if (DATA_CLOCK == data_id)
	    {
	      tmp_repsShowDuration = false;
	      tmp_statesUseDuration = true;
	      tmp_extendMicrostates = true;
	    }
	  else
	    {
	      tmp_repsShowDuration = false;
	      tmp_statesUseDuration = true;
	    }
	  break;
	}
    }
  const bool repsShowDuration = tmp_repsShowDuration; // show stretched callstacks
  const bool statesUseDuration = tmp_statesUseDuration; // use duration to calculate state charts
  const bool extendMicrostates = tmp_extendMicrostates; // we show discrete profiling microstates with
  // width=(tick-1), but for computing
  // zoomed-out graphs we need to extend to
  // account for all ticks, width=(ntick)
  const bool reverseScan = repsShowDuration || extendMicrostates; // scan packets in reverse

  // determine range of packet indices (lo_pkt_idx, hi_pkt_idx)
  long lo_pkt_idx, hi_pkt_idx;
  if (extendMicrostates && !(entity_prop_id == PROP_THRID || entity_prop_id == PROP_LWPID))
    {
      // merging data from multiple threads, need to scan all packets with timestamp [start_ts, exp end]
      hrtime_t exp_end_time = exp->getLastEvent () + 1;
      hi_pkt_idx = getIdxByVals (packets, aux, entity_prop_value,
				 exp_end_time, DataView::REL_LT); // last item
    }
  else
    hi_pkt_idx = getIdxByVals (packets, aux, entity_prop_value,
			       end_ts, DataView::REL_LT);
  if (repsShowDuration)
    {
      // There are two issues to deal with
      // 1. events that end "off screen" to the right
      // 2. overlapping events

      // 1. events that end "off screen" to the right
      // For now, we only consistently handle the case where events don't overlap.
      // Note that packet timestamps mark end of duration, not start.
      // This means that the rightmost event won't be within hi_pkt_idx.
      // Solution: Check if end+1 packet _started_ in-range
      // Caveat: because we only look ahead by one packet, if there are
      // overlapping duration events (e.g. EXPID aggregation)), zoom level
      // and panning combo may cause events with TSTAMP>end_ts
      // to appear/disappear.  A complete solution would involve
      // a solution to 2.

      // 2. overlapping events
      // For now, we have a simplistic solution that makes "wide" events win.  However,
      // a future solution for deterministically dealing with overlap might look like this:
      // - find all packets that touch the visible time range
      //   - possibly use two DataViews: one with TSTAMP_HI sort and one with TSTAMP_LO
      //     sort to allow efficient determination of packets with HI and LO endpoints in-range
      // - create buckets to  capture "winning" event for each bin (each pixel, that is)
      // - sort the new list of packets by TSTAMP_HI (for example)
      // - looping thru the packets that are in-range, update every bin it touches with it's id
      // - if there is overlap, earlier packets will be kicked out of bins
      // - On the GUI side, paint one event at a time, as normal.
      // - However, for selections, recognize that duration of event may span many bins
      //
      long idx;
      if (hi_pkt_idx >= 0)
	// a packet was found to the left of the end time
	idx = hi_pkt_idx + 1; // attempt to go one packet right
      else
	idx = getIdxByVals (packets, aux, entity_prop_value,
			    end_ts, DataView::REL_GTEQ);
      if (isValidIdx (packets, entity_prop_id, aux, entity_prop_value, idx))
	{
	  int64_t pkt_ts = packets->getLongValue (PROP_TSTAMP, idx);
	  int64_t duration = packets->getLongValue (PROP_EVT_TIME, idx);
	  pkt_ts -= duration;
	  if (pkt_ts < end_ts)
	    hi_pkt_idx = idx;
	}
    }
  lo_pkt_idx = getIdxByVals (packets, aux, entity_prop_value,
			     start_ts, DataView::REL_GTEQ);

  // allocate structs that return chart data
  bool hasCumulativeCharts = false;
  if (chartProps && chartProps->size () > 0)
    {
      int nprops = chartProps->size ();
      // pre-allocate storage
      propIds = new Vector<int> (nprops);
      propVals = new Vector<void*>(nprops);
      propNumStates = new Vector<int> (nprops);
      propCumulativeChart = new Vector<bool>(nprops);
      propCumulativeRecentBinLastVal = new Vector<long long>(nprops);
      propCumulativeRecentBinHighVal = new Vector<long long>(nprops);
      propCumulativeRecentBin = new Vector<int>(nprops);
      for (int propNum = 0; propNum < nprops; propNum++)
	{
	  const char* propStr = chartProps->fetch (propNum);
	  int items_per_prop = 0;
	  int prop_id = PROP_NONE;
	  if (!strcmp (propStr, "EVT_COUNT"))
	    items_per_prop = 1; // use PROP_NONE for counting packets
	  else
	    {
	      int lookup_prop_id = dbeSession->getPropIdByName (propStr);
	      PropDescr *propDscr = packets->getProp (lookup_prop_id);
	      if (propDscr != NULL)
		{
		  switch (propDscr->vtype)
		    {
		    case TYPE_INT32:
		    case TYPE_UINT32:
		    case TYPE_INT64:
		    case TYPE_UINT64:
		      items_per_prop = propDscr->getMaxState () + 1;
		      // add extra slot to store values with out-of-range idx
		      prop_id = lookup_prop_id;
		      break;
		    case TYPE_DOUBLE:
		      break; // not implemented yet
		    case TYPE_STRING:
		    case TYPE_OBJ:
		    case TYPE_DATE:
		    default:
		      break;
		    }
		}
	    }
	  void *vals;
	  if (!items_per_prop)
	    vals = NULL;
	  else if (items_per_prop == 1)
	    {
	      Vector<long long> *longVals = new Vector<long long> ();
	      longVals->store (numDeltas - 1, 0); // initialize all elements
	      vals = longVals;
	    }
	  else
	    {
	      Vector<Vector<long long>*> *stateVals =
		      new Vector<Vector<long long>*> ();
	      vals = stateVals;
	      // initialize only on-demand, some may not be needed
	    }

	  bool isCumulativeChart;
#define YXXX_HEAP_VS_TIME 1 // YXXX add data meaning to properties?
#if YXXX_HEAP_VS_TIME
	  isCumulativeChart = (prop_id == PROP_HCUR_LEAKS || prop_id == PROP_HCUR_ALLOCS);
#endif
	  if (isCumulativeChart)
	    hasCumulativeCharts = true;
	  propIds->store (propNum, prop_id);
	  propVals->store (propNum, vals);
	  propNumStates->store (propNum, items_per_prop);
	  propCumulativeRecentBinLastVal->store (propNum, 0);
	  propCumulativeRecentBinHighVal->store (propNum, 0);
	  propCumulativeRecentBin->store (propNum, 0);
	  propCumulativeChart->store (propNum, isCumulativeChart);
	}
    }

  // Adjust idx range for calculating 'cumulative charts' e.g. heap size
  if (hasCumulativeCharts)
    {
      // set initial values if earlier packet exists
      long lo_idx;
      if (lo_pkt_idx >= 0)
	// packet was found to the right of start
	lo_idx = lo_pkt_idx - 1; // attempt to go left by one event
      else
	// no packet was to the right of start, look left of start
	lo_idx = getIdxByVals (packets, aux, entity_prop_value,
			       start_ts, DataView::REL_LT);
      if (isValidIdx (packets, entity_prop_id, aux, entity_prop_value, lo_idx))
	{
	  // preceding packet found
	  // update initial values
	  int nprops = propCumulativeChart->size ();
	  for (int propNum = 0; propNum < nprops; propNum++)
	    {
	      if (!propCumulativeChart->fetch (propNum))
		continue;
	      int propId = propIds->fetch (propNum);
	      long long value = packets->getLongValue (propId, lo_idx);
	      propCumulativeRecentBinLastVal->store (propNum, value);
	      propCumulativeRecentBinHighVal->store (propNum, value);
	    }
	  // update indices used for iterating
	  lo_pkt_idx = lo_idx;
	  if (hi_pkt_idx < lo_pkt_idx)
	    hi_pkt_idx = lo_pkt_idx;
	}
    }
  if (lo_pkt_idx < 0 || hi_pkt_idx < 0)
    goto dbeGetTLData_done; // no data; return empty vectors, not null

  // representative events (subset of callstacks to represent on TL)
  if (getRepresentatives)
    {
      representativeEvents = new Vector<long>(numDeltas);
      // per-bin, longest event's index
      binRepIdx = new Vector<int>(numDeltas);
      for (int ii = 0; ii < numDeltas; ++ii)
	binRepIdx->append (-1);
    }
  // While packets are sorted by _end_ timestamp (TSTAMP),
  // after calculating start times for non-zero durations,
  // start times are not guaranteed be monotonically increasing.
  // For packets with duration, we'll scan them in reverse order to
  // take advantage of the monotonically decreasing _end_ timestamps.
  long start_idx, idx_inc;
  if (!reverseScan)
    {
      start_idx = lo_pkt_idx;
      idx_inc = 1;
    }
  else
    {
      start_idx = hi_pkt_idx;
      idx_inc = -1;
    }
  for (long ii = start_idx; ii >= lo_pkt_idx && ii <= hi_pkt_idx; ii += idx_inc)
    {
      if (!isVisibleTLEvent (exp, view_mode, packets, ii) && !hasCumulativeCharts)
	continue;

      // determine packet time duration and start bin
      int tmp_start_bin; // packet start bin
      int tmp_end_bin; // packet end bin (inclusive)
      const hrtime_t pkt_end_ts = packets->getLongValue (PROP_TSTAMP, ii);
      const hrtime_t pkt_dur = packets->getLongValue (PROP_EVT_TIME, ii);
      const hrtime_t pkt_start_ts = pkt_end_ts - pkt_dur;
      if (pkt_end_ts < start_ts && !hasCumulativeCharts)
	continue; // weird, should not happen
      if (pkt_start_ts >= end_ts)
	continue; // could happen
      hrtime_t bin_end_ts = pkt_end_ts;
      if (bin_end_ts >= end_ts)
	bin_end_ts = end_ts - 1;
      tmp_end_bin = (int) ((bin_end_ts - start_ts) / delta);
      hrtime_t bin_start_ts = pkt_start_ts;
      if (bin_start_ts < start_ts)
	bin_start_ts = start_ts; // event truncated to left.
      tmp_start_bin = (int) ((bin_start_ts - start_ts) / delta);
      // By definition
      //   (end_ts - start_ts) == delta * numDeltas
      // and we know
      //   pkt_start < end_ts
      // therefore
      //   (pkt_start - start_ts) < delta * numDeltas
      //   (pkt_start - start_ts) / delta < numDeltas
      //   bin < numDeltas
      assert (tmp_end_bin < numDeltas);
      assert (tmp_start_bin < numDeltas);
      const bool is_offscreen = tmp_end_bin < 0 ? true : false;
      if (tmp_end_bin < 0)
	tmp_end_bin = 0;
      const int pkt_end_bin = tmp_end_bin; // packet end bin (inclusive)
      const int pkt_start_bin = tmp_start_bin;
      if (getRepresentatives && !is_offscreen)
	{ // find best representative
	  // Note: for events with duration, we're scanning packets in order
	  // of decreasing end-timestamp.  This means that the first packet
	  // that hits a particular _start_ bin will have the longest duration
	  // of any later packet that might hit that start bin.  The
	  // the first packet will be the best (longest) packet.
	  const int bin = reverseScan ? pkt_start_bin : pkt_end_bin;
	  int eventIdx = binRepIdx->fetch (bin);
	  if (eventIdx == -1)
	    {
	      eventIdx = representativeEvents->size (); // append to end
	      representativeEvents->append (ii);
	      binRepIdx->store (bin, eventIdx);
	    }
	}
      if (propIds)
	{ // per-bin chart: sum across filtered packets
	  for (int propNum = 0; propNum < propIds->size (); propNum++)
	    {
	      void *thisProp = propVals->fetch (propNum);
	      if (thisProp == NULL)
		continue; // no valid data
	      if (is_offscreen && !propCumulativeChart->fetch (propNum))
		continue; // offscreen events are only processed for cumulative charts
	      int propId = propIds->fetch (propNum);
	      long long val;
	      if (propId == PROP_NONE)
		val = 1; // count
	      else
		val = packets->getLongValue (propId, ii);
	      long nitems = propNumStates->fetch (propNum);
	      if (nitems < 1)
		continue;
	      else if (nitems == 1)
		{
		  // chart is not based on not multiple states
		  Vector<long long>* thisPropVals =
			  (Vector<long long>*)thisProp;
		  if (thisPropVals->size () == 0)
		    thisPropVals->store (numDeltas - 1, 0);
		  const int bin = statesUseDuration ? pkt_start_bin : pkt_end_bin;
		  if (!propCumulativeChart->fetch (propNum))
		    {
		      val += thisPropVals->fetch (bin);
		      thisPropVals->store (bin, val);
		    }
		  else
		    {
		      // propCumulativeChart
		      long long high_value = propCumulativeRecentBinHighVal->fetch (propNum);
		      int last_bin = propCumulativeRecentBin->fetch (propNum);
		      if (last_bin < bin)
			{
			  // backfill from previous event
			  // last_bin: store largest value (in case of multiple events)
			  thisPropVals->store (last_bin, high_value);
			  // propagate forward the bin's last value
			  long long last_value = propCumulativeRecentBinLastVal->fetch (propNum);
			  for (int kk = last_bin + 1; kk < bin; kk++)
			    thisPropVals->store (kk, last_value);
			  // prepare new bin for current event
			  high_value = 0; // high value of next bin is 0.
			  propCumulativeRecentBinHighVal->store (propNum, high_value);
			  propCumulativeRecentBin->store (propNum, bin);
			}
		      long long this_value = packets->getLongValue (propId, ii);
		      propCumulativeRecentBinLastVal->store (propNum, this_value);
		      if (high_value < this_value)
			{
			  // record the max
			  high_value = this_value;
			  propCumulativeRecentBinHighVal->store (propNum, high_value);
			}
		      if (ii == hi_pkt_idx)
			{
			  // bin: show largest value (in case of multiple events
			  thisPropVals->store (bin, high_value);
			  //forward fill remaining bins
			  for (int kk = bin + 1; kk < numDeltas; kk++)
			    thisPropVals->store (kk, this_value);
			}
		    }
		}
	      else
		{
		  // means val is actually a state #
		  Vector<Vector<long long>*>* thisPropStateVals =
			  (Vector<Vector<long long>*>*)thisProp;
		  if (thisPropStateVals->size () == 0)
		    thisPropStateVals->store (numDeltas - 1, 0);
		  long stateNum;
		  if (val >= 0 && val < nitems)
		    stateNum = (long) val;
		  else
		    stateNum = nitems - 1; // out of range, use last slot
		  hrtime_t graph_pkt_dur = pkt_dur;
		  hrtime_t graph_pkt_start_ts = pkt_start_ts;
		  int tmp2_start_bin = pkt_start_bin;
		  if (propId == PROP_MSTATE)
		    {
		      if (statesUseDuration && extendMicrostates)
			{
			  // microstate stacks are shown and filtered with width=NTICK-1
			  // but for microstate graph calcs use width=NTICK.
			  graph_pkt_dur += ptimerTickDuration;
			  graph_pkt_start_ts -= ptimerTickDuration;
			  hrtime_t bin_start_ts = graph_pkt_start_ts;
			  if (bin_start_ts < start_ts)
			    bin_start_ts = start_ts; // event truncated to left.
			  tmp2_start_bin = (int) ((bin_start_ts - start_ts) / delta);
			}
		    }
		  const int graph_pkt_start_bin = statesUseDuration ? tmp2_start_bin : pkt_end_bin;

		  // We will distribute the state's presence evenly over duration of the event.
		  // When only a 'partial bin' is touched by an event, adjust accordingly.
		  long long value_per_bin; // weight to be applied to each bin
		  {
		    long long weight;
		    if (propId == PROP_MSTATE)  // ticks to nanoseconds
		      weight = packets->getLongValue (PROP_NTICK, ii) * ptimerTickDuration;
		    else if (graph_pkt_dur)
		      weight = graph_pkt_dur; // nanoseconds
		    else
		      weight = 1; // no duration; indicate presence
		    if (graph_pkt_start_bin != pkt_end_bin)
		      {
			// spans multiple bins
			double nbins = (double) graph_pkt_dur / delta;
			value_per_bin = weight / nbins;
		      }
		    else
		      value_per_bin = weight;
		  }
		  for (int evtbin = graph_pkt_start_bin; evtbin <= pkt_end_bin; evtbin++)
		    {
		      Vector<long long>* stateValues =
			      (Vector<long long>*) thisPropStateVals->fetch (evtbin);
		      if (stateValues == NULL)
			{
			  // on-demand storage
			  stateValues = new Vector<long long>(nitems);
			  stateValues->store (nitems - 1, 0); // force memset of full vector
			  thisPropStateVals->store (evtbin, stateValues);
			}
		      long long new_val = stateValues->fetch (stateNum);
		      if (graph_pkt_start_bin == pkt_end_bin ||
			  (evtbin > graph_pkt_start_bin && evtbin < pkt_end_bin))
			{
			  new_val += value_per_bin;
			}
		      else
			{
			  // partial bin
			  const hrtime_t bin_start = start_ts + evtbin * delta;
			  const hrtime_t bin_end = start_ts + (evtbin + 1) * delta - 1;
			  if (evtbin == graph_pkt_start_bin)
			    {
			      // leftmost bin
			      if (graph_pkt_start_ts < bin_start)
				new_val += value_per_bin;
			      else
				{
				  double percent = (double) (bin_end - graph_pkt_start_ts) / delta;
				  new_val += value_per_bin*percent;
				}
			    }
			  else
			    {
			      // rightmost bin
			      if (pkt_end_ts > bin_end)
				new_val += value_per_bin;
			      else
				{
				  double percent = (double) (pkt_end_ts - bin_start) / delta;
				  new_val += value_per_bin*percent;
				}
			    }
			}
		      stateValues->store (stateNum, new_val);
		    }
		}
	    }
	}
    }
  delete binRepIdx;
  delete propIds;
  delete propCumulativeChart;
  delete propCumulativeRecentBinLastVal;
  delete propCumulativeRecentBinHighVal;
  delete propCumulativeRecentBin;
  if (representativeEvents != NULL && reverseScan)
    {
      if (repsShowDuration)
	{
	  //YXXX for now prune here, but in the future, let gui decide what to show
	  // Prune events that are completely obscured long duration events.
	  // Note: representativeEvents is sorted by decreasing _end_ timestamps.
	  Vector<long> *prunedEvents = new Vector<long>(numDeltas);
	  hrtime_t prev_start_ts = MAX_TIME;
	  long repCnt = representativeEvents->size ();
	  for (long kk = 0; kk < repCnt; kk++)
	    {
	      long ii = representativeEvents->fetch (kk);
	      hrtime_t tmp_end_ts = packets->getLongValue (PROP_TSTAMP, ii);
	      hrtime_t tmp_dur = packets->getLongValue (PROP_EVT_TIME, ii);
	      hrtime_t tmp_start_ts = tmp_end_ts - tmp_dur;
	      if (tmp_start_ts >= prev_start_ts)
		// this event would be completely hidden
		// (because of sorting, we know tmp_end_ts <= prev_end_ts)
		continue;
	      prev_start_ts = tmp_start_ts;
	      prunedEvents->append (ii);
	    }
	  // invert order to to get increasing _end_ timestamps
	  representativeEvents->reset ();
	  for (long kk = prunedEvents->size () - 1; kk >= 0; kk--)
	    {
	      long packet_idx = prunedEvents->fetch (kk);
	      representativeEvents->append (packet_idx);
	    }
	  delete prunedEvents;
	}
      else
	{ // !repsShowDuration
	  // Note: representativeEvents is sorted by decreasing _end_ timestamps.
	  // Reverse the order:
	  long hi_idx = representativeEvents->size () - 1;
	  long lo_idx = 0;
	  while (hi_idx > lo_idx)
	    {
	      // swap
	      long lo = representativeEvents->fetch (lo_idx);
	      long hi = representativeEvents->fetch (hi_idx);
	      representativeEvents->store (lo_idx, hi);
	      representativeEvents->store (hi_idx, lo);
	      hi_idx--;
	      lo_idx++;
	    }
	}
    }

dbeGetTLData_done:
  if (getRepresentatives)
    {
      representativeVals = dbeGetTLDataRepVals (view_mode, start_ts, delta,
		    numDeltas, packets, representativeEvents, repsShowDuration);
      delete representativeEvents;
    }
  Vector<void*> *results = new Vector<void*> (2);
  results->store (0, representativeVals);
  results->store (1, propVals);
  return results;
}

// add representative events to return buffer

static Vector<void *> *
dbeGetTLDataRepVals (VMode view_mode, hrtime_t start_ts, hrtime_t delta,
		     int numDeltas, DataView*packets,
		     Vector<long> *representativeEvents, bool showDuration)
{
  int numrecs = representativeEvents ? representativeEvents->size () : 0;
  // allocate storage for results
  Vector<int> *startBins = new Vector<int>(numrecs);
  Vector<int> *numBins = new Vector<int>(numrecs);
  Vector<Obj> *eventIdxs = new Vector<Obj>(numrecs);
  Vector<Obj> *stackIds = NULL;
  if (packets->getProp (PROP_FRINFO))
    stackIds = new Vector<Obj>(numrecs);
  Vector<int> *mstates = NULL;
  if (packets->getProp (PROP_MSTATE))
    mstates = new Vector<int>(numrecs);
  Vector<Vector<long long>*> *sampleVals = NULL;
  if (packets->getProp (PROP_SMPLOBJ))
    sampleVals = new Vector<Vector<long long>*>(numrecs);
  Vector<long long> *timeStart = new Vector<long long>(numrecs);
  Vector<long long> *timeEnd = new Vector<long long>(numrecs);
  int prevEndBin = -1; // make sure we don't overlap bins
  for (int eventIdx = 0; eventIdx < numrecs; eventIdx++)
    {
      long packetIdx = representativeEvents->fetch (eventIdx);
      // long eventId = packets->getIdByIdx( packetIdx );
      const hrtime_t pkt_tstamp = packets->getLongValue (PROP_TSTAMP, packetIdx);
      const hrtime_t pkt_dur = showDuration ? packets->getLongValue (PROP_EVT_TIME, packetIdx) : 0;
      timeStart->store (eventIdx, pkt_tstamp - pkt_dur);
      timeEnd->store (eventIdx, pkt_tstamp);

      // calc startBin
      int startBin = (int) ((pkt_tstamp - pkt_dur - start_ts) / delta);
      if (startBin <= prevEndBin)
	startBin = prevEndBin + 1;
      // calc binCnt
      int endBin = (int) ((pkt_tstamp - start_ts) / delta);
      if (endBin >= numDeltas)
	endBin = numDeltas - 1;
      int binCnt = endBin - startBin + 1;
      prevEndBin = endBin;
      startBins->store (eventIdx, startBin);
      numBins->store (eventIdx, binCnt);
      eventIdxs->store (eventIdx, packetIdx); // store packet's idx
      if (stackIds != NULL)
	{
	  void* stackId = getStack (view_mode, packets, packetIdx);
	  stackIds->store (eventIdx, (Obj) (unsigned long) stackId);
	}
      if (mstates != NULL)
	{
	  int mstate = packets->getIntValue (PROP_MSTATE, packetIdx);
	  mstates->store (eventIdx, mstate);
	}
      if (sampleVals != NULL)
	{
	  Sample* sample = (Sample*) packets->getObjValue (PROP_SMPLOBJ, packetIdx);
	  if (!sample || !sample->get_usage ())
	    sample = sample;
	  else
	    {
	      PrUsage* prusage = sample->get_usage ();
	      Vector<long long> *mstateVals = prusage->getMstateValues ();
	      sampleVals->store (eventIdx, mstateVals);
	    }
	}
    }
  // caller responsible for: delete representativeEvents;
  Vector<void*> *results = new Vector<void*> (8);
  results->store (0, startBins);
  results->store (1, numBins);
  results->store (2, eventIdxs);
  results->store (3, stackIds);
  results->store (4, mstates);
  results->store (5, sampleVals);
  results->store (6, timeStart);
  results->store (7, timeEnd);
  return results;
}

// starting from <event_id> packet idx, step <move_count> visible events
// return the resulting idx and that packet's center time, or null if no event.
Vector<long long> *
dbeGetTLEventCenterTime (int dbevindex, int exp_id, int data_id,
			 int entity_prop_id, int entity_prop_val, int aux,
			 long long event_id, long long move_count)
{
  DataView *packets = getTimelinePackets (dbevindex, exp_id, data_id,
					  entity_prop_id);
  if (packets == NULL)
    return NULL;
  long idx = (long) event_id;

  DbeView *dbev = dbeSession->getView (dbevindex);
  VMode view_mode = dbev->get_view_mode ();
  Experiment *exp = dbeSession->get_exp (exp_id);
  int direction;
  if (move_count == 0)
    direction = 0;
  else if (move_count < 0)
    {
      move_count = -move_count;
      direction = -1;
    }
  else
    direction = 1;
  idx = getTLVisibleIdxByStepping (exp, view_mode, entity_prop_id, packets, aux,
				   entity_prop_val, idx, move_count, direction);
  if (idx >= 0)
    {
      long long ts = packets->getLongValue (PROP_TSTAMP, idx);
      long long dur = packets->getLongValue (PROP_EVT_TIME, idx);
      long long center = ts - dur / 2;
      Vector<long long> *results = new Vector<long long> (2);
      results->store (0, idx); // result idx
      results->store (1, center); // result timestamp
      return results;
    }
  return NULL;
}

long long
dbeGetTLEventIdxNearTime (int dbevindex, int exp_id, int data_id,
			  int entity_prop_id, int entity_prop_val, int aux,
			  int searchDirection, long long tstamp)
{
  DataView *packets = getTimelinePackets (dbevindex, exp_id, data_id,
					  entity_prop_id);
  if (packets == NULL)
    return -1;
  DbeView *dbev = dbeSession->getView (dbevindex);
  VMode view_mode = dbev->get_view_mode ();
  Experiment *exp = dbeSession->get_exp (exp_id);
  if (searchDirection < 0)
    {
      int idx = getTLVisibleIdxByVals (exp, view_mode, entity_prop_id,
				       packets, aux, entity_prop_val, tstamp,
				       DataView::REL_LTEQ);
      if (idx != -1)
	return idx;
      searchDirection = 1; // couldn't find to left, try to right
    }
  if (searchDirection > 0)
    {
      int idx = getTLVisibleIdxByVals (exp, view_mode, entity_prop_id,
				       packets, aux, entity_prop_val, tstamp,
				       DataView::REL_GTEQ);
      if (idx != -1)
	return idx;
      // couldn't find to right, fall through to generic
    }
  // search left and right of timestamp
  long idx1, idx2;
  idx1 = getTLVisibleIdxByVals (exp, view_mode, entity_prop_id,
				packets, aux, entity_prop_val, tstamp,
				DataView::REL_LT);
  idx2 = getTLVisibleIdxByVals (exp, view_mode, entity_prop_id,
				packets, aux, entity_prop_val, tstamp,
				DataView::REL_GTEQ);
  if (idx1 == -1)
    return idx2;
  else if (idx2 == -1)
    return idx1;

  // both valid, so need to compare to see which is closer
  long long t1 = packets->getLongValue (PROP_TSTAMP, idx1);
  long long t2 = packets->getLongValue (PROP_TSTAMP, idx2);
  long long t2dur = packets->getLongValue (PROP_EVT_TIME, idx2);
  long long delta1 = tstamp - t1; // should always be positive
  long long delta2 = (t2 - t2dur) - tstamp; // if negative, overlaps idx1
  if (delta1 > delta2)
    return idx2;
  else
    return idx1;
}

enum Aggr_type
{
  AGGR_NONE,
  AGGR_FAIR,
  AGGR_MAX,
  AGGR_MIN,
  AGGR_CNT,
  AGGR_SUM,
  AGGR_AVG
};

static Aggr_type
getAggrFunc (char *aname)
{
  Aggr_type agrfn = AGGR_NONE;
  if (aname == NULL)
    return agrfn;
  if (strcmp (aname, NTXT ("FAIR")) == 0)
    agrfn = AGGR_FAIR;
  else if (strcmp (aname, NTXT ("MAX")) == 0)
    agrfn = AGGR_MAX;
  else if (strcmp (aname, NTXT ("MIN")) == 0)
    agrfn = AGGR_MIN;
  else if (strcmp (aname, NTXT ("CNT")) == 0)
    agrfn = AGGR_CNT;
  else if (strcmp (aname, NTXT ("SUM")) == 0)
    agrfn = AGGR_SUM;
  else if (strcmp (aname, NTXT ("AVG")) == 0)
    agrfn = AGGR_AVG;
  return agrfn;
}

static long long
computeAggrVal (DefaultMap<long long, long long> *fval_map, Aggr_type agrfn)
{
  long long aval = 0;
  long cnt = 0;
  Vector<long long> *fvals = fval_map->values ();
  long nvals = fvals->size ();
  for (int i = 0; i < nvals; ++i)
    {
      long long val = fvals->fetch (i);
      switch (agrfn)
	{
	case AGGR_FAIR:
	  aval = val;
	  break;
	case AGGR_MAX:
	  if (aval < val || cnt == 0)
	    aval = val;
	  break;
	case AGGR_MIN:
	  if (aval > val || cnt == 0)
	    aval = val;
	  break;
	case AGGR_CNT:
	  aval = cnt + 1;
	  break;
	case AGGR_SUM:
	case AGGR_AVG:
	  aval += val;
	  break;
	case AGGR_NONE:
	  break;
	}
      if (agrfn == AGGR_FAIR)
	break;
      cnt += 1;
    }

  // Finalize aggregation
  if (agrfn == AGGR_AVG)
    if (cnt > 0)
      aval = (aval + cnt / 2) / cnt;
  delete fvals;
  return aval;
}

Vector<long long> *
dbeGetAggregatedValue (int data_id, // data table id
		       char *lfilter, // local filter
		       char *fexpr, // function expression
		       char *pname_ts, // property name for timestamp
		       hrtime_t start_ts, // start of the first time interval
		       hrtime_t delta, // time interval length
		       int num, // number of time intervals
		       char *pname_key, // property name for aggregation key
		       char *aggr_func) // aggregation function
{
  Vector<long long> *res = new Vector<long long>;
  Experiment *exp = dbeSession->get_exp (0);
  if (exp == NULL)
    return res;
  hrtime_t end_ts = start_ts + delta * num;
  if (end_ts < start_ts)    // check overflow
    end_ts = MAX_TIME;

  if (exp->get_status () == Experiment::INCOMPLETE
      && exp->getLastEvent () < end_ts)
    exp->update ();

  DataDescriptor *dataDscr = exp->get_raw_events (data_id);
  if (dataDscr == NULL)
    return res;

  // Process timestamp argument
  int prop_ts = dbeSession->getPropIdByName (pname_ts);
  if (prop_ts == PROP_NONE)
    return res;
  assert (prop_ts == -1);

  // Parse all expressions
  Expression *flt_expr = NULL;
  if (lfilter != NULL)
    flt_expr = dbeSession->ql_parse (lfilter);
  Expression *func_expr = NULL;
  if (fexpr != NULL)
    func_expr = dbeSession->ql_parse (fexpr);
  if (func_expr == NULL)   // Not specified or malformed
    return res;

  // Process aggregation key argument
  int prop_key = PROP_NONE;
  Data *data_key = NULL;
  if (pname_key != NULL)
    {
      prop_key = dbeSession->getPropIdByName (pname_key);
      data_key = dataDscr->getData (prop_key);
      if (data_key == NULL)   // Specified but not found
	return res;
    }

  // Process aggregation function argument
  Aggr_type agrfn = AGGR_FAIR;
  if (aggr_func != NULL)
    {
      agrfn = getAggrFunc (aggr_func);
      if (agrfn == AGGR_NONE) // Specified but not recognized
	return res;
    }
  DefaultMap<long long, long long> *
	fval_map = new DefaultMap<long long, long long>; // key_val -> func_val
  Vector<long long> *key_set = NULL;
  assert (key_set != NULL);
  if (key_set == NULL)
    {
      key_set = new Vector<long long>;
      key_set->append (0L);
    }
  DefaultMap<long long, int> *key_seen = new DefaultMap<long long, int>;
  long idx_prev = -1;
  for (int tidx = 0; tidx < num; ++tidx)
    {
      long idx_cur = -1;
      assert (idx_cur != -1);
      int left = key_set->size ();
      key_seen->clear ();
      for (long idx = idx_cur; idx > idx_prev; --idx)
	{
	  long id = 0;
	  assert (id != 0);

	  // Pre-create expression context
	  Expression::Context ctx (dbeSession->getView (0), exp, NULL, id);
	  // First use the filter
	  if (flt_expr != NULL)
	    if (flt_expr->eval (&ctx) == 0)
	      continue;

	  // Calculate the key
	  // keys are limited to integral values
	  long long key = 0;
	  if (data_key != NULL)
	    key = data_key->fetchLong (id);

	  // Check if already seen
	  if (key_seen->get (key) == 1)
	    continue;
	  key_seen->put (key, 1);
	  left -= 1;

	  // Calculate function value
	  // function values are limited to integral values
	  long long fval = func_expr->eval (&ctx);
	  fval_map->put (key, fval);
	  if (left == 0)
	    break;
	}
      idx_prev = idx_cur;
      long long aval = computeAggrVal (fval_map, agrfn);
      res->store (tidx, aval);
    }
  delete key_seen;
  delete fval_map;
  delete flt_expr;
  delete func_expr;
  return res;
}

Vector<char*> *
dbeGetLineInfo (Obj pc)
{
  DbeInstr *instr = (DbeInstr*) pc;
  if (instr == NULL || instr->get_type () != Histable::INSTR)
    return NULL;
  DbeLine *dbeline = (DbeLine*) instr->convertto (Histable::LINE);
  const char *fname = dbeline ? dbeline->sourceFile->get_name () : NTXT ("");
  char lineno[16];
  *lineno = '\0';
  if (dbeline != NULL)
    snprintf (lineno, sizeof (lineno), NTXT ("%d"), dbeline->lineno);
  Vector<char*> *res = new Vector<char*>(2);
  res->store (0, strdup (fname));
  res->store (1, strdup (lineno));
  return res;
}

int
dbeSetAlias (char *name, char *uname, char *expr)
{
  char *res = dbeSession->indxobj_define (name, uname, expr, NULL, NULL);
  return res == NULL ? 0 : 1;
}

Vector<char*> *
dbeGetAlias (char *name)
{
  Vector<char*> *res = new Vector<char*>;
  int idx = dbeSession->findIndexSpaceByName (name);
  if (idx >= 0)
    {
      char *str = dbeSession->getIndexSpaceDescr (idx);
      res->append (dbe_strdup (str));
      str = dbeSession->getIndexSpaceExprStr (idx);
      res->append (dbe_strdup (str));
    }
  return res;
}

static int
key_cmp (const void *p1, const void *p2)
{
  long long ll1 = *(long long*) p1;
  long long ll2 = *(long long*) p2;
  return ll1 < ll2 ? -1 : ll1 > ll2 ? 1 : 0;
}

Vector<Vector<long long>*> *
dbeGetXYPlotData (
		  int data_id, // data table id
		  char *lfilter, // local filter expression
		  char *arg, // name for the argument
		  char *func1, // expression for the first axis (x)
		  char *aggr1, // aggregation function for func1: "SUM","CNT",...
		  char *func2, // expression for the second axis (y)
		  char *aggr2, // aggregation function for func2
		  char *func3, // expression for the third axis (color)
		  char *aggr3) // aggregation function for func3
{
  Vector<Vector<long long>*> *res = new Vector<Vector<long long>*>;
  Experiment *exp = dbeSession->get_exp (0);
  if (exp == NULL)
    return res;
  if (exp->get_status () == Experiment::INCOMPLETE)
    exp->update ();

  DataDescriptor *dataDscr = exp->get_raw_events (data_id);
  if (dataDscr == NULL)
    return res;

  // Parse all expressions
  Vector<Expression*> *funcs = new Vector<Expression*>;
  Vector<Aggr_type> *aggrs = new Vector<Aggr_type>;
  Vector<DefaultMap<long long, long long>*> *fval_maps =
	  new Vector<DefaultMap<long long, long long>*>;
  Vector<DefaultMap<long long, long>*> *cnt_maps =
	  new Vector<DefaultMap<long long, long>*>;
  if (func1 != NULL)
    {
      Expression *expr = dbeSession->ql_parse (func1);
      funcs->append (expr);
      aggrs->append (getAggrFunc (aggr1));
      fval_maps->append (new DefaultMap<long long, long long>);
      cnt_maps->append (new DefaultMap<long long, long>);
      res->append (new Vector<long long>);
      if (func2 != NULL)
	{
	  expr = dbeSession->ql_parse (func2);
	  funcs->append (expr);
	  aggrs->append (getAggrFunc (aggr2));
	  fval_maps->append (new DefaultMap<long long, long long>);
	  cnt_maps->append (new DefaultMap<long long, long>);
	  res->append (new Vector<long long>);
	  if (func3 != NULL)
	    {
	      expr = dbeSession->ql_parse (func3);
	      funcs->append (expr);
	      aggrs->append (getAggrFunc (aggr3));
	      fval_maps->append (new DefaultMap<long long, long long>);
	      cnt_maps->append (new DefaultMap<long long, long>);
	      res->append (new Vector<long long>);
	    }
	}
    }
  if (funcs->size () == 0)
    {
      funcs->destroy ();
      delete funcs;
      fval_maps->destroy ();
      delete fval_maps;
      cnt_maps->destroy ();
      delete cnt_maps;
      delete aggrs;
      return res;
    }
  Expression *arg_expr = NULL;
  if (arg != NULL)
    arg_expr = dbeSession->ql_parse (arg);
  if (arg_expr == NULL)
    {
      funcs->destroy ();
      delete funcs;
      fval_maps->destroy ();
      delete fval_maps;
      cnt_maps->destroy ();
      delete cnt_maps;
      delete aggrs;
      return res;
    }
  Expression *flt_expr = NULL;
  if (lfilter != NULL)
    flt_expr = dbeSession->ql_parse (lfilter);
  Vector<long long> *kidx_map = new Vector<long long>(); // key_idx -> key_val
  for (long i = 0; i < dataDscr->getSize (); i++)
    {
      Expression::Context ctx (dbeSession->getView (0), exp, NULL, i);
      // First use the filter
      if (flt_expr != NULL)
	if (flt_expr->eval (&ctx) == 0)
	  continue;

      // Compute the argument
      long long key = arg_expr->eval (&ctx);
      if (kidx_map->find (key) == -1)
	kidx_map->append (key);
      for (long j = 0; j < funcs->size (); ++j)
	{
	  Expression *func = funcs->fetch (j);
	  Aggr_type aggr = aggrs->fetch (j);
	  DefaultMap<long long, long long> *fval_map = fval_maps->fetch (j);
	  DefaultMap<long long, long> *cnt_map = cnt_maps->fetch (j);
	  long long fval = func->eval (&ctx);
	  long long aval = fval_map->get (key);
	  long cnt = cnt_map->get (key);
	  switch (aggr)
	    {
	    case AGGR_NONE:
	    case AGGR_FAIR:
	      if (cnt == 0)
		aval = fval;
	      break;
	    case AGGR_MAX:
	      if (aval < fval || cnt == 0)
		aval = fval;
	      break;
	    case AGGR_MIN:
	      if (aval > fval || cnt == 0)
		aval = fval;
	      break;
	    case AGGR_CNT:
	      aval = cnt + 1;
	      break;
	    case AGGR_SUM:
	    case AGGR_AVG:
	      aval += fval;
	      break;
	    }
	  cnt_map->put (key, cnt + 1);
	  fval_map->put (key, aval);
	}
    }
  kidx_map->sort (key_cmp);

  // Finalize aggregation, prepare result
  for (long j = 0; j < funcs->size (); ++j)
    {
      Aggr_type aggr = aggrs->fetch (j);
      Vector<long long> *resj = res->fetch (j);
      DefaultMap<long long, long long> *
	      fval_map = fval_maps->fetch (j);
      DefaultMap<long long, long> *
	      cnt_map = cnt_maps->fetch (j);
      for (int kidx = 0; kidx < kidx_map->size (); ++kidx)
	{
	  long long key = kidx_map->fetch (kidx);
	  long long aval = fval_map->get (key);
	  if (aggr == AGGR_AVG)
	    {
	      long cnt = cnt_map->get (key);
	      if (cnt > 0)
		aval = (aval + cnt / 2) / cnt;
	    }
	  resj->append (aval);
	}
    }
  delete flt_expr;
  funcs->destroy ();
  delete funcs;
  delete aggrs;
  delete arg_expr;
  delete kidx_map;
  fval_maps->destroy ();
  delete fval_maps;
  cnt_maps->destroy ();
  delete cnt_maps;
  return res;
}

/* ********************************************************************* */
/*  Routines for use by Collector GUI */
/**
 * Returns signal value for provided name. Example of name: "SIGUSR1"
 * @param signal
 * @return value
 */
int
dbeGetSignalValue (char *signal)
{
  int ret = -1;
  if (signal == NULL)
    return ret;
  if (strcmp (signal, "SIGUSR1") == 0)
    return (SIGUSR1);
  if (strcmp (signal, "SIGUSR2") == 0)
    return (SIGUSR2);
  if (strcmp (signal, "SIGPROF") == 0)
    return (SIGPROF);
  return ret;
}

char *
dbeSendSignal (pid_t p, int signum)
{
  int ret = kill (p, signum);
  if (p == 0 || p == -1)
    return (dbe_sprintf (GTXT ("kill of process %d not supported\n"), p));
  if (ret == 0)
    return NULL;
  char *msg = dbe_sprintf (GTXT ("kill(%d, %d) failed: %s\n"), p, signum,
			   strerror (errno));
  return msg;
}

char *
dbeGetCollectorControlValue (char *control)
{
  if (control == NULL)
    return NULL;
  if (col_ctr == NULL)
    col_ctr = new Coll_Ctrl (1);
  char *msg = col_ctr->get (control);
  return msg;
}

char *
dbeSetCollectorControlValue (char *control, char * value)
{
  if (control == NULL)
    return NULL;
  if (col_ctr == NULL)
    col_ctr = new Coll_Ctrl (1);
  char *msg = col_ctr->set (control, value);
  return msg;
}

char *
dbeUnsetCollectorControlValue (char *control)
{
  if (control == NULL)
    return NULL;
  if (col_ctr == NULL)
    col_ctr = new Coll_Ctrl (1);
  char *msg = col_ctr->unset (control);
  return msg;
}

void
dbeSetLocation (const char *fname, const char *location)
{
  Vector<SourceFile*> *sources = dbeSession->get_sources ();
  for (long i = 0, sz = sources ? sources->size () : 0; i < sz; i++)
    {
      SourceFile *src = sources->get (i);
      DbeFile *df = src->dbeFile;
      if (df && (strcmp (fname, df->get_name ()) == 0))
	{
	  df->find_file ((char *) location);
	  break;
	}
    }
}

void
dbeSetLocations (Vector<const char *> *fnames, Vector<const char *> *locations)
{
  if (fnames == NULL || locations == NULL
      || fnames->size () != locations->size ())
    return;
  for (long i = 0, sz = fnames->size (); i < sz; i++)
    dbeSetLocation (fnames->get (i), locations->get (i));
}

Vector<void*> *
dbeResolvedWith_setpath (const char *path)
{
  Vector<char*> *names = new Vector<char*>();
  Vector<char*> *pathes = new Vector<char*>();
  Vector<long long> *ids = new Vector<long long>();
  Vector<SourceFile*> *sources = dbeSession->get_sources ();
  for (long i = 0, sz = sources ? sources->size () : 0; i < sz; i++)
    {
      SourceFile *src = sources->get (i);
      DbeFile *df = src->dbeFile;
      if (df == NULL || (df->filetype & DbeFile::F_FICTION) != 0)
	continue;
      char *fnm = df->get_name ();
      if ((df->filetype & (DbeFile::F_JAVACLASS | DbeFile::F_JAVA_SOURCE)) != 0)
	{
	  char *jnm = dbe_sprintf (NTXT ("%s/%s"), path, fnm);
	  if (df->check_access (jnm) == DbeFile::F_FILE)
	    {
	      names->append (dbe_strdup (fnm));
	      pathes->append (jnm);
	      ids->append (src->id);
	      continue;
	    }
	  free (jnm);
	}
      char *nm = dbe_sprintf (NTXT ("%s/%s"), path, get_basename (fnm));
      if (df->check_access (nm) == DbeFile::F_FILE)
	{
	  names->append (dbe_strdup (fnm));
	  pathes->append (nm);
	  ids->append (src->id);
	  continue;
	}
      free (nm);
    }
  if (names->size () != 0)
    {
      Vector<void*> *data = new Vector<void*>(3);
      data->append (names);
      data->append (pathes);
      data->append (ids);
      return data;
    }
  return NULL;
}

Vector<void*> *
dbeResolvedWith_pathmap (const char *old_prefix, const char *new_prefix)
{
  size_t len = strlen (old_prefix);
  Vector<char*> *names = new Vector<char*>();
  Vector<char*> *pathes = new Vector<char*>();
  Vector<long long> *ids = new Vector<long long>();
  Vector<SourceFile*> *sources = dbeSession->get_sources ();
  for (long i = 0, sz = sources ? sources->size () : 0; i < sz; i++)
    {
      SourceFile *src = sources->get (i);
      DbeFile *df = src->dbeFile;
      if (df == NULL || (df->filetype & DbeFile::F_FICTION) != 0)
	continue;
      char *fnm = df->get_name ();
      if (strncmp (old_prefix, fnm, len) == 0
	  && (fnm[len] == '/' || fnm[len] == '\0'))
	{
	  char *nm = dbe_sprintf (NTXT ("%s/%s"), new_prefix, fnm + len);
	  if (df->check_access (nm) == DbeFile::F_FILE)
	    {
	      names->append (dbe_strdup (fnm));
	      pathes->append (nm);
	      ids->append (src->id);
	      continue;
	    }
	  if ((df->filetype & DbeFile::F_JAVA_SOURCE) != 0)
	    {
	      free (nm);
	      nm = dbe_sprintf (NTXT ("%s/%s"), new_prefix, fnm);
	      if (df->check_access (nm) == DbeFile::F_FILE)
		{
		  names->append (dbe_strdup (fnm));
		  pathes->append (nm);
		  ids->append (src->id);
		  continue;
		}
	    }
	  free (nm);
	}
    }
  if (names->size () != 0)
    {
      Vector<void*> *data = new Vector<void*>(3);
      data->append (names);
      data->append (pathes);
      data->append (ids);
      return data;
    }
  return NULL;
}

void
dbe_archive (Vector<long long> *ids, Vector<const char *> *locations)
{
  if (ids == NULL || locations == NULL || ids->size () != locations->size ())
    return;
  Experiment *exp = dbeSession->get_exp (0);
  if (exp == NULL)
    return;
  Vector<SourceFile*> *sources = dbeSession->get_sources ();
  for (long i1 = 0, sz1 = ids->size (); i1 < sz1; i1++)
    {
      long long id = ids->get (i1);
      for (long i = 0, sz = sources ? sources->size () : 0; i < sz; i++)
	{
	  SourceFile *src = sources->get (i);
	  if (src->id == id)
	    {
	      DbeFile *df = src->dbeFile;
	      if (df)
		{
		  char *fnm = df->find_file ((char *) locations->get (i1));
		  if (fnm)
		    {
		      char *nm = df->get_name ();
		      char *anm = exp->getNameInArchive (nm, false);
		      exp->copy_file (fnm, anm, true);
		      free (anm);
		    }
		}
	    }
	}
    }
}

/* ************************************************************************ */

/* Routines to check connection between Remote Analyzer Client and er_print */
char *
dbeCheckConnection (char *str)
{
  return dbe_strdup (str);
}
